I am trying to adapt an old code which used Python2.7 and Keras 1.x to Python3.7.3 and Keras 2.2.4 and TensorFlow 1.13.1. Here is how the code looks:
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)
Essentially it is a custom made convolutional neural network, which takes 3 different arrays of variable dimensions as input and returns a scalar prediction. And this is the output when I execute it:
======================================== 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)
I suspect that this error is associated with the shape of the "labels" array, which is flat. What am I doing wrong? Also, why am I getting
DEBUG: final_fp.get_shape()= (?, 186)
but model.summary() shows
concatenate_1 (Concatenate) (None, 55, 186) 0
Where did this extra dimension (55) come from? Perhaps the network expects for some reason the labels to have dimensions (1128, 55, 1) and not (1128, 1).
If you need more information please ask me and I will add more debugging print functions.