Graph neural networks: message passing, GCN and expressivity
Before this lesson: lesson 01 (the message and update functions are MLPs) and lesson 09 (self-attention is permutation-equivariant). From the linear-algebra track: lesson 05 (eigenvalues, power iteration) and lesson 19 (the graph Laplacian, the GCN layer derived from spectral filters, the eigenvalues of ). Time: about 85 minutes, plus the notebook.
Why this matters #
Many objects in science and industry are graphs. A molecule is a graph of atoms and bonds. A crystal is a graph of atoms within a cutoff distance. A weather or finite-element mesh, a road network, a social network and a network of seismic stations are graphs too. GNNs are the core of machine-learned interatomic potentials (SchNet, NequIP, MACE), of learned mesh simulators (MeshGraphNets), of the weather model GraphCast, and of many recommender systems. Interviews ask three standard questions about GNNs: why equivariance, how expressive they are (the WL test), and why deep GNNs fail.
1. Predict first #
2. The picture #
One round of message passing #
Take a path of three nodes, 1 — 2 — 3, with one number per node: . In one round, every node takes the mean of its own number and its neighbours' numbers:
- node 1 sees and gets ;
- node 2 sees and gets ;
- node 3 sees and gets .
After round 1, . Node 3 has not seen node 1 yet: they are 2 edges apart. Round 2 gives . Now node 3 depends on node 1. In general, after rounds a node depends on its -hop neighbourhood: all nodes at most edges away. This is the receptive field of the node, as in a CNN (lesson 07). A real GNN layer also multiplies by learned weights and applies a nonlinearity, but information still moves one edge per layer.
Press One round and watch the value spread. Node colour shows the value of the node (blue = forward values; darker = larger). The start is an impulse at one node. Click a node to select it: the yellow ring marks the nodes it can see after the rounds done so far (its -hop neighbourhood). Notice that a node stays at 0 until the number of rounds reaches its distance to the impulse. Switch to sum aggregation and see the values grow at the high-degree nodes.
Compared with a CNN and with attention #
A convolution is message passing on a pixel grid. There, each neighbour has a fixed position (up, left, …) and its own weight. On a general graph the neighbours have no order, and their number changes from node to node. So the layer must treat them as a multiset: a set in which an element can appear more than once. It must combine them with a symmetric function, that is, a function that gives the same result for every order of its inputs: sum, mean or max. This one constraint shapes the whole lesson.
Self-attention (lesson 09) is message passing on the complete graph: every token sends a message to every other token, with learned weights. A GNN sends messages only along the edges that come with the data. Graph attention (GAT) is attention masked by the adjacency matrix.
A GNN has 3 layers. Nodes and are 5 edges apart. How does the input feature of node change the output of node ?
Each layer moves information one edge. After 3 layers, the output of node is a function of the inputs in its 3-hop neighbourhood only. Shared weights do not move information; they are the same function applied at every node. The aggregation changes what is combined, not how far it reaches.
Notation #
A graph has nodes. The adjacency matrix has when there is an edge from to . For an undirected graph, is symmetric. The neighbours of node are , and its degree is . Node features form a matrix : row belongs to node , and there are channels (one row per node, as one row per example in a mini-batch).
In code, a sparse graph is stored as edge_index: a integer array with one column
(source , target ) per directed edge. An undirected edge appears twice, once in each direction.
For the path 1 — 2 — 3 with nodes numbered 0, 1, 2:
edge_index = [[0, 1, 1, 2], # sources j
[1, 0, 2, 1]] # targets i
3. Definitions and main results #
Message passing #
One layer of a message-passing neural network (MPNN) (Gilmer et al. 2017) computes, for every node :
- is the message function, usually an MLP. is an optional edge feature (a bond type, a distance).
- is the aggregation: a function of the multiset of messages that does not depend on their order (sum, mean, max, or an attention-weighted sum).
- is the update function, an MLP or a GRU.
The same and act at every node and every edge. So the number of parameters does not depend on the size of the graph, and one layer costs message evaluations, where is the number of edges.
How it is computed. Gather and for every edge, compute all messages in one batch,
then add each message into the row of its target node. In PyTorch this last step is
out.index_add_(0, target, messages); in NumPy it is np.add.at(out, target, messages).
PyTorch Geometric's MessagePassing class has the same three parts (message, aggregate,
update).
Two kinds of tasks. For a node-level task (classify each paper), put a small head on each final state . For a graph-level task (predict the energy of a molecule), first apply a readout that turns all node states into one vector, such as .
The GCN layer #
The graph convolutional network (GCN) layer of Kipf and Welling (2017) is
with a weight matrix and an elementwise nonlinearity . Row by row:
So GCN is message passing with a linear message scaled by the degrees, a sum over the neighbours and the node itself, and the update .
- Self-loop (): without it, would not depend on , only on the neighbours.
- Normalization. A plain sum grows with the degree. Nodes with many neighbours (hubs) get large features, and stacked layers blow up. The eigenvalues of lie in (linear-algebra lesson 19), so repeated propagation stays bounded. The row-normalized (the mean over the node and its neighbours) has the same eigenvalues, because is similar to .
- Low-pass filter. , where is the normalized Laplacian of the graph with self-loops. A graph-Fourier component with Laplacian eigenvalue is multiplied by . Smooth components (small ) pass. All others shrink, and the roughest ones () also flip sign. Linear-algebra lesson 19 derives the layer as a first-order Chebyshev filter.
- Cost. With a sparse , one layer costs , and it has weights for a graph of any size.
Permutation equivariance and invariance #
The numbering of the nodes is arbitrary. Node 1 could be called node 5. A good model should not depend on this choice. Renumber the nodes and the node outputs should only be renumbered in the same way (equivariance); a single graph-level output should not change at all (invariance).
Follow both paths around the square. Relabel the nodes, then apply the layer; or apply the layer, then relabel the outputs. For the GCN layer the two results match (the error is at round-off level), but only when the adjacency matrix is relabelled together with the features. Choose GCN, A not relabeled or dense layer: the error becomes large, because these layers depend on the numbering.
A relabelling is a permutation : old node becomes new node . Its permutation matrix has and zeros elsewhere. Then (the rows are moved), and the new adjacency matrix has (the edges are moved with the nodes).
A map is permutation-equivariant if for every permutation matrix . A map to a single vector is permutation-invariant if .
Theorem (equivariance of message passing). Let be a message-passing layer whose aggregation depends only on the multiset of messages (no edge features, for simplicity). Then:
- (a) for every permutation matrix ;
- (b) a stack of such layers is equivariant;
- (c) the sum readout satisfies , so "readout after stack" is invariant;
- (d) for GCN: , and .
Why this is true, in one sentence: the layer only ever asks "who are my neighbours and what do they send?", and a relabelling changes neither answer, only the names.
Proof.
- In the new graph, node carries , and its neighbours are , because .
- The message from to is . So node receives exactly the multiset , maybe in another order.
- The aggregation sees only the multiset. So the new aggregate at is , and the new output there is . Row of the new output equals row of the old output. This is (a).
- (b): take two layers and . By (a) for , . Then (a) for , with input , gives . Induction over the layers gives any depth.
- (c): , because every row of has exactly one 1, so . Mean and max readouts are invariant for the same reason: they see only the multiset of rows.
- (d): (because ). The degrees are permuted: , so . Hence , and , because and an elementwise commutes with reordering rows.
Equivariance builds the symmetry into the model, as translation equivariance does for a CNN. Node outputs move with the nodes; only a readout is invariant. (Prince's book stores nodes as columns; his Eq. 13.6 is the same statement.)
Expressivity: the 1-WL test #
How powerful can a message-passing GNN be? The answer comes from an old test for graph isomorphism. Two graphs are isomorphic if one is a relabelling of the other.
1-WL colour refinement (Weisfeiler and Leman). Give every node a colour: its input label, or one common colour if there are no features. Then repeat:
with one injective HASH for both graphs ("injective" means different inputs always get different colours). The new colour of a node encodes its old colour and the multiset of its neighbours' colours. Then compare the colour histograms: the number of nodes of each colour in each graph. If at some round the histograms differ, the graphs are not isomorphic. If they stay equal, 1-WL cannot distinguish the graphs; they may or may not be isomorphic.
Press Refine to run one round of colour refinement on both graphs. Colours here are 1-WL colour classes (the number in each node is the colour id); one colour table is shared by both graphs. The table below lists each colour, the signature it was made from, and how many nodes of each graph have it (counts that differ are magenta). With path vs triangle + edge, round 1 gives equal histograms (both have degrees 1, 1, 2, 2, 2), but round 2 separates them. With two triangles vs hexagon, every node keeps one colour forever: 1-WL, and so every message-passing GNN, sees no difference.
Theorem (Xu et al. 2019, Lemma 2; Morris et al. 2019). If 1-WL gives two graphs the same colour histograms in every round, then every MPNN whose input features are a function of the initial colours gives them the same graph-level output.
Why this is true: an MPNN layer is one round of 1-WL in which HASH is replaced by a learned function that may merge colours but never splits them. So it can never see more than 1-WL.
Proof.
- Claim: after layers, for some function , for every node of both graphs. In words: equal colours imply equal embeddings.
- For this holds by the assumption on the input features.
- Step from to . Let for nodes , in either graph. HASH is injective, so and the multisets of neighbour colours are equal. By the claim for , and the multisets of neighbour embeddings are equal. So the multisets of messages, the aggregates and the outputs of are equal: .
- Equal colour histograms then give equal multisets of final embeddings, hence equal sum, mean or max readouts.
Example. In two triangles and in a 6-ring, every node has degree 2. Round 1 gives every node of both graphs the colour HASH(0, {{0, 0}}), and no colour ever splits. So every MPNN gives both graphs the same output, although only one is connected and only one has triangles. In chemistry, decalin (two 6-rings that share a bond) and bicyclopentyl (two 5-rings joined by a bond) are also indistinguishable by 1-WL (checked in section 5). Plain MPNNs cannot count cycles in general.
Ways out: add structural or positional features (cycle counts, Laplacian eigenvectors), use higher-order GNNs (-WL, cost ), add random node identifiers (exact equivariance is lost), or use geometry (3-D positions; see the deeper box at the end of this section).
Graph is a path of 5 nodes. Graph is a triangle plus a separate edge (also 5 nodes and 4 edges). Every node starts with the same colour. What does 1-WL report?
Round 1 colours each node by its degree, and both graphs have the degrees 1, 1, 2, 2, 2. In round 2, the path has a degree-2 node with neighbours of degree 1 and 2. In the triangle every degree-2 node has two neighbours of degree 2. That colour exists only in , so the histograms differ. 1-WL works on any graph, connected or not.
Sum, mean or max? (GIN) #
Simplest case: one-hot features. Let each neighbour carry the one-hot vector of its type, or . Then:
- the sum is the count vector, which is the multiset: it loses nothing (it is injective);
- the mean is the count vector divided by the degree: it keeps the proportions and loses the size;
- the max is the 0/1 indicator of the types present: it keeps the set and loses the counts.
Build two neighbour multisets with the + and − buttons. Type a is blue, type b is violet. The table shows the sum, mean and max of the one-hot vectors for both multisets. An aggregator that gives the same output for two different multisets is marked confused (magenta); one that separates them is marked separates (aqua). Try the presets: mean loses the size, max loses the counts, and the sum separates every pair.
Xu et al. (2019) prove the general version. For countable features, there is a function such that is injective on bounded multisets (Lemma 5). Mean captures only the distribution of the multiset, and max only its underlying set (Corollaries 8 and 9). A GNN with injective aggregation, update and readout is as powerful as 1-WL (Theorem 3). Their graph isomorphism network (GIN) meets these conditions:
with learned or fixed. The factor keeps the node's own state apart from the neighbour sum (Corollary 6). The MLP matters: one linear map followed by a ReLU, as in GCN, is not enough (§5.1 of the paper). GCN and GraphSAGE (mean or max, with one-layer perceptrons) are strictly less powerful than 1-WL. Mean is still a good choice when proportions matter and the features are rich. Sum is the choice when counts matter: the number of hydrogen atoms, a total energy.
Node has neighbours with features ; node has neighbours (one-hot types). Which aggregators give and different results?
Sum gives and : different. Mean gives for both: the proportions are the same. Max gives for both: the same set of types is present. Only the sum keeps the size of the multiset.
Over-smoothing #
Simplest case: drop the weights and the nonlinearity. Then layers compute for a feature column . Each step is a low-pass filter. What is left after many steps?
Move the slider (the number of applications of ). The graph has three communities (blue, aqua, violet), and each node has a noisy 2-D feature. The right panel shows the features of all nodes. A few steps remove the noise inside each community and the three groups separate. Many steps push every node towards one common direction (the dashed ray), scaled by : the nodes then differ only by their degree. The first chart splits into three parts, as fractions of on a log scale: the spread inside the communities (noise, magenta), the spread between them (signal, aqua), and the smooth part , which carries only degree information (blue). The second chart shows the accuracy of a nearest-class-mean classifier (a linear probe) on the features: it rises from 0.75 to 1, then falls towards chance as the smooth part takes over.
Theorem (over-smoothing of linear propagation). Let the graph be connected. Write with orthonormal eigenvectors and . Let . Then , , and
In the limit, node holds : one common number times .
Why this is true: repeated multiplication by is power iteration (linear-algebra lesson 05). Every eigen-direction is multiplied by ; only the direction with survives.
Proof (four steps)
- is symmetric, so it has real eigenvalues and orthonormal eigenvectors. All eigenvalues lie in (linear-algebra lesson 19).
- . So is an eigenvector with eigenvalue 1.
- The eigenvalue 1 is simple. With the Laplacian , we have . So is constant (for a connected graph, spans the null space of ) . With step 1, every other eigenvalue has , so .
- . The term is for every . Every other coefficient shrinks by a factor , and orthogonality gives .
What it means. Every feature column tends to a multiple of , so the nodes differ only by their degree. With mean aggregation, every node tends to the same value. Dense, well-mixed graphs (small ) over-smooth in a few layers.
- Weights do not save you. A linear GCN computes : acts on the nodes and the weight matrices act on the channels, so the weights cannot undo the filter over the nodes. With ReLU, Oono and Suzuki (2020) show that the distance to the "degree-only" subspace is , with the largest singular value of the weights. When , the output keeps only degree (and connected-component) information.
- Smoothing is also the signal. When neighbours usually share the label (homophily), a few rounds remove noise and keep the class. This is why a 2-layer GCN works on citation graphs. Section 5 shows both sides on one graph.
- Fixes: residual connections , initial residuals (GCNII), normalization (PairNorm), DropEdge, or only 2–3 layers.
A common measure of smoothness is the Dirichlet energy . It is 0 exactly on the over-smoothed limit and decays to 0 with depth.
The eigenvalues of other than 1 satisfy . After how many propagation steps is the non-smooth part of guaranteed to be below 1% of its initial size?
We need , so : 90 steps. The decay is geometric but slow when is close to 1. For the star graph of section 4, and 7 steps are enough ().
Over-squashing #
After layers, node sees its -hop neighbourhood. On trees and small-world graphs this neighbourhood grows exponentially with . All of it must fit into one fixed-size vector , and it must pass through the few edges that join distant regions (the bottlenecks). This is over-squashing (Alon and Yahav 2021).
Topping et al. (2022, Lemma 1) bound it for an MPNN that aggregates with the weights . If the derivatives of and are bounded by and , a node at distance from satisfies
Here is the input feature of node . A walk of length between nodes at distance must be a shortest path. So is a sum, over the shortest paths, of products of factors . The bound is small when few paths join and . In a tree there is only one path, and the bound decays exponentially in .
| Over-smoothing | Over-squashing | |
|---|---|---|
| What goes wrong | node states become too similar | distant information cannot get through |
| Cause | repeated averaging (a low-pass filter) | exponential receptive field, fixed-size vectors, bottleneck edges |
| Measured by | distance to the smooth subspace, ; Dirichlet energy | the Jacobian |
| Fixes | residuals, GCNII, PairNorm, fewer layers | rewiring (add edges), a virtual node, a fully connected last layer, global attention, multi-scale meshes |
Graph attention #
Graph attention (GAT) (Veličković et al. 2018) replaces the fixed weights by learned attention weights. With , a score ( is concatenation, a learned vector), weights , and output . This is self-attention whose softmax runs only over the neighbours: attention masked by . GAT scores pairs with a small additive network, not with a scaled dot product, but the idea is the same. A transformer is the special case of the complete graph, with positional encodings (lesson 10) in place of the graph structure.
E(3)-equivariant GNNs: what geometry adds
Atoms also have positions . Rotating, reflecting or translating the whole system (the group E(3)) leaves the energy unchanged and rotates the forces. A plain MPNN on the bond graph ignores geometry. Raw coordinates as input features break the symmetry, which the model must then learn from data, and only approximately. There are two ways to build the symmetry in:
- Invariant models use only invariant inputs in the messages: distances (SchNet), plus angles (DimeNet).
- Equivariant models also carry vector or tensor features that rotate with the input. EGNN (Satorras et al. 2021) uses , and . The vectors rotate with the system and ignore translations, and is invariant, so is equivariant. NequIP and MACE use features labelled by the irreducible representations of SO(3) (spherical harmonics of degree ), combined by Clebsch–Gordan tensor products.
What this buys: exact symmetry (an invariant energy , and forces from autodiff that are equivariant automatically; proof in linear-algebra lesson 19); data efficiency (NequIP reports better accuracy than earlier models with up to three orders of magnitude less training data); and information that the bond graph lacks (distances, angles, orientation). The ML-for-science track covers these models in depth.
Training a small GCN #
Kipf and Welling's model for semi-supervised node classification is
with the cross-entropy over the labelled nodes only, and one forward pass over the full graph per step (16 hidden units, dropout 0.5, weight decay , Adam with learning rate 0.01). On Cora (2,708 papers, 7 classes, 20 labels per class) it reaches 81.5% test accuracy, against 55.1% for an MLP on the features alone (their Table 3). The setting is transductive: the unlabelled nodes are in the graph during training, so their features flow through into the predictions of the labelled nodes. An inductive model must handle new nodes or new graphs at test time.
Answers to section 1. (1) No. Every node of both graphs has degree 2, so 1-WL gives every node the same colour in every round, and the theorem gives equal outputs. For GCN you can also see it directly: everywhere and , so a constant feature stays constant. You need extra features (triangle counts), a more expressive model, or geometry. (2) The accuracy drops. Each layer is a low-pass filter, and 32 of them push all node states towards times a common vector (over-smoothing). A deep plain stack is also hard to optimize. Kipf and Welling found 2–3 layers best, and beyond about 7 layers training was difficult without residual connections (their Appendix B).
4. Worked example #
The star graph: a hub with three leaves. Node 1 is the centre, joined to leaves 2, 3 and 4. (A "virtual node" joined to every node is such a hub.)
Step 1: degrees with self-loops. The centre has 3 neighbours plus itself: . Each leaf has 1 neighbour plus itself: .
Step 2: the matrix . Each entry is . Centre–centre: . Centre–leaf: . Leaf–itself: . Leaf–leaf: 0 (no edge).
Step 3: one propagation of the feature , with three aggregations:
- GCN: centre ; leaf 2 ; so .
- Plain sum with self-loops: . The centre value grows with its degree.
- Mean with self-loops: .
Step 4: the spectrum.
- , with eigenvector . Check the centre row: ✓. A leaf row: ✓.
- , twice: differences between leaves with the centre at 0, such as and . The centre receives , and each leaf keeps half its value.
- The last eigenvalue from the trace: , so , with eigenvector .
- So .
Step 5: over-smoothing. , and . So
Every leaf ends at 1.2, whatever its own value was. The centre ends at (the ratio ). The rest of is in the space (squared norm 2), plus a part with squared norm 4.8 in the space. So the error after steps is : 0.894 at , 0.044 at , and 0.0014 at . With mean aggregation, all four nodes tend to .
Step 6: multisets. One-hot types and :
| neighbours | sum | mean | max |
|---|---|---|---|
| (1, 1) | (0.5, 0.5) | (1, 1) | |
| (2, 2) | (0.5, 0.5) | (1, 1) | |
| (2, 1) | (0.667, 0.333) | (1, 1) |
Sum separates all three. Mean confuses the first two (same proportions). Max confuses all three (same set).
Step 7: parameters. Kipf and Welling's Cora model has weights (their Eq. 9 has no biases; 23,063 with biases). The same weights run on a graph of any size.
In the star graph, the leaves start with the values 1, 2 and 3 (the centre with 0). After many GCN propagations, what value does each leaf hold?
Many steps keep only the top eigenvector . All leaves have the same degree, so they end at the same value . The start values of the leaves are lost; only the weighted average survives.
5. In code #
NumPy checks the worked example, the 1-WL examples, equivariance of masked attention, and shows smoothing at work on a 3-community graph. The notebook for this lesson has these cells and the exercises.
import numpy as np
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler, normalize
np.set_printoptions(precision=3, suppress=True)
# 1. Worked example: the star graph (centre 0, leaves 1, 2, 3)
A = np.zeros((4, 4))
A[0, 1:] = A[1:, 0] = 1
A_tilde = A + np.eye(4) # self-loops
d = A_tilde.sum(1) # degrees with self-loops: [4. 2. 2. 2.]
A_hat = A_tilde / np.sqrt(np.outer(d, d)) # D^-1/2 (A + I) D^-1/2
h = np.array([0., 1., 2., 3.])
print(A_hat @ h) # [2.121 0.5 1. 1.5 ]
print(np.linalg.eigvalsh(A_hat)) # [-0.25 0.5 0.5 1. ]
u1 = np.sqrt(d) / np.linalg.norm(np.sqrt(d)) # top eigenvector, D^1/2 1 normalized
limit = u1 * (u1 @ h)
print(limit) # [1.697 1.2 1.2 1.2 ]
print([round(float(np.linalg.norm(np.linalg.matrix_power(A_hat, K) @ h - limit)), 4)
for K in (1, 5, 10)]) # [0.8944, 0.0442, 0.0014]
# 2. 1-WL colour refinement: equal colour histograms => no MPNN separates the graphs
def wl_histogram(edges, n, rounds=4):
nbrs = [[] for _ in range(n)]
for a, b in edges:
nbrs[a].append(b)
nbrs[b].append(a)
colour = [0] * n # no node features: one colour
for _ in range(rounds):
colour = [hash((colour[i], tuple(sorted(colour[j] for j in nbrs[i])))) for i in range(n)]
return sorted(colour)
ring = lambda k, o=0: [(o + i, o + (i + 1) % k) for i in range(k)]
decalin = ring(6) + [(1, 6), (6, 7), (7, 8), (8, 9), (9, 0)] # two 6-rings sharing the bond 0-1
bicyclopentyl = ring(5) + ring(5, 5) + [(0, 5)] # two 5-rings joined by the bond 0-5
print(wl_histogram(ring(3) + ring(3, 3), 6) == wl_histogram(ring(6), 6),
wl_histogram(decalin, 10) == wl_histogram(bicyclopentyl, 10)) # True True
# 3. Sum, mean and max over one-hot neighbour features a = (1, 0), b = (0, 1)
a, b = np.eye(2)
for name, X in {"{a,b}": [a, b], "{a,a,b,b}": [a, a, b, b], "{a,a,b}": [a, a, b]}.items():
X = np.array(X)
print(name, X.sum(0), X.mean(0).round(3), X.max(0))
# {a,b} [1. 1.] [0.5 0.5] [1. 1.]
# {a,a,b,b} [2. 2.] [0.5 0.5] [1. 1.]
# {a,a,b} [2. 1.] [0.667 0.333] [1. 1.]
# 4. Graph attention = self-attention masked by A + I: equivariant if nodes and mask move together
rng = np.random.default_rng(0)
n, C = 8, 4
adj = rng.random((n, n)) < 0.3
adj = adj | adj.T | np.eye(n, dtype=bool) # undirected, with self-loops
Wq, Wk, Wv = rng.standard_normal((3, C, C))
def masked_attention(X, adj):
S = (X @ Wq) @ (X @ Wk).T / np.sqrt(C)
S = np.where(adj, S, -np.inf) # a node only attends to its neighbours
P = np.exp(S - S.max(1, keepdims=True))
return (P / P.sum(1, keepdims=True)) @ (X @ Wv)
W_mlp = rng.standard_normal((n * C, n * C)) # a dense layer on the flattened node table
mlp = lambda X: (X.reshape(-1) @ W_mlp).reshape(n, C)
X = rng.standard_normal((n, C))
perm = rng.permutation(n)
err_att = np.abs(masked_attention(X[perm], adj[perm][:, perm]) - masked_attention(X, adj)[perm]).max()
err_mlp = np.linalg.norm(mlp(X[perm]) - mlp(X)[perm]) / np.linalg.norm(mlp(X))
print(f"{err_att:.1e}", round(float(err_mlp), 2)) # 4.4e-16 1.33
# 5. Smoothing on a 3-community graph: it helps, then it over-smooths
rng = np.random.default_rng(0)
n, k = 300, 3
y = np.repeat(np.arange(k), n // k)
U = np.triu(rng.random((n, n)) < np.where(y[:, None] == y[None, :], 0.08, 0.005), 1)
A = (U | U.T).astype(float)
X = 0.35 * rng.standard_normal((k, 16))[y] + rng.standard_normal((n, 16)) # weak features
train = np.zeros(n, bool)
for c in range(k):
train[rng.choice(np.flatnonzero(y == c), 10, replace=False)] = True
P = normalize(A + np.eye(n), norm="l1") # mean over the node and its neighbours
for K in (0, 1, 2, 8, 32, 128, 512):
Z = np.linalg.matrix_power(P, K) @ X
spread = np.linalg.norm(Z - Z.mean(0)) / np.linalg.norm(Z)
acc = [LogisticRegression(max_iter=5000).fit(F[train], y[train]).score(F[~train], y[~train])
for F in (Z, StandardScaler().fit_transform(Z))]
print(K, f"{spread:.1e}", np.round(acc, 3))
# 0 9.8e-01 [0.504 0.493]
# 1 8.8e-01 [0.93 0.9 ]
# 2 7.6e-01 [0.993 0.996]
# 8 4.1e-01 [0.993 0.993]
# 32 2.5e-02 [0.993 0.993]
# 128 6.8e-07 [0.333 0.989]
# 512 4.1e-15 [0.333 0.333]
Part 4: masked attention is equivariant up to round-off; the dense layer is not. Part 5 prints, for each , the relative spread between nodes and the test accuracy of a logistic regression on the raw and on the standardized features. 89% of the edges join nodes of the same class, so two rounds of averaging lift the accuracy from 0.50 to 0.99. Then the spread shrinks like (0.9 is the second eigenvalue of , which comes from the communities). At the differences between nodes are about of the common part, and the classifier on raw features predicts one class. After standardization the class signal survives until round-off erases it at .
6. Where it shows up #
- Molecules and materials. Interatomic potentials (SchNet, NequIP, MACE) predict the energy as a sum of atomic terms (a sum readout) and the forces by autodiff. They run molecular dynamics far more cheaply than density functional theory (DFT).
- Weather and climate. GraphCast has an encoder (from the 0.25° grid to a mesh), a processor of 16 GNN layers with unshared weights on a multi-mesh, and a decoder (from the mesh back to the grid). The multi-mesh is an icosahedron refined 6 times (40,962 nodes), with the edges of all refinement levels. Coarse edges carry information far in a few hops: a fix for over-squashing. ECMWF's AIFS uses GNN encoders and decoders around a transformer processor.
- PDE surrogates. MeshGraphNets (Pfaff et al. 2021) use encode–process–decode with 15 message-passing steps on simulation meshes.
- Seismology. Van den Ende and Ampuero (2020) locate earthquakes and estimate magnitudes with a GNN over the station network, for any number of stations in any order.
- Recommendation and citation graphs. Node classification and link prediction with GCN, GraphSAGE (sampled neighbours, inductive) and GAT.
7. Common mistakes #
- Wrong edge direction. Messages flow from source to target. Aggregating by the wrong row of
edge_indexreverses the graph. An undirected edge must appear in both directions. - No self-loops or no normalization. Without self-loops, a node ignores its own state. Without normalization, features scale with the degree and explode with depth.
- A mean readout for an extensive target. A total energy grows with the number of atoms; use a sum readout.
- Stacking plain GCN layers to see further. Depth over-smooths. Use residuals, GCNII, or long-range edges.
- "The MLP inside makes it universal." The 1-WL limit comes from what the aggregation sees. No MLP removes it.
- Breaking equivariance by accident: ordering neighbours by their index, using node IDs as features, or using Laplacian eigenvectors without handling their sign ambiguity.
- Label leakage. In transductive training, the labels of test nodes must not be used, not even for early stopping.
8. Check yourself #
- Compute for a triangle (3 nodes, all joined). What does one GCN propagation do?
Answer
is the all-ones matrix and , so . Then : every node gets the mean of all nodes. The eigenvalues are 1, 0, 0, so : one propagation over-smooths completely. - Give two neighbour multisets that both mean and max confuse but sum separates. Then give two
that max confuses but mean separates.
Answer
and : the mean is and the max is for both, but the sums are and . and with : the same set, so the same max; the means and differ by . - A layer concatenates the features of a node's neighbours in increasing node-index order (padded
with zeros up to degree 3) and applies an MLP. Is it permutation-equivariant?
Answer
No. After a relabelling, the same neighbours appear in a different order, so the MLP sees a permuted input and in general gives a different output: the layer depends on the numbering. A symmetric aggregation (sum, mean, max, attention) fixes this. - The non-top eigenvalues of have . How many propagation steps until the
non-smooth part of is guaranteed to be below 1% of its initial size? And for the star graph?
Answer
: 90 steps. The star has : 7 steps (). - You add a virtual node joined to all nodes. Which depth problem does this address, and what
is its cost?
Answer
Over-squashing and long-range transport: any two nodes are now at most 2 hops apart. The cost: the virtual node is itself one fixed-size vector for all nodes (a new bottleneck), and the extra edges speed up mixing, which can make over-smoothing faster. - You predict the total energy of molecules of different sizes. Sum or mean readout? And how do
you get forces that rotate with the molecule?
Answer
Sum: energy is extensive. Two far-apart copies of a molecule have twice the energy; a sum readout doubles, a mean does not. For forces, predict an E(3)-invariant energy and take by autodiff; the chain rule makes rotate with the molecule.
Write the three steps of one message-passing layer.
Message ; aggregate (order-independent); update .
Write the GCN layer.
with , , .
Why does GCN add self-loops and use the symmetric normalization?
Self-loops make depend on . The normalization keeps the eigenvalues of in , so stacked layers do not blow up and hubs do not dominate.
State permutation equivariance of a GNN layer .
for every permutation matrix : relabelling the nodes only relabels the outputs.
Why is the sum readout permutation-invariant?
, because (each row of has exactly one 1).
What is the 1-WL limit of message-passing GNNs?
If 1-WL colour refinement gives two graphs equal colour histograms in every round, every MPNN gives them the same graph-level output. Example: two triangles vs a 6-ring.
Why is sum aggregation more expressive than mean or max?
On one-hot features the sum is the count vector, which is the whole multiset. Mean keeps only proportions (loses the size); max keeps only the set (loses the counts).
After GCN propagations on a connected graph, what does a feature column converge to, and how fast?
To with (one common number times ); the rest shrinks like , = largest , .
What is over-squashing?
The -hop neighbourhood grows exponentially, but it must pass through a few bottleneck edges into one fixed-size vector, so far-away inputs barely change .
Compute for the triangle graph.
= all ones, , so : one step replaces every feature by the mean.
9. Interview angle #
- "Why ?" — Self-loops keep the node's own state. The normalization keeps the eigenvalues in , so stacking is stable. It is a first-order spectral filter.
- "How powerful are GNNs?" — At most as powerful as 1-WL. GIN reaches it with sum aggregation and an MLP. Two triangles vs a 6-ring is the standard counterexample. Fixes: structural or positional features, higher-order GNNs, geometry.
- "Why does depth not help GNNs?" — Over-smoothing () and over-squashing (the Jacobian bound, bottlenecks), with the fixes for each.
- "GNN vs transformer?" — A transformer is a GNN on the complete graph with attention weights. Positional encodings stand in for the graph structure. GAT is masked attention.
- "Design a model for molecules, or for weather on the sphere." — An E(3)-invariant energy with autodiff forces and equivariant messages; encode–process–decode on a multi-scale mesh.
10. Practice #
The notebook for this lesson runs in Colab. It uses NumPy for the graph operations and PyTorch for training. Five exercises, each with a check cell and a folded solution:
- Build the normalized adjacency from
edge_index, checked on the star graph. - Message passing with scatter-add (
np.add.at), checked against the dense product . - A permutation-equivariance test for your layer, and a test that must fail for a layer that is not equivariant.
- 1-WL colour refinement on two graphs: separate a path from a triangle plus an edge, and fail on two triangles vs a hexagon.
- Train a 2-layer GCN on a synthetic 3-community graph, then show over-smoothing as the depth grows.
11. Watch and read #
- Simon Prince, Understanding Deep Learning (free PDF), chapter 13: §13.3–13.4 (tasks, equivariance, parameter sharing, a GCN layer), §13.6–13.8 (transductive training; mean, Kipf normalization, max and attention layers), and the chapter notes on the power of GNNs and over-smoothing.
- Sanchez-Lengeling et al., A Gentle Introduction to Graph Neural Networks (Distill, 2021): interactive figures of message passing, pooling and readouts.
- Xu et al., How Powerful are Graph Neural Networks? (2019): §2 (the WL test), §4 (Lemma 5, Corollary 6, GIN), §5 (one-layer perceptrons, mean and max).
- Kipf and Welling, Semi-Supervised Classification with Graph Convolutional Networks (2017): §2 (the propagation rule), §3.1 (the two-layer model), Table 3 (propagation models), Appendix B (depth and residual connections).
- Topping et al., Understanding over-squashing and bottlenecks on graphs via curvature (2022): Lemma 1 (the Jacobian bound).
- PyTorch Geometric, Creating Message Passing Networks:
the
MessagePassingclass and the GCN layer step by step.
Runs in your browser with nothing to install. The notebook repeats the key demos and has exercises with checks; solutions are inside, folded.