Shape mismatch between logits and labels for computing loss on 3D tenso in GCN

RuntimeError: Expected target size [25, 10], got [25].

I have a sensors data and I want to perform node level classification using GCN. I have k nodes (sensors). Each node has m observations (node features) and each observation is a n dimensional vector. Shape of my dataset is k,m,n, its a 3d dataset. I used DGL to convert data to graph form.

k =  25
m = 2000
n = 6
num_classes = 10

node_features = torch.randn((k, m, n)) #Generate node features.
node_labels = torch.tensor([i  for i in range (k)]) #Create tensor of labels

#Create graph
nodes= [i for i in range(k)]
edges = []
for node1, node2 in combinations(nodes, 2):
    edges.append([node1, node2])
a = np.array(edges)
src =  a[:,0]
dst = a[:,1]
g = dgl.graph((src , dst)) # create graph

g.ndata['features'] = node_features # Assign node features 
g.ndata['labels'] = node_labels # Assign labels

Above code creates a graph. Below is graph structure.

Graph(num_nodes=25, num_edges=300,
ndata_schemes={‘features’: Scheme(shape=(2000, 6), dtype=torch.float32), ‘labels’: Scheme(shape=(), dtype=torch.int64)}
edata_schemes={})

Next, I build the GCN model.

import torch.nn as nn
import torch.nn.functional as F
from dgl.nn import GraphConv

class GCN(nn.Module):
    def __init__(self, in_feats, h_feats, num_classes):
        super(GCN, self).__init__()
        self.conv1 = GraphConv(in_feats, h_feats)
        self.conv2 = GraphConv(h_feats, num_classes)

    def forward(self, g, in_feat):
        h = self.conv1(g, in_feat)
        h = F.relu(h)
        h = self.conv2(g, h)
        return h

Training of model is:

num_epochs = 50 
hidden_size = 64
features = g.ndata["features"]
labels = g.ndata["labels"]

model = GCN(n, hidden_size , num_classes)
optimizer = torch.optim.Adam(model.parameters(), lr=0.01)
criterion = nn.CrossEntropyLoss()


# Train model
for epoch in range(num_epochs):
    logits = model(g, g.ndata['features'])
    loss = criterion(logits, labels)
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()
    print(f"Epoch {epoch + 1}, loss: {loss.item()}")

On line loss = criterion(logits, labels), following error occurs.

RuntimeError: Expected target size [25, 10], got [25].

How I can solve this problem? If I pass 2 dimensional data to this model, it works fine but my data is 3 dimensional.

Note: Shape of logits is torch.Size([k, m, num_classes ]) while shape of labels is torch.Size([k]).

Hi asif:

Since your node has m observations and each of observation is a n dimensional vector, so your actual feature dimension is m*n.

While you create the model with the code (model = GCN(n, hidden_size , num_classes)), the in_feats size is just n.

Can you double check your code?
Let us know if you have more questions.

If I set m*n for in_feats, I face this error. RuntimeError: mat1 and mat2 shapes cannot be multiplied (50000x6 and 12000x16). I have in-depth knowledge of GCN therefore unable to figure out the problem.

This code generates random data. Once it will become operational, I will plug my original dataset into this code. Can you please give a run to this code? You will be able to see the error in more detail.

Hi asif, can you move the code to Google Colab and share the link here.
I think there are still several syntax issue in the code, and not easy to reproduce the error.

For example, TypeError: combinations(): argument ‘input’ (position 1) must be Tensor, not list

I have placed the code on this notebook. Please check it.

Since your node feature is actually a (k, m, n) 3d tensor, you first you need to reshape it to (k, m*n) 2d tensor.
node_features = torch.randn((k, m, n)) #Generate node features.
node_features = node_features.view(k, -1) # Add this line.

For your model, the in_feats should be m*n instead of n.
# model = GCN(n, hidden_size , num_classes)
model = GCN(m*n, hidden_size , num_classes)

And there is another error in your code. Since your num_classes is 10, so the label of each node can be only 0-9.
# node_labels = torch.tensor([i for i in range (k)]) #Create tensor of labels
node_labels = torch.randint(0, num_classes, (k,))

I’ve also updated the colab, please take a look.

Thanks @frozenbugs. Its working now. I will plug my origional dataset and will see the performance. Just one quick question, when we are mapping 3d data to 2d to train model, we are reshaping it and that our information be lost? What if data is time stamed? or contains column for month, day, minute etc. How information will be preserved in that case?

It might make sense to have some positional encodings dedicated to temporal information. However, we are not experts on this topic and cannot give you concrete suggestions.

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.