Pytorch Geometric - Graph Classification Issue - Train loader mixes graphs

username: Bixqu
cooked: <p>I am trying to run a graph classification problem. For testing purposes, I am using a list of data objects, each of which looks like:</p>
<pre><code class="lang-auto">dataset = produceDataset(directory_path,
                      embeddings_path,
                      user_features_path,
                      labels_path,
                      train_frac=0.6,
                      val_frac=0.2,
                      binary_classification=True)
</code></pre>
<pre><code class="lang-auto">dataset[0]
Data(edge_attr=[1306, 1], edge_index=[2, 1306], x=[1281, 768], y=[1])
</code></pre>
<p>The structure of my data is a set of N graphs and N binary labels for each. I am not sure if the above structure is correctly created.</p>
<p>Then I build the loaders and assign pieces of the list for training and testing:</p>
<pre><code class="lang-auto">train_dataset, test_dataset = dataset[:2], dataset[2:]

train_loader = DataLoader(train_dataset,
                         batch_size=2,
                         shuffle=True)
test_loader = DataLoader(test_dataset,
                         batch_size=1,
                         shuffle=False)
</code></pre>
<p>I define the model:</p>
<pre><code class="lang-auto">class Net(torch.nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = GCNConv(768, 16)
        self.conv2 = GCNConv(16, 2)

    def forward(self, data):
        x, edge_index = data.x, data.edge_index

        x = self.conv1(x, edge_index)
        x = F.relu(x)
        x = F.dropout(x, training=self.training)
        x = self.conv2(x, edge_index)

        return F.softmax(x, dim=1)
</code></pre>
<p>and try to train it:</p>
<pre><code class="lang-auto">device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = Net().to(device)
optimizer = torch.optim.Adam(model.parameters(), lr=0.01, weight_decay=5e-4)

model = Net().to(device)

def train():
    model.train()
    for data in train_loader:
        data_cuda = data.to(device)
        optimizer.zero_grad()
        out = model(data_cuda)#.unsqueeze(0).type(torch.float).mean(1).type(torch.int32).type(torch.float)
        y = data_cuda.y.type(torch.long)
        loss = CrossEntropyLoss(out, y)
        optimizer.step()

def test(loader):
    correct = []
    for data in loader:
        model.eval()
        data_cuda = data.to(device)
        pred = model(data_cuda).unsqueeze(0).type(torch.int32)
        correct += [1 if pred.eq(data_cuda.y).item() else 0]
        
    acc = sum(correct) / len(data)
    print('Accuracy: {:.4f}'.format(acc))

for epoch in range(1, 21):
    train()
    
test(test_loader)
</code></pre>
<p>I don’t know if the output of my model is correct for my task, it’s most likely not, as if I print the shapes of<br>
<code>out</code> and <code>y</code> from the train method, they look like:</p>
<pre><code class="lang-auto">torch.Size([1484, 2])
torch.Size([2])
</code></pre>
<p>So I see that, for a batch size of 2, the node feature matrix just gets stacked, lacking a batch dimension. This is the first time I’m using Pytorch Geometric, and I am trying to understand this code, since I need to work on it for a project. Can someone please help me in getting it running? <img src="https://discuss.pytorch.org/images/emoji/apple/frowning.png?v=9" title=":frowning:" class="emoji" alt=":frowning:"></p>
<p><strong>EDIT</strong></p>
<p>I tried transposing the output. Now out and y are of shapes:</p>
<pre><code class="lang-auto">torch.Size([2, 1484])
torch.Size([2])
</code></pre>
<p>but when I pass them to the CrossEntropyLoss, I get:</p>
<p><code>RuntimeError: bool value of Tensor with more than one value is ambiguous</code></p>
<p>However, if I test this code:</p>
<pre><code class="lang-auto">loss = CrossEntropyLoss()
input = torch.randn(3, 15, requires_grad=True)
target = torch.empty(3, dtype=torch.long).random_(5)
output = loss(input, target)
</code></pre>
<p>the shapes of input and target are:</p>
<pre><code class="lang-auto">torch.Size([3, 15])
torch.Size([3])
</code></pre>
<p>And it does work. I really don’t understand what’s wrong.</p>

username: EricAlcaide
cooked: <aside class="quote no-group" data-username="Bixqu" data-post="1" data-topic="78611">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/letter_avatar_proxy/v4/letter/b/958977/48.png" class="avatar"> Bixqu:</div>
<blockquote>
<p>r testing purposes, I am using a list of data object</p>
</blockquote>
</aside>
<p>It looks like you need the readout phase to average node embeddings and have a single prediction for each graph</p>