Study interactive :: Progress tools open in the Study Hub reader.

All lessons in this module

Previous lesson. Graph Neural Networks Advanced Topics · Next lesson. Graph Neural Networks Quick Reference

Graph Neural Networks Project Tutorial

Step-by-step tutorial: Node classification with GCN on Cora dataset.

Project: Node Classification with GCN

Objective

Classify research papers in the Cora citation network using Graph Convolutional Networks.

Copy the cells below onto your machine after installing PyTorch Geometric. They are tagged so the Study Hub accuracy suite does not download Cora or require GPU stacks.

Step 1: Setup

import torch
import torch.nn as nn
import torch.nn.functional as F
from torch_geometric.datasets import Planetoid
from torch_geometric.nn import GCNConv

Step 2: Load Dataset

dataset = Planetoid(root='/tmp/Cora', name='Cora')
data = dataset[0]

print(f"Nodes: {data.x.shape[0]}")
print(f"Edges: {data.edge_index.shape[1]}")
print(f"Features: {data.x.shape[1]}")
print(f"Classes: {dataset.num_classes}")

Step 3: Define GCN Model

class GCN(nn.Module):
    def __init__(self, input_dim, hidden_dim, output_dim):
        super(GCN, self).__init__()
        self.c hidden_dim)
        self.c output_dim)
    
    def forward(self, x, 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.log_softmax(x, dim=1)

Step 4: Training

model = GCN(input_dim=dataset.num_features, 
            hidden_dim=64, 
            output_dim=dataset.num_classes)
optimizer = torch.optim.Adam(model.parameters(), lr=0.01)

def train():
    model.train()
    optimizer.zero_grad()
    out = model(data.x, data.edge_index)
    loss = F.nll_loss(out[data.train_mask], data.y[data.train_mask])
    loss.backward()
    optimizer.step()
    return loss.item()

def test():
    model.eval()
    out = model(data.x, data.edge_index)
    pred = out.argmax(dim=1)
    acc = (pred[data.test_mask] == data.y[data.test_mask]).sum() / data.test_mask.sum()
    return acc.item()

# Train
for epoch in range(200):
    loss = train()
    if epoch % 20 == 0:
        acc = test()
        print(f"Epoch {epoch}, Loss: {loss:.4f}, Accuracy: {acc:.4f}")

Tiny local smoke (no PyG download)

Runs with NumPy only. Shows one message-passing step on a tiny synthetic graph.

import numpy as np

rng = np.random.default_rng(0)
n_nodes, n_feat, n_classes = 12, 8, 3
x = rng.normal(size=(n_nodes, n_feat))
# Undirected ring + a few random edges
edges = [(i, (i + 1) % n_nodes) for i in range(n_nodes)]
edges += [(0, 5), (2, 8), (3, 9)]
adj = np.zeros((n_nodes, n_nodes))
for i, j in edges:
    adj[i, j] = 1.0
    adj[j, i] = 1.0
np.fill_diagonal(adj, 1.0)
deg = adj.sum(axis=1)
deg_inv_sqrt = np.diag(1.0 / np.sqrt(np.maximum(deg, 1e-8)))
norm_adj = deg_inv_sqrt @ adj @ deg_inv_sqrt

w = rng.normal(size=(n_feat, n_classes))
h = np.maximum(0.0, norm_adj @ x @ w)  # one GCN-like layer + ReLU
y_hat = h.argmax(axis=1)
print(f"Synthetic nodes={n_nodes} edges={len(edges)} pred_classes={sorted(set(y_hat.tolist()))}")
assert h.shape == (n_nodes, n_classes)

All lessons in this module

Previous lesson. Graph Neural Networks Advanced Topics · Next lesson. Graph Neural Networks Quick Reference