1
votes

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.

2
Please, anyone??? I am trying to put together a more concise example with random data in the hope that someone will answer. - tevang

2 Answers

0
votes

Your last Dense layer main_predictions is not giving a 2 dimensional output since your are not flattening the inputs of it.

You need to use a Flatten layer after Convolution layers so that the output of the Dense is 2 dimensional.

The main_predictions requires a 3D label but you are providing it a 2D label. Therefore, you are getting the error.

You can add a Flatten layer in the code like :

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

And then compile the model.

0
votes

In your code you mentioned as a comment that previously you had used final_fp = merge([fp_out0, fp_out1, fp_out2], mode='sum'). So, according to this, you have used parameters of mode as sum not as concat. You are merging layer by adding them. But in new code you are using final_fp = concatenate([fp_out0, fp_out1, fp_out2]). So, there is difference between your old code and new code. In new code you have to use keras.layers.Add() to get the same functionality.

And the value error occured because shape incompabilty with your label data and output node of model. Try to change keras.layers.Concatenate with keras.layers.Add.

Update

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
_________________________________________________________________