Node Classification with GNN
Cora dataset, 2-layer GCN, training loop, masked loss, test accuracy, visualizing embeddings.
Node Classification with GNN is a free Learn AI with Python lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Learn AI with Python learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
The Node Classification Task
Node classification predicts a label for each node using its features and the graph structure. Classic example: label each paper in a citation network by its research topic, using both the paper words and which papers it cites.
The Cora Dataset
Cora is the MNIST of graph learning. It is a citation graph of 2,708 machine-learning papers. Edges are citations; each paper has a bag-of-words feature vector of length 1433; the goal is to classify each paper into one of 7 topics.
# Cora:
# nodes = 2708 papers
# edges = citations
# features per node = 1433
# classes = 7Loading via Planetoid
PyTorch Geometric ships Cora through the Planetoid loader, which downloads and formats the data into a single graph object.
from torch_geometric.datasets import Planetoid
dataset = Planetoid(root="data/Cora", name="Cora")
data = dataset[0]
print(data) # x, edge_index, y, train_mask, test_maskThe Data Object
The graph object holds everything: data.x (features 2708 x 1433), data.edge_index (connectivity), data.y (true labels), and boolean masks marking which nodes are for training, validation, and testing.
A GCN for 7 Classes
We build a 2-layer GCN that maps the 1433 input features through a 64-dim hidden layer down to 7 class logits.
import torch
import torch.nn.functional as F
from torch_geometric.nn import GCNConv
class GCN(torch.nn.Module):
def __init__(self):
super().__init__()
self.conv1 = GCNConv(1433, 64)
self.conv2 = GCNConv(64, 7)
def forward(self, x, edge_index):
x = F.relu(self.conv1(x, edge_index))
x = F.dropout(x, training=self.training)
return self.conv2(x, edge_index)Transductive Learning
Cora is transductive: the whole graph (including test nodes and their features) is visible during training; we only hide the test labels. The model uses every node connections but learns from labeled training nodes only.
The train_mask
The train_mask is a boolean vector selecting which nodes contribute to the loss. We run the model on the entire graph but compute cross-entropy only on masked training nodes.
model = GCN()
optimizer = torch.optim.Adam(model.parameters(), lr=0.01, weight_decay=5e-4)
def train():
model.train()
optimizer.zero_grad()
out = model(data.x, data.edge_index)
loss = F.cross_entropy(out[data.train_mask], data.y[data.train_mask])
loss.backward()
optimizer.step()
return loss.item()Masked Loss Intuition
Even though the forward pass produces logits for all 2708 nodes, indexing with train_mask restricts the loss to labeled training nodes. The unlabeled nodes still pass messages, helping the model, but do not directly drive the gradient.
Evaluating with test_mask
After training, we evaluate accuracy on the held-out test_mask nodes, which the loss never touched. This measures generalization to papers whose labels the model never saw.
@torch.no_grad()
def test():
model.eval()
pred = model(data.x, data.edge_index).argmax(dim=1)
correct = (pred[data.test_mask] == data.y[data.test_mask]).sum()
return int(correct) / int(data.test_mask.sum())Visualizing Embeddings with t-SNE
To see what the GCN learned, take the hidden-layer node embeddings and project them to 2D with t-SNE. A well-trained GCN produces clusters where nodes of the same class group together.
from sklearn.manifold import TSNE
import matplotlib.pyplot as plt
emb = model.conv1(data.x, data.edge_index).detach().numpy()
z = TSNE(n_components=2).fit_transform(emb)
plt.scatter(z[:, 0], z[:, 1], c=data.y, cmap="tab10", s=8)Interpreting the t-SNE Plot
Well-separated colored clusters mean the embeddings are class-discriminative, a sign the GCN learned useful structure. Overlapping blobs suggest under-training or over-smoothing. t-SNE is a qualitative check, not a metric.
Quick Check
Test your node classification knowledge.
Recap
You learned node classification with a GNN:
- Planetoid loads the Cora citation graph
- A 2-layer GCN maps 1433 to 64 to 7 classes
- train_mask restricts the loss; test_mask measures generalization
- t-SNE visualizes node embeddings to inspect class separation
Frequently asked questions
Is the “Node Classification with GNN” lesson free?
Yes — the full text of “Node Classification with GNN” is free to read here on the web, and the Learn AI with Python course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Learn AI with Python course, upgrade to CoddyKit PRO.
What will I learn in “Node Classification with GNN”?
Cora dataset, 2-layer GCN, training loop, masked loss, test accuracy, visualizing embeddings. You practise Learn AI with Python with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Learn AI with Python?
No prior experience is required. Learn AI with Python on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Node Classification with GNN” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Learn AI with Python lesson?
Yes. Every Learn AI with Python lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Graph Theory for Machine Learning
- Graph Convolutional Networks (GCN)
- Node Classification with GNN
- Link Prediction and Graph Classification