Ошибка значения при проверке цели: ожидалось, что main_prediction будет иметь 3 измерения, но получил массив с формой (1128, 1)

#python #tensorflow #keras #conv-neural-network #valueerror

#python #тензорный поток #keras #conv-neural-network #valueerror

Вопрос:

Я пытаюсь адаптировать старый код, в котором использовались Python2.7 и Keras 1.x, к Python3.7.3 и Keras 2.2.4 и TensorFlow 1.13.1. Вот как выглядит код:

 from keras.layers import Input, add, Dense, Flatten, concatenate
from keras import activations
from keras import models
from keras import backend as K
import numpy as np

import utils
from NGF.preprocessing import tensorise_smiles, tensorise_smiles_mp
from NGF.layers import NeuralGraphHidden, NeuralGraphOutput
from NGF.models import build_graph_conv_model
from NGF.sparse import GraphTensor, EpochIterator

# ==============================================================================
# ================================ Load the data ===============================
# ==============================================================================
print("{:=^100}".format(' Data preprocessing '))
data, labels = utils.load_delaney()

# Tensorise data
X_atoms, X_bonds, X_edges = tensorise_smiles_mp(data)
print('Atoms:', X_atoms.shape)
print('Bonds:', X_bonds.shape)
print('Edges:', X_edges.shape)

# Load sizes from data shape
num_molecules = X_atoms.shape[0]
max_atoms = X_atoms.shape[1]
max_degree = X_bonds.shape[2]
num_atom_features = X_atoms.shape[-1]
num_bond_features = X_bonds.shape[-1]

# ==============================================================================
# =============== Example 1: Building a 3-layer graph convnet  =================
# ==============================================================================
print("{:=^100}".format(' Example 1 '))

# Parameters
conv_width = 8
fp_length = 62

# Define the input layers
atoms0 = Input(name='atom_inputs', shape=(max_atoms, num_atom_features))
bonds = Input(name='bond_inputs', shape=(max_atoms, max_degree, num_bond_features))
edges = Input(name='edge_inputs', shape=(max_atoms, max_degree), dtype='int32')
print("DEBUG: edges=", K.print_tensor(edges))

# Define the convoluted atom feature layers
atoms1 = NeuralGraphHidden(conv_width, activation='relu', use_bias=False)([atoms0, bonds, edges])
atoms2 = NeuralGraphHidden(conv_width, activation='relu', use_bias=False)([atoms1, bonds, edges])

# Define the outputs of each (convoluted) atom feature layer to fingerprint
fp_out0 = NeuralGraphOutput(fp_length, activation='softmax')([atoms0, bonds, edges])
fp_out1 = NeuralGraphOutput(fp_length, activation='softmax')([atoms1, bonds, edges])
fp_out2 = NeuralGraphOutput(fp_length, activation='softmax')([atoms2, bonds, edges])

# Flatten the input before the Dense layer by summing the 3 outputs to obtain fingerprint
# final_fp = merge([fp_out0, fp_out1, fp_out2], mode='sum') # Old Keras 1.x syntax
print("DEBUG: fp_out0.get_shape()=", fp_out0.get_shape())
print("DEBUG: fp_out1.get_shape()=", fp_out1.get_shape())
print("DEBUG: fp_out2.get_shape()=", fp_out2.get_shape())
# final_fp = add([fp_out0, fp_out1, fp_out2])
final_fp = concatenate([fp_out0, fp_out1, fp_out2])
print("DEBUG: final_fp.get_shape()=", final_fp.get_shape())

# Build and compile model for regression.
main_pred = Dense(1, activation='linear', name='main_prediction')(final_fp)
print("DEBUG: main_pred.get_shape()=", main_pred.get_shape())
model = models.Model(inputs=[atoms0, bonds, edges], outputs=[main_pred])
model.compile(optimizer='adagrad', loss='mse')

# Show summary
model.summary()

# Train the model
print("DEBUG: labels.shape", labels.shape)
model.fit(x=[X_atoms, X_bonds, X_edges], y=labels, epochs=20, batch_size=32, validation_split=0.2)
  

По сути, это специально созданная сверточная нейронная сеть, которая принимает 3 разных массива переменных измерений в качестве входных данных и возвращает скалярное предсказание. И это результат, когда я его выполняю:

 ======================================== Data preprocessing ========================================
