danielegrattarola / spektral

Graph Neural Networks with Keras and Tensorflow 2.
https://graphneural.network
MIT License
2.37k stars 335 forks source link

RuntimeError: Exception encountered when calling ARMAConv.call(). #455

Open donn-liew opened 1 week ago

donn-liew commented 1 week ago

Hi, trying to learn spektral here. I can't seem to use ARMAConv:

def create_model(n_nodes, n_node_features, model_layers): node_features_input = Input(shape=(n_node_features,), dtype=tf.float32) adjacency_input = Input((n_nodes,), dtype=tf.float32, sparse=True)

x = node_features_input
for layer in model_layers:
    if isinstance(layer, (spektral.layers.AGNNConv, 
                          spektral.layers.CrystalConv,
                          spektral.layers.EdgeConv,
                          spektral.layers.GatedGraphConv,
                          spektral.layers.GeneralConv,
                          spektral.layers.GINConv,
                          spektral.layers.GraphSageConv,
                          spektral.layers.TAGConv
                          )):
        x = layer([x, adjacency_input])

    if isinstance(layer, (spektral.layers.APPNPConv,
                  )):

        x = layer([x, adjacency_input])

    if isinstance(layer, keras.layers.Dense):
        x = layer(x)
    else:
        x = layer([x, adjacency_input])

model = Model(inputs=[node_features_input, adjacency_input], outputs=x)
return model

Load and prepare data

graph = spektral.datasets.Cora()[0] node_features = graph.x adjacency_matrix = graph.a

labels = graph.y.flatten()[:node_features.shape[0]]

Define model layers

model_layers = [ spektral.layers.ARMAConv(channels=graph.n_node_features), layers.Dense(1, activation='sigmoid') ]

Create and compile the model

model = create_model(graph.n_nodes, graph.n_node_features, model_layers) model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy']) model.summary()

Train the model

history = model.fit( [node_features, adjacency_matrix], labels, epochs=2, batch_size=graph.n_nodes, validation_split=0.1, shuffle=False # Important for graph data )

Evaluate the model

test_loss, test_accuracy = model.evaluate([node_features, adjacency_matrix], labels) print(f"Test accuracy: {test_accuracy:.4f}")

I get the following error:

Traceback (most recent call last):

File ~/miniconda3/envs/tf/lib/python3.10/site-packages/spyder_kernels/py3compat.py:356 in compat_exec exec(code, globals, locals)

File model = create_model(graph.n_nodes, graph.n_node_features, model_layers)

File in create_model x = layer([x, adjacency_input])

File ~/miniconda3/envs/tf/lib/python3.10/site-packages/keras/src/utils/traceback_utils.py:122 in error_handler raise e.with_traceback(filtered_tb) from None

File ~/miniconda3/envs/tf/lib/python3.10/site-packages/spektral/layers/convolutional/conv.py:74 in _inner_check_dtypes return call(inputs, **kwargs)

File ~/miniconda3/envs/tf/lib/python3.10/site-packages/spektral/layers/convolutional/arma_conv.py:144 in call output *= mask[0]

RuntimeError: Exception encountered when calling ARMAConv.call().

Could not automatically infer the output shape / dtype of 'arma_conv_3' (of type ARMAConv). Either the ARMAConv.call() method is incorrect, or you need to implement the ARMAConv.compute_output_spec() / compute_output_shape() method. Error encountered:

Tried to convert 'y' to a tensor and failed. Error: None values not supported.

Arguments received by ARMAConv.call(): • args=(['<KerasTensor shape=(None, 1433), dtype=float32, sparse=None, name=keras_tensor_12>', '<KerasTensor shape=(None, 2708), dtype=float32, sparse=True, name=keras_tensor_13>'],) • kwargs={'mask': ['None', 'None']}

Thanks in advance :)

donn-liew commented 1 week ago

I managed to stop the error by changing:

if mask is not None:

into

if mask is not None and mask[0] is not None:

in ~/miniconda3/envs/tf/lib/python3.10/site-packages/spektral/layers/convolutional/arma_conv.py

I'm still not quite sure if this is a proper solution.