Home > database >  How to use python spektral library DisjointLoader to feed FC network instead of Graph Isomorphism Ne
How to use python spektral library DisjointLoader to feed FC network instead of Graph Isomorphism Ne

Time:10-09

I want to compare the performance of classification problem using GIN vs. Fully Connected Network. I have started with example from the spektral library TUDataset classification with GIN. I have created custom dataset for my problem and it is being loaded using DisjointLoader from spektral.data.

I am seeing my supervised learning is showing good results on this data using GIN network. However, to compare these results with Fully Connected network, I am facing problem in loading inputs from dataset into FC network input. The dataset is stored in graph format with Node attributes matrix and adjacency matrix. There are 18 nodes in the graph and each node has 7 attributes in the attribute matrix.

I have tried loading the FC network with just Node attributes matrix but I am facing mismatch error.

here is the FC network that I have defined instead of GIN0 network from the example shared above:

class FCN0(Model):
    def __init__(self, channels, outputs):
        super().__init__()
        self.dense1 = Dense(channels, activation="relu")
        self.dropout = Dropout(0.5)
        self.dense2 = Dense(channels*3, activation="relu")
        self.dense3 = Dense(outputs, activation="relu")

    def call(self, inputs):
        x, a, i = inputs
        x = self.dense1(x)
        x = self.dense2(x)
        return self.dense3(x)

The error message is as follows:

  File "/home/xx/lib/python3.7/site-packages/tensorflow/python/eager/execute.py", line 60, in quick_execute
    inputs, attrs, num_outputs)
tensorflow.python.framework.errors_impl.InvalidArgumentError:  Incompatible shapes: [126,1] vs. [7,1]
         [[node gradient_tape/mean_squared_error/BroadcastGradientArgs (defined at dut_gin_vs_circuits.py:147) ]] [Op:__inference_train_step_588]

Function call stack:
train_step

I would highly appreciate, if someone can help me identify what transformations are needed at the input to be fit the data into to FC network while loading data using the same dataset loader.

CodePudding user response:

The problem is that your FC network does not have a global pooling layer (also sometimes called "readout"), and so the output of the network will have shape (batch_size * 18, 1) instead of (batch_size, 1) which is the shape of the target.

Essentially, your FC network is suitable for node-level prediction, but not graph-level prediction. To fix this, you can introduce a global pooling layer as follows:

from spektral.layers import GlobalSumPool

class FCN0(Model):
    def __init__(self, channels, outputs):
        super().__init__()
        self.dense1 = Dense(channels, activation="relu")
        self.dropout = Dropout(0.5)
        self.dense2 = Dense(channels*3, activation="relu")
        self.dense3 = Dense(outputs, activation="relu")
        self.pool = GlobalSumPool()

    def call(self, inputs):
        x, a, i = inputs
        x = self.dense1(x)
        x = self.dense2(x)
        x = self.dense3(x)
        return self.pool([x, i])  # Only pass `i` if in disjoint mode

You can move the pooling layer wherever in your computational graph, the important thing is that at some point you reduce the node-level representation to a graph-level representation.

Cheers

  • Related