Tensorising molecules in batches...
1128/1128 [==================================================] - 1s 740us/step
Merging batch tensors...    [DONE]
Atoms: (1128, 55, 62)
Bonds: (1128, 55, 5, 6)
Edges: (1128, 55, 5)
============================================ Example 1 =============================================
DEBUG: edges= Tensor("Print:0", shape=(?, 55, 5), dtype=int32)
DEBUG: fp_out0.get_shape()= (?, 62)
DEBUG: fp_out1.get_shape()= (?, 62)
DEBUG: fp_out2.get_shape()= (?, 62)
DEBUG: final_fp.get_shape()= (?, 186)
DEBUG: main_pred.get_shape()= (?, 1)
__________________________________________________________________________________________________
Layer (type)                    Output Shape         Param #     Connected to                     
==================================================================================================
atom_inputs (InputLayer)        (None, 55, 62)       0                                            
__________________________________________________________________________________________________
bond_inputs (InputLayer)        (None, 55, 5, 6)     0                                            
__________________________________________________________________________________________________
edge_inputs (InputLayer)        (None, 55, 5)        0                                            
__________________________________________________________________________________________________
neural_graph_hidden_1 (NeuralGr [(None, 55, 62), (No 2720        atom_inputs[0][0]                
                                                                 bond_inputs[0][0]                
                                                                 edge_inputs[0][0]                
__________________________________________________________________________________________________
neural_graph_hidden_2 (NeuralGr [(None, 55, 62), (No 2720        neural_graph_hidden_1[0][0]      
                                                                 bond_inputs[0][0]                
                                                                 edge_inputs[0][0]                
__________________________________________________________________________________________________
neural_graph_output_1 (NeuralGr [(None, 55, 62), (No 4278        atom_inputs[0][0]                
                                                                 bond_inputs[0][0]                
                                                                 edge_inputs[0][0]                
__________________________________________________________________________________________________
neural_graph_output_2 (NeuralGr [(None, 55, 62), (No 4278        neural_graph_hidden_1[0][0]      
                                                                 bond_inputs[0][0]                
                                                                 edge_inputs[0][0]                
__________________________________________________________________________________________________
neural_graph_output_3 (NeuralGr [(None, 55, 62), (No 4278        neural_graph_hidden_2[0][0]      
                                                                 bond_inputs[0][0]                
                                                                 edge_inputs[0][0]                
__________________________________________________________________________________________________
concatenate_1 (Concatenate)     (None, 55, 186)      0           neural_graph_output_1[0][0]      
                                                                 neural_graph_output_2[0][0]      
                                                                 neural_graph_output_3[0][0]      
__________________________________________________________________________________________________
main_prediction (Dense)         (None, 55, 1)        187         concatenate_1[0][0]              
==================================================================================================
Total params: 18,461
Trainable params: 18,461
Non-trainable params: 0
__________________________________________________________________________________________________
DEBUG: labels.shape (1128,)
Traceback (most recent call last):
  File "/home/thomas/Programs/Anaconda3/lib/python3.7/site-packages/IPython/core/interactiveshell.py", line 3296, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-2-9a41784534dc>", line 1, in <module>
    runfile('/home2/thomas/Programs/keras-neural-graph-fingerprint_Py3/examples.py', wdir='/home2/thomas/Programs/keras-neural-graph-fingerprint_Py3')
  File "/home2/thomas/Programs/pycharm-2019.1.1/helpers/pydev/_pydev_bundle/pydev_umd.py", line 197, in runfile
    pydev_imports.execfile(filename, global_vars, local_vars)  # execute the script
  File "/home2/thomas/Programs/pycharm-2019.1.1/helpers/pydev/_pydev_imps/_pydev_execfile.py", line 18, in execfile
    exec(compile(contents "n", file, 'exec'), glob, loc)
  File "/home2/thomas/Programs/keras-neural-graph-fingerprint_Py3/examples.py", line 80, in <module>
    model.fit(x=[X_atoms, X_bonds, X_edges], y=labels, epochs=20, batch_size=32, validation_split=0.2)
  File "/home/thomas/Programs/Anaconda3/lib/python3.7/site-packages/keras/engine/training.py", line 952, in fit
    batch_size=batch_size)
  File "/home/thomas/Programs/Anaconda3/lib/python3.7/site-packages/keras/engine/training.py", line 789, in _standardize_user_data
    exception_prefix='target')
  File "/home/thomas/Programs/Anaconda3/lib/python3.7/site-packages/keras/engine/training_utils.py", line 128, in standardize_input_data
    'with shape '   str(data_shape))
ValueError: Error when checking target: expected main_prediction to have 3 dimensions, but got array with shape (1128, 1)
  

Я подозреваю, что эта ошибка связана с формой массива «labels», который является плоским. Что я делаю не так?
Кроме того, почему я получаю

DEBUG: final_fp.get_shape()= (?, 186)

но model.summary() показывает

concatenate_1 (Concatenate) (None, 55, 186) 0

Откуда взялось это дополнительное измерение (55)? Возможно, сеть по какой-то причине ожидает, что метки будут иметь размеры (1128, 55, 1) , а не (1128, 1) .

Если вам нужна дополнительная информация, пожалуйста, спросите меня, и я добавлю больше функций отладки печати.

Комментарии:

1. Пожалуйста, кто-нибудь??? Я пытаюсь собрать более краткий пример со случайными данными в надежде, что кто-нибудь ответит.

Ответ №1:

Ваш последний плотный слой main_predictions не выдает 2-мерный вывод, поскольку вы не сглаживаете его входные данные.

Вам нужно использовать Flatten слой после слоев свертки, чтобы результат Dense был 2-мерным.

main_predictions Требуется 3D-метка, но вы предоставляете ей 2D-метку. Следовательно, вы получаете ошибку.

Вы можете добавить слой выравнивания в код, например :

 flatten = Flatten()( final_fp )
main_pred = Dense(1, activation='linear', name='main_prediction')( flatten )
  

А затем скомпилируйте модель.

Комментарии:

1. То, что вы предлагаете, дает "ValueError: Input 0 is incompatible with layer flatten_1: expected min_ndim=3, found ndim=2" . На самом деле, я думал, что, объединяя три 2D-тензора, я сглаживал входные данные до плотного слоя final_fp = concatenate([fp_out0, fp_out1, fp_out2]) . Но почему я все еще считаю, что проблема в y том, что я передаю model.fit() ..?

2. На самом деле, я не понимаю, откуда взялись эти 55 дюймов main_prediction (Dense) (None, 55, 1) ! Возможно, сеть по какой-то причине ожидает, что метки будут иметь размеры (1128, 55, 1) , а не (1128, 1) .

Ответ №2:

В вашем коде вы упомянули в качестве комментария, который вы ранее использовали final_fp = merge([fp_out0, fp_out1, fp_out2], mode='sum') . Итак, в соответствии с этим вы использовали параметры mode as sum , а не as concat . Вы объединяете слой, добавляя их. Но в новом коде, который вы используете final_fp = concatenate([fp_out0, fp_out1, fp_out2]) . Итак, есть разница между вашим старым кодом и новым кодом. В новом коде вы должны использовать keras.layers.Add() , чтобы получить ту же функциональность.

И ошибка значения произошла из-за несоответствия формы вашим данным метки и выходному узлу модели. Попробуйте изменить keras.layers.Concatenate с keras.layers.Add помощью .

Обновить

 final_fp = Input(shape=(55,62)) # I had used as input which can be replace with your final_fp
flatten_1 = Flatten()(final_fp)
main_pred = Dense(1, activation='linear', name='main_prediction')(flatten_1)

model = Model(inputs=final_fp,outputs=main_pred)
print(model.summary())
  
 _________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         (None, 55, 62)            0         
_________________________________________________________________
flatten_1 (Flatten)          (None, 3410)              0         
_________________________________________________________________
main_prediction (Dense)      (None, 1)                 3411      
=================================================================
Total params: 3,411
Trainable params: 3,411
Non-trainable params: 0
_________________________________________________________________
  

Комментарии:

1. У вас один острый глаз. 🙂 Если бы у вас было два, вы бы заметили, что выше concatenate у меня есть закомментированная строка, использующая add . Обе операции создают 1D тензор, я просто хотел проверить, будет ли замена add на concatenate иметь какой-либо эффект, но это не так.

2. Кстати, у меня оба глаза в порядке. Я также видел, что вы использовали add . Итак, если вы использовали add , ваш код работает или нет? Хорошо! Я понимаю, что вы хотите заменить add на concatenate , но есть разница между add и concatenate .

3. Эффекта нет. Единственное отличие в том, что вместо тензора (None, 55, 186) я получаю (None, 55, 62) .

4. @tevang Итак, после этого вы можете использовать flatten и подключиться к Dense . См. Обновление в ответе.

5. Чего я не понимаю с самого начала, так это почему Keras Model() считает, что выходные данные NeuralGraphOutput() , а именно fp_out0, fp_out1, fp_out2 имеют форму (None, 55, 62) , в то время как перед передачей их в Model() их формы (?,62) . « DEBUG: fp_out0.get_shape()= (?, 62) DEBUG: fp_out1.get_shape()= (?, 62) DEBUG: fp_out2.get_shape()= (?, 62) « Проблема начинается оттуда. Я пытался сгладить, но Flatten() жалуется, что входные данные должны иметь больше измерений ValueError: Input 0 is incompatible with layer flatten_4: expected min_ndim=3, found ndim=2 .