Before you start: review of the earlier sessions
The thread so far. Session 3 gave one GNN; session 4 gives the grammar that generates all of them. Lecture 19 will measure this design space empirically.
What this session takes from earlier ones
Those sessions in one minute each
Lecture 3 · Graph Neural Networks
A GNN layer = for every node, combine its own vector with an order-free aggregate of its neighbours' vectors, using weights shared across all nodes; stacking K layers lets information travel K hops.
Rows of \(H\) are node embeddings; \(D^{-1}A\) averages over neighbours; \(W_k\) transforms the neighbourhood message; \(B_k\) transforms the node itself.
Define similarity by co-occurrence on short random walks, then learn one vector per node so that dot products reproduce it — fast with negative sampling, but just a lookup table.
\(N_R(u)\): multiset of nodes visited by walks from \(u\) under strategy \(R\) (uniform for DeepWalk, \(p,q\)-biased for node2vec); \(n_i\): negatives sampled ∝ degree; \(\sigma\): sigmoid.
Warm-up: answer these before you read on
What goes wrong if the aggregation is not permutation invariant? from Lecture 3
The embedding would depend on the arbitrary order in which the neighbours are listed, so the same graph could receive different embeddings.
What do p and q control in node2vec? from Lecture 2
The return parameter p penalises stepping back to the previous node; the in-out parameter q biases towards staying close (BFS, small q favours DFS). They trade off local versus structural similarity.
What does the self-loop (or the B matrix) do in the GCN layer? from Lecture 3
It keeps the node's own previous vector in the update, so a node does not forget its own features while absorbing its neighbours'.
Give the three limits of shallow embeddings. from Lecture 2
No parameter sharing (one vector per node), no use of node features, and no embedding for nodes unseen at training time (transductive).
More questions from every session you have reached, with spaced repetition: the cumulative review.
In short
Lecture 3 gave one GNN. This lecture gives the grammar that generates all of them. A GNN is specified by five choices: (1) the message each neighbour sends, (2) how messages are aggregated, (3) how layers are connected (stacked, skipped), (4) how the input graph is augmented into a computation graph, and (5) the learning objective.
Inside one layer, GCN, GraphSAGE and GAT differ mainly in who weighs the neighbours: GCN weighs them by degree, GraphSAGE concatenates the node with a pooled summary of its neighbours, and GAT learns the weights with attention.
Across layers, the big surprise is that deeper is not better: stacking many layers makes every node's receptive field cover the whole graph, so embeddings become indistinguishable — over-smoothing. The remedies are shallow-but-expressive layers, pre/post MLPs, and skip connections.
Parts (4) augmentation and (5) objectives are Lecture 5. This page covers (1)–(3).
The picture: the GNN design space
How to read it (hover a step)
- Message \(\mathbf{m}_u^{(l)}=\text{MSG}^{(l)}(\mathbf{h}_u^{(l-1)})\), e.g. a linear layer \(\mathbf{W}^{(l)}\mathbf{h}_u^{(l-1)}\). Every neighbour prepares what it sends.
- Aggregation \(\mathbf{h}_v^{(l)}=\text{AGG}^{(l)}(\{\mathbf{m}_u^{(l)}: u\in N(v)\},\ \mathbf{m}_v^{(l)})\): sum, mean, max, attention… must be order-invariant. Include the node's own message, or its information gets lost.
- Layer connectivity: plain stacking, residual skips, or "jump" every layer to the output.
- Graph augmentation: the raw graph need not be the computation graph (add features, add/drop edges, sample neighbours) — Lecture 5.
- Objective: supervised / self-supervised; node / edge / graph level — Lecture 5.
1 · A single GNN layer = message + aggregation
A layer compresses a set of vectors (the node's own and its neighbours') into one vector, in two steps. Putting it together:
Usually the self-message uses a different matrix (\(\mathbf{B}^{(l)}\) vs \(\mathbf{W}^{(l)}\)) and is combined by concatenation or summation. A non-linearity \(\sigma\) (ReLU most common; PReLU often better; sigmoid only when you need bounded outputs) adds expressiveness.
2 · Three classic layers in the same language
| Message | Aggregation | Weight of neighbour u for v | |
|---|---|---|---|
| GCN (Kipf & Welling 2017) | \(\mathbf{m}_u=\frac{1}{|N(v)|}\mathbf{W}^{(l)}\mathbf{h}_u^{(l-1)}\) | \(\sigma(\text{Sum})\) over \(N(v)\) (self-loops included) | fixed: \(1/|N(v)|\) (paper: \(1/\sqrt{d_ud_v}\)) |
| GraphSAGE (Hamilton et al. 2017) | inside AGG (e.g. MLP) | \(\sigma(\mathbf{W}\cdot\text{CONCAT}(\mathbf{h}_v,\text{AGG}(\{\mathbf{h}_u\})))\) | depends on AGG: mean, pool, LSTM |
| GAT (Veličković et al. 2018) | \(\mathbf{W}^{(l)}\mathbf{h}_u^{(l-1)}\) | \(\sigma(\sum_u\alpha_{vu}\mathbf{m}_u)\) | learned: \(\alpha_{vu}=\text{softmax}_u(e_{vu})\) |
GraphSAGE: concatenate self with a neighbourhood summary
Two-stage aggregation: first \(\mathbf{h}_{N(v)}=\text{AGG}(\{\mathbf{h}_u^{(l-1)}\})\), then \(\mathbf{h}_v^{(l)}=\sigma(\mathbf{W}^{(l)}[\mathbf{h}_v^{(l-1)}\,\|\,\mathbf{h}_{N(v)}])\). Aggregator options:
- Mean — weighted average of neighbours.
- Pool — transform each neighbour with an MLP, then mean/max: \(\text{Mean}(\{\text{MLP}(\mathbf{h}_u)\})\).
- LSTM — run an LSTM over a random shuffle \(\pi(N(v))\) of neighbours. Not permutation invariant; the shuffle is a training-time workaround.
Optional \(\ell_2\) normalisation \(\mathbf{h}_v\leftarrow \mathbf{h}_v/\|\mathbf{h}_v\|_2\) at every layer puts all embeddings on the unit sphere; sometimes it helps.
GAT: let the network decide which neighbours matter
In GCN/GraphSAGE the weight \(\alpha_{vu}=1/|N(v)|\) is fixed by structure: all neighbours are equally important. GAT makes it a learned function of the two nodes:
- Score every edge: \(e_{vu}=a(\mathbf{W}\mathbf{h}_u,\mathbf{W}\mathbf{h}_v)\), with \(a\) e.g. a single linear layer on the concatenation (the paper adds a LeakyReLU).
- Normalise over the neighbourhood: \(\alpha_{vu}=\exp(e_{vu})/\sum_{k\in N(v)}\exp(e_{vk})\).
- Weighted sum: \(\mathbf{h}_v^{(l)}=\sigma(\sum_{u\in N(v)}\alpha_{vu}\mathbf{W}^{(l)}\mathbf{h}_u^{(l-1)})\).
Multi-head attention runs several independent attention mechanisms and concatenates or sums their outputs — it stabilises training. Benefits: learned importance; computation parallel over edges; storage \(O(|V|+|E|)\); localised; inductive (an edge-wise shared mechanism).
GAT computes attention only over neighbours. What would happen if it attended over all nodes?
It would become a Transformer on the complete graph (Lecture 3, slide 71): \(O(|V|^2)\) cost and the graph structure would disappear unless you inject it some other way — positional encodings or attention biases. That is exactly the design problem of graph transformers (Lecture 8).
3 · GNN layers in practice
The classic layers are a starting point. A suggested modern layer is a pipeline: Linear → BatchNorm → Dropout → Activation → Attention/Gating → Aggregation (from Design Space of GNNs, You et al. 2020).
- Batch normalisation: per feature dimension, re-centre to zero mean and unit variance over the \(N\) node embeddings in the batch, then rescale with learnable \(\gamma,\beta\). Stabilises training.
- Dropout: during training zero out neurons with probability \(p\); in GNNs it's applied to the linear layer of the message function.
- Attention / gating: control how much each message counts.
GraphGym (built into PyG) lets you sweep this design space systematically — useful for the course project.
4 · Stacking layers and the over-smoothing problem
The standard way: stack \(L\) layers, \(\mathbf{h}_v^{(0)}=\mathbf{x}_v\) → … → \(\mathbf{h}_v^{(L)}\). The problem: over-smoothing — all node embeddings converge to the same value.
Explanation via the receptive field (the set of nodes that determine an embedding = the \(K\)-hop neighbourhood). Two nodes' receptive fields overlap in ~1 node at 1 hop, ~20 at 2 hops, almost the whole graph at 3 hops. Same input set ⇒ nearly the same embedding.
Lesson 1 — be cautious with depth
Unlike CNNs, adding GNN layers often hurts. (1) Analyse the receptive field your task needs (e.g. graph diameter); (2) set \(L\) just a bit larger. If a shallow GNN isn't expressive enough:
- Make each layer deeper: make MSG/AGG a 3-layer MLP instead of one linear map.
- Add layers that don't pass messages: MLP pre-processing layers (encode images/text features) and post-processing layers (reasoning over embeddings, graph classification). "In practice, adding these layers works great."
Lesson 2 — skip connections
Early-layer embeddings often separate nodes better. So add shortcuts: \(F(\mathbf{x})\to F(\mathbf{x})+\mathbf{x}\). For a GCN layer:
Why it works: \(N\) skip connections create \(2^N\) paths through the network — an implicit mixture of shallow and deep GNNs (Veit et al. 2016). Alternative: Jumping Knowledge (Xu et al. 2018) — the final layer aggregates all intermediate embeddings \(\mathbf{h}_v^{(0)},\dots,\mathbf{h}_v^{(L)}\) by concat, pooling or LSTM.
The mathematics, step by step
Lecture 3 gave one layer. This session shows that it is one member of a family: every layer is 'compute messages, then aggregate them', and the well-known architectures differ only in how a neighbour is weighted. The cards state the general template, then GCN, GraphSAGE and GAT as three ways to fill it in, and finally the arithmetic behind over-smoothing and the skip connection that counters it.
Symbols used in this session
| symbol | meaning | what kind of object |
|---|---|---|
| \(\mathbf h_v^{(l)}\) | embedding of node \(v\) after layer \(l\) | vector |
| \(\mathbf m_u^{(l)}\) | message computed from node \(u\) in layer \(l\) | vector |
| \(\text{MSG},\ \text{AGG}\) | message function (usually a linear map) and aggregation function (sum, mean or max) | functions; AGG must not depend on the order of its inputs |
| \(N(v)\) | neighbours of \(v\) | set of nodes |
| \(\mathbf W^{(l)}\) | weight matrix of layer \(l\), shared by all nodes | matrix (parameters) |
| \(e_{vu}\) | attention score: how important \(u\)'s message is to \(v\), before normalisation | real number |
| \(\alpha_{vu}\) | attention weight: \(e_{vu}\) after a softmax over the neighbours of \(v\) | number in \((0,1)\); sums to 1 over \(u\in N(v)\) |
| \(\mathbf a\) | weight vector of the attention scoring function | vector (parameters) |
| \(\Vert\) | concatenation: write one vector after the other | operation |
1The general layer: message, then aggregation
In words. Every node turns its previous vector into a message. Every node then combines the messages of its neighbours with its own message into its new vector.
Why it has this form. The two steps separate two jobs. MSG decides what a node says, and is typically \(\mathbf W^{(l)}\mathbf h_u\). AGG decides how a set of messages is combined, and must give the same result for any order of the neighbours: sum, mean and max all do. The node's own message is kept apart from the neighbours' (often with its own matrix, or by concatenation) so that the node's own information is not drowned in the aggregate. A non-linearity is applied at the end.
Watch out. Sum, mean and max are not interchangeable: they forget different things (Lecture 6 makes this exact). The template says nothing about which is best.
2GCN and GraphSAGE as two instances
In words. GCN: message = weight matrix times the neighbour's vector divided by the degree; aggregation = sum. GraphSAGE: aggregate the neighbours with a mean, max-pool or LSTM, glue the result after the node's own vector, then apply one matrix.
Why it has this form. In GCN, dividing each message by \(|N(v)|\) and summing is the same as taking the mean, so GCN is the template with MSG \(=\mathbf W\mathbf h_u/|N(v)|\) and AGG = sum. GraphSAGE's concatenation doubles the input of \(\mathbf W^{(l)}\): the matrix has one block for the node itself and one for its neighbourhood, which is the same as using two separate matrices and adding. GraphSAGE optionally rescales each \(\mathbf h_v^{(l)}\) to length 1 (\(\ell_2\) normalisation) so that vectors of high-degree and low-degree nodes are comparable.
Watch out. The GCN formula as written has no term for the node itself; in practice a self-loop is added, so \(v\) is counted among its own neighbours.
3GAT: neighbours weighted by attention
In words. Score each neighbour from the pair of transformed vectors, turn the scores of one node's neighbours into weights that sum to one, and take the weighted sum of the neighbours' messages.
Why it has this form. In GCN the weight of neighbour \(u\) is fixed by the graph: \(1/|N(v)|\). GAT replaces it by a learned number. The score \(e_{vu}\) is a tiny one-layer network on the two endpoints; the softmax makes the weights positive, comparable across nodes of different degree, and summing to one, so the update is still a (weighted) average. With several heads, the computation is repeated with independent \(\mathbf W,\mathbf a\) and the results are concatenated (or averaged in the last layer), which makes training more stable.
Watch out. The attention weights are computed only over existing edges: GAT does not look at non-neighbours (a transformer does, Lecture 8). \(\alpha_{vu}\neq\alpha_{uv}\) in general.
4Over-smoothing and the skip connection
In words. Add the layer's input back to its output. The layer then only has to learn the change to the embedding, and the node's earlier, more local vector is never lost.
Why it has this form. Each layer of averaging pulls neighbouring vectors together. After \(K\) layers a node's vector is an average over everything within \(K\) hops; once \(K\) reaches the diameter of the graph, every node averages over (almost) the same set and all embeddings become nearly equal. With the skip, unrolling \(L\) layers gives a sum of terms that passed through \(0,1,\dots,L\) layers: a mixture of shallow and deep models, in which the shallow, still-distinct terms survive.
Watch out. More layers is not more expressive power here. If a task needs a larger receptive field than the number of useful layers, add skip connections or make each layer richer, rather than stacking plain layers.
5Batch normalisation and dropout inside a layer
In words. For each coordinate \(j\) of the embedding, subtract the mean over the nodes in the batch and divide by the standard deviation, then rescale and shift with two learned numbers.
Why it has this form. Activations whose scale drifts from layer to layer make gradient descent slow or unstable; normalising gives every coordinate mean 0 and variance 1 before the learned \(\gamma_j,\beta_j\) choose a scale. Dropout is the complementary trick against over-fitting: during training each coordinate of a message is set to zero with probability \(p\) and the rest are divided by \(1-p\), so the expected value is unchanged; at test time nothing is dropped.
Watch out. Batch normalisation uses statistics of the batch during training and stored running averages at test time; forgetting to switch the model to evaluation mode is a classic source of wrong test numbers.
Check yourself
Questions from the lecture, in order. Answer each one in your head (or on paper) before you open it. If one stumps you, follow the link to the walkthrough block it comes from.
Check yourself: in the tree of a 2-layer GNN, how many grey boxes sit at layer 1 for a node of degree 5? show answer
Five — one per neighbour — and each of them has its own children.
from Recap: deep graph encoders and computation graphs
Check yourself: with Sum aggregation and all features equal to 1, what does a 1-layer GNN compute for each node? show answer
(Its degree, times a weight.) With Mean? (A constant — mean cannot see the degree.)
from A single GNN layer: message and aggregation
Check yourself: an LSTM reads its input in order, so it is not permutation invariant. Why does a random shuffle \(\pi\) help? show answer
Training on many random orders pushes the LSTM to ignore the order, so it becomes approximately invariant — but there is no guarantee.
from Classic layer 2: GraphSAGE and its aggregators
Check yourself: in the skip-GCN formula, the self term \(\mathbf{h}_v^{(l-1)}\) has no weight matrix. What constraint does that put on the layer dimensions? show answer
Input and output dimensions must be equal, or you need a projection on the skip path.
Lecture walkthrough reference · slide by slide · opens on demand
The whole lecture in order, grouped by topic. Every drawing on the slides is redrawn here as a clean figure (click the step buttons where a figure has them), the heading of each block links to the matching pages of the official PDF, and the Review section after the walkthrough ties this session to the earlier ones. Read this and you do not need the deck.
- Recap: deep graph encoders and computation graphs
- A general GNN framework: five design choices
- A single GNN layer: message and aggregation
- Do not lose the node itself; non-linearities
- Classic layer 1: GCN as message + aggregation
- Classic layer 2: GraphSAGE and its aggregators
- Classic layer 3: why attention? Not all neighbours are equal
- The attention mechanism step by step, multi-head attention and its benefits
- GNN layers in practice: modern modules and batch normalisation
- Dropout, and where it goes in a GNN
- Stacking layers and the over-smoothing problem
- Lesson 1: be careful with depth; make shallow GNNs expressive
- Lesson 2: skip connections and jumping knowledge
Recap: deep graph encoders and computation graphs slides 4-7 ↗
The lecture opens with a short recap of Lecture 3. Slide 4 shows the deep graph encoder: the input graph goes through graph-convolution layers, activation functions and regularisation (for example dropout), more graph convolutions, and so on; the output is a node embedding for every node (and, by pooling, embeddings of subgraphs and whole graphs).
Slide 5 restates the central idea (Kipf and Welling): a node's neighbourhood defines a computation graph. First determine the computation graph of node \(i\) (the rings of neighbours at distance 1 and 2), then propagate and transform information along it. The goal is to learn how to propagate information across the graph to compute node features.
Slide 6: nodes aggregate information from their neighbours using neural networks — each grey box in the tree of target node A is a small network that takes the vectors arriving from the children. Slide 7: every node defines its own computation graph based on its neighbourhood; the figure draws a separate tree under each node of the input graph, and the trees differ in shape.
The question for today: Lecture 3 used one specific box (average the neighbours, then a linear map and a non-linearity). What are all the reasonable choices for the box and for how boxes are wired together? This lecture builds a general vocabulary in which GCN, GraphSAGE and GAT are just three settings.
Check yourself: in the tree of a 2-layer GNN, how many grey boxes sit at layer 1 for a node of degree 5? show answer
Five — one per neighbour — and each of them has its own children.
A general GNN framework: five design choices slides 8-13 ↗
Slides 8–13 introduce the framework from You, Ying and Leskovec, "Design Space of Graph Neural Networks" (NeurIPS 2020). The figure is a two-layer computation tree, labelled with five numbered parts:
- Message — what each node sends to its neighbours.
- Aggregation — how a node combines the messages it receives. Slide 9: GNN layer = message + aggregation, and different choices give GCN, GraphSAGE, GAT, …
- Layer connectivity (slide 10) — how layers are connected into a full GNN: stack them sequentially, and possibly add skip connections.
- Graph augmentation (slide 11) — the idea that the raw input graph ≠ the computational graph. We may change the features (graph feature augmentation) or the structure (graph structure augmentation) before message passing.
- Learning objective (slide 12) — how we train: supervised or unsupervised objectives, at the node, edge or graph level. (These are discussed later in the course.)
Slide 13 repeats the full picture as a summary. In the figure, layer 2 sits above layer 1: messages flow upward from the leaves (input features), each layer has its own message and aggregation, and the arrows between the layers are "layer connectivity". Graph augmentation acts at the bottom (on what the tree is built from), and the learning objective at the top (on the final embedding).
This lecture covers parts 1–3. Parts 4–5 are the subject of Lecture 5.
A single GNN layer: message and aggregation slides 15-18 ↗
Slide 15 zooms in on parts 1 and 2. Slide 16 states the idea of a GNN layer: compress a set of vectors into a single vector. The input is the node's own previous embedding \(\mathbf{h}_v^{(l-1)}\) and the neighbours' previous embeddings \(\mathbf{h}_{u}^{(l-1)}, u\in N(v)\); the output is the new embedding \(\mathbf{h}_v^{(l)}\). It works in two steps: (1) message, (2) aggregation.
(1) Message computation (slide 17). A message function turns each node's embedding into a message:
\[ \mathbf{m}_u^{(l)}=\mathrm{MSG}^{(l)}\big(\mathbf{h}_u^{(l-1)}\big). \]Intuition: each node creates a message that will be sent to other nodes later. Example: a linear layer, \(\mathbf{m}_u^{(l)}=\mathbf{W}^{(l)}\mathbf{h}_u^{(l-1)}\) — multiply the node features by a weight matrix. The figure marks the message step as the small boxes just above the coloured leaf nodes.
(2) Aggregation (slide 18). Node \(v\) aggregates the messages from its neighbours:
\[ \mathbf{h}_v^{(l)}=\mathrm{AGG}^{(l)}\Big(\big\{\mathbf{m}_u^{(l)},\ u\in N(v)\big\}\Big). \]Examples: Sum\((\cdot)\), Mean\((\cdot)\) or Max\((\cdot)\) aggregators, e.g. \(\mathbf{h}_v^{(l)}=\mathrm{Sum}(\{\mathbf{m}_u^{(l)},u\in N(v)\})\). The input is a set (more precisely a multiset), so AGG must not depend on the order of its inputs — this is what keeps the layer permutation equivariant (Lecture 3).
Check yourself: with Sum aggregation and all features equal to 1, what does a 1-layer GNN compute for each node? show answer
(Its degree, times a weight.) With Mean? (A constant — mean cannot see the degree.)
Do not lose the node itself; non-linearities slides 19-21 ↗
Slide 19 points out an issue with the aggregation above: the information from node \(v\) itself can get lost, because \(\mathbf{h}_v^{(l)}\) does not directly depend on \(\mathbf{h}_v^{(l-1)}\) — only the neighbours' messages enter.
Solution: include \(\mathbf{h}_v^{(l-1)}\) when computing \(\mathbf{h}_v^{(l)}\).
- Message: also compute a message from \(v\) itself. Usually a different computation is used for the self-message: \(\mathbf{m}_u^{(l)}=\mathbf{W}^{(l)}\mathbf{h}_u^{(l-1)}\) for neighbours, \(\mathbf{m}_v^{(l)}=\mathbf{B}^{(l)}\mathbf{h}_v^{(l-1)}\) for the node itself (the figure colours the two kinds differently).
- Aggregation: first aggregate from the neighbours, then combine with the self-message, via concatenation or summation:
Slide 20 puts it together: (1) message, \(\mathbf{m}_u^{(l)}=\mathrm{MSG}^{(l)}(\mathbf{h}_u^{(l-1)})\) for \(u\in N(v)\cup\{v\}\); (2) aggregation, \(\mathbf{h}_v^{(l)}=\mathrm{AGG}^{(l)}(\{\mathbf{m}_u^{(l)},u\in N(v)\},\mathbf{m}_v^{(l)})\); plus a non-linearity (activation) \(\sigma(\cdot)\), such as ReLU or sigmoid, that adds expressiveness. It can be applied in the message step or in the aggregation step.
Slide 21 lists activation functions, each applied to the \(i\)-th dimension of the embedding \(\mathbf{x}\) separately:
- ReLU: \(\mathrm{ReLU}(\mathbf{x}_i)=\max(\mathbf{x}_i,0)\). The most commonly used. Plot: flat at 0 for negative inputs, the line \(y=x\) for positive.
- Sigmoid: \(\sigma(\mathbf{x}_i)=1/(1+e^{-\mathbf{x}_i})\). Use it only when you want to restrict the range of the embeddings (its output lies in \((0,1)\)).
- Parametric ReLU: \(\mathrm{PReLU}(\mathbf{x}_i)=\max(\mathbf{x}_i,0)+a_i\min(\mathbf{x}_i,0)\), where \(a_i\) is a trainable slope for negative inputs (plot: \(y=x\) on the right, \(y=ax\) on the left). Empirically it performs better than ReLU.
Why concatenation and not just summation? \(\mathrm{CONCAT}(\mathbf{a},\mathbf{b})\) keeps "what my neighbours say" and "what I am" in separate coordinates, so the next linear layer can weigh them differently. Summation \(\mathbf{a}+\mathbf{b}\) mixes them into one vector — cheaper, but less flexible.
Classic layer 1: GCN as message + aggregation slides 22-23 ↗
Slide 22 recalls the Graph Convolutional Network layer (Kipf and Welling, ICLR 2017):
\[ \mathbf{h}_v^{(l)}=\sigma\Big(\mathbf{W}^{(l)}\sum_{u\in N(v)}\frac{\mathbf{h}_u^{(l-1)}}{|N(v)|}\Big). \]How do we write it as message + aggregation? Move \(\mathbf{W}^{(l)}\) inside the sum (it is linear, so this changes nothing):
\[ \mathbf{h}_v^{(l)}=\sigma\Big(\sum_{u\in N(v)}\underbrace{\mathbf{W}^{(l)}\frac{\mathbf{h}_u^{(l-1)}}{|N(v)|}}_{\text{message}}\Big),\qquad \text{aggregation} = \sigma(\text{Sum}). \]Slide 23 spells out the two parts:
- Message: each neighbour sends \(\mathbf{m}_u^{(l)}=\frac{1}{|N(v)|}\mathbf{W}^{(l)}\mathbf{h}_u^{(l-1)}\), i.e. its transformed embedding normalised by the node degree. (The GCN paper uses a slightly different normalisation.)
- Aggregation: sum the messages from the neighbours, then apply the activation: \(\mathbf{h}_v^{(l)}=\sigma\big(\mathrm{Sum}(\{\mathbf{m}_u^{(l)},u\in N(v)\})\big)\).
Where did the self term \(\mathbf{B}\mathbf{h}_v\) of Lecture 3 go? The slide answers: in GCN the input graph is assumed to have self-edges, which are included in the summation. So \(v\in N(v)\), and the node's own vector enters as one of the "neighbour" messages, with the same weight matrix \(\mathbf{W}^{(l)}\).
For reference, the original paper's normalisation is symmetric: the message from \(u\) to \(v\) is scaled by \(1/\sqrt{\tilde d_u\tilde d_v}\), where \(\tilde d\) counts the self-loop. Edges between two hubs get down-weighted.
Classic layer 2: GraphSAGE and its aggregators slides 24-26 ↗
Slide 24 introduces GraphSAGE (Hamilton et al., "Inductive Representation Learning on Large Graphs", NeurIPS 2017):
\[ \mathbf{h}_v^{(l)}=\sigma\Big(\mathbf{W}^{(l)}\cdot\mathrm{CONCAT}\big(\mathbf{h}_v^{(l-1)},\ \mathrm{AGG}(\{\mathbf{h}_u^{(l-1)},\forall u\in N(v)\})\big)\Big). \]It is a two-stage aggregation:
- Stage 1 — aggregate from the neighbours: \(\mathbf{h}_{N(v)}^{(l)}\leftarrow\mathrm{AGG}(\{\mathbf{h}_u^{(l-1)},\forall u\in N(v)\})\).
- Stage 2 — further aggregate over the node itself: \(\mathbf{h}_v^{(l)}\leftarrow\sigma\big(\mathbf{W}^{(l)}\cdot\mathrm{CONCAT}(\mathbf{h}_v^{(l-1)},\mathbf{h}_{N(v)}^{(l)})\big)\).
In message + aggregation language, the message is computed inside AGG\((\cdot)\). Slide 25 lists three choices of AGG and marks, in each formula, which part is the message and which part is the aggregation:
- Mean — a weighted average of neighbours: \(\mathrm{AGG}=\sum_{u\in N(v)}\frac{\mathbf{h}_u^{(l-1)}}{|N(v)|}\). Message = \(\mathbf{h}_u/|N(v)|\); aggregation = the sum.
- Pool — transform each neighbour vector, then apply a symmetric vector function such as Mean or Max: \(\mathrm{AGG}=\mathrm{Mean}(\{\mathrm{MLP}(\mathbf{h}_u^{(l-1)}),\forall u\in N(v)\})\). Message = the MLP; aggregation = the mean (or max).
- LSTM — apply an LSTM to a reshuffled list of neighbours: \(\mathrm{AGG}=\mathrm{LSTM}([\mathbf{h}_u^{(l-1)},\forall u\in\pi(N(v))])\), where \(\pi\) is a random permutation. Here the LSTM is the whole aggregation.
Slide 26: \(\ell_2\) normalisation, optional, applied to \(\mathbf{h}_v^{(l)}\) at every layer:
\[ \mathbf{h}_v^{(l)}\leftarrow\frac{\mathbf{h}_v^{(l)}}{\lVert\mathbf{h}_v^{(l)}\rVert_2}\quad\forall v\in V,\qquad \lVert\mathbf{u}\rVert_2=\sqrt{\textstyle\sum_i u_i^2}. \]Without it, embedding vectors can have very different scales (\(\ell_2\)-norms). After it, all vectors have the same norm (they lie on the unit sphere). In some cases, but not always, this improves performance.
Check yourself: an LSTM reads its input in order, so it is not permutation invariant. Why does a random shuffle \(\pi\) help? show answer
Training on many random orders pushes the LSTM to ignore the order, so it becomes approximately invariant — but there is no guarantee.
Classic layer 3: why attention? Not all neighbours are equal slides 27-30 ↗
Slide 27 writes the Graph Attention Network (GAT) layer:
\[ \mathbf{h}_v^{(l)}=\sigma\Big(\sum_{u\in N(v)}\alpha_{vu}\,\mathbf{W}^{(l)}\mathbf{h}_u^{(l-1)}\Big), \]where \(\alpha_{vu}\) are attention weights. Slide 28 writes the same thing in message form, \(\mathbf{h}_v^{(l)}=\sigma(\sum_{u\in N(v)}\alpha_{vu}\mathbf{m}_u^{(l)})\).
Compare with GCN and GraphSAGE (slides 27–28). There, \(\alpha_{vu}=\frac{1}{|N(v)|}\) is the weighting factor (importance) of \(u\)'s message to \(v\). Two consequences:
- \(\alpha_{vu}\) is defined explicitly, from a structural property of the graph (the node degree);
- so all neighbours \(u\in N(v)\) are equally important to node \(v\).
Slide 29 argues that this is wrong in general: not all of a node's neighbours are equally important. Attention is inspired by cognitive attention. The weight \(\alpha_{vu}\) should focus on the important parts of the input and fade out the rest. The idea: the network should devote more computing power to the small but important part of the data. Which part is important depends on the context, and it is learned through training.
Slide 30 (citing Veličković et al., ICLR 2018, and Vaswani et al., NeurIPS 2017) poses the question: can we do better than simple neighbourhood aggregation — can the weighting factors \(\alpha_{vu}\) be learned? Goal: specify an arbitrary importance for each neighbour of each node. Idea: compute each node's embedding \(\mathbf{h}_v^{(l)}\) with an attention strategy: nodes attend over their neighbourhoods' messages, which implicitly gives different weights to different nodes in a neighbourhood.
A social-network example: to predict a user's political leaning, a few close friends may tell you more than hundreds of brand accounts the user follows. Mean aggregation gives the brands most of the weight, simply because there are more of them.
The attention mechanism step by step, multi-head attention and its benefits slides 31-36 ↗
Let \(\alpha_{vu}\) be a by-product of an attention mechanism \(a\).
Step 1 — attention coefficients (slides 31–32). The function \(a\) computes a raw score \(e_{vu}\) for each pair of nodes, based on their messages:
\[ e_{vu}=a\big(\mathbf{W}^{(l)}\mathbf{h}_u^{(l-1)},\ \mathbf{W}^{(l)}\mathbf{h}_v^{(l-1)}\big)\quad(\text{equivalently } e_{vu}=a(\mathbf{m}_u^{(l)},\mathbf{m}_v^{(l)})). \]\(e_{vu}\) indicates the importance of \(u\)'s message to node \(v\). The figure shows node A and its neighbour B with the edge labelled \(e_{AB}=a(\mathbf{W}^{(l)}\mathbf{h}_A^{(l-1)},\mathbf{W}^{(l)}\mathbf{h}_B^{(l-1)})\).
Step 2 — normalise with softmax (slide 33), so that the weights over each neighbourhood sum to 1:
\[ \alpha_{vu}=\frac{\exp(e_{vu})}{\sum_{k\in N(v)}\exp(e_{vk})},\qquad \sum_{u\in N(v)}\alpha_{vu}=1. \]Step 3 — weighted sum: \(\mathbf{h}_v^{(l)}=\sigma\big(\sum_{u\in N(v)}\alpha_{vu}\mathbf{W}^{(l)}\mathbf{h}_u^{(l-1)}\big)\). For node A with neighbours B, C, D (figure):
\[ \mathbf{h}_A^{(l)}=\sigma\big(\alpha_{AB}\mathbf{W}^{(l)}\mathbf{h}_B^{(l-1)}+\alpha_{AC}\mathbf{W}^{(l)}\mathbf{h}_C^{(l-1)}+\alpha_{AD}\mathbf{W}^{(l)}\mathbf{h}_D^{(l-1)}\big). \]What is \(a\)? (slide 34) The approach is agnostic to the choice. A simple option is a single-layer neural network with trainable weights: concatenate the two transformed vectors and apply a linear layer,
\[ e_{AB}=\mathrm{Linear}\Big(\mathrm{Concat}\big(\mathbf{W}^{(l)}\mathbf{h}_A^{(l-1)},\ \mathbf{W}^{(l)}\mathbf{h}_B^{(l-1)}\big)\Big). \]The parameters of \(a\) are trained jointly with the weight matrices \(\mathbf{W}^{(l)}\), end to end.
Multi-head attention (slide 35) stabilises the learning of attention. Create several attention scores, each replica with its own parameters: \(\mathbf{h}_v^{(l)}[1],\mathbf{h}_v^{(l)}[2],\mathbf{h}_v^{(l)}[3]\), each computed with its own weights \(\alpha_{vu}^{1},\alpha_{vu}^{2},\alpha_{vu}^{3}\). Then aggregate the outputs, by concatenation or summation: \(\mathbf{h}_v^{(l)}=\mathrm{AGG}(\mathbf{h}_v^{(l)}[1],\mathbf{h}_v^{(l)}[2],\mathbf{h}_v^{(l)}[3])\).
Benefits (slide 36):
- Key benefit: implicitly specifies different importance values \(\alpha_{vu}\) for different neighbours.
- Computationally efficient: attention coefficients can be computed in parallel across all edges; aggregation can be parallelised across all nodes.
- Storage efficient: sparse matrix operations need at most \(O(V+E)\) stored entries; the number of parameters is fixed, independent of graph size.
- Localised: attends only over local network neighbourhoods.
- Inductive: a shared, edge-wise mechanism that does not depend on the global graph structure.
Check yourself: raw scores \(e_{AB}=2, e_{AC}=e_{AD}=0\). Then \(\alpha_{AB}=e^2/(e^2+2)\approx0.79\), and C, D get about 0.11 each. Why does softmax over neighbours only (not over all nodes) matter for the cost?
GNN layers in practice: modern modules and batch normalisation slides 38-40 ↗
Slide 38 (again from the Design Space paper): the classic layers are a great starting point, but we can often get better performance with a general GNN layer design that includes modern deep-learning modules proven useful in many domains. The figure shows "a suggested GNN layer" as a vertical pipeline: Linear → BatchNorm → Dropout → Activation → Attention → Aggregation. The first five boxes form the transformation (the message); the last is the aggregation.
Slide 39 lists what each module does:
- Batch normalisation — stabilises neural network training.
- Dropout — prevents overfitting.
- Attention / gating — controls the importance of a message.
- More — any other useful deep-learning module.
Slide 40 explains batch normalisation (Ioffe and Szegedy, ICML 2015). Goal: stabilise training. Idea: given a batch of inputs (node embeddings), re-centre them to zero mean and rescale them to unit variance. Input: \(\mathbf{X}\in\mathbb{R}^{N\times D}\) (\(N\) node embeddings of dimension \(D\)). Trainable parameters: \(\boldsymbol{\gamma},\boldsymbol{\beta}\in\mathbb{R}^{D}\). Output: \(\mathbf{Y}\in\mathbb{R}^{N\times D}\), the normalised embeddings.
Step 1 — mean and variance of each dimension \(j\) over the \(N\) embeddings:
\[ \boldsymbol{\mu}_j=\frac1N\sum_{i=1}^{N}\mathbf{X}_{i,j},\qquad \boldsymbol{\sigma}_j^2=\frac1N\sum_{i=1}^{N}\big(\mathbf{X}_{i,j}-\boldsymbol{\mu}_j\big)^2. \]Step 2 — normalise, then rescale and shift with the learned parameters:
\[ \hat{\mathbf{X}}_{i,j}=\frac{\mathbf{X}_{i,j}-\boldsymbol{\mu}_j}{\sqrt{\boldsymbol{\sigma}_j^2+\epsilon}},\qquad \mathbf{Y}_{i,j}=\boldsymbol{\gamma}_j\hat{\mathbf{X}}_{i,j}+\boldsymbol{\beta}_j . \]The small \(\epsilon\) avoids division by zero. Why learn \(\boldsymbol{\gamma},\boldsymbol{\beta}\)? Forcing every dimension to mean 0 and variance 1 may remove useful information; the learned scale and shift let the network undo the normalisation where that helps.
Dropout, and where it goes in a GNN slides 41-43 ↗
Slide 41 explains dropout (Srivastava et al., JMLR 2014). Goal: regularise a neural network to prevent overfitting. Idea:
- During training: with some probability \(p\), randomly set neurons to zero (turn them off). The figure shows a fully connected network and, after dropout, the same network with some neurons crossed out ("removed neurons") together with their connections.
- During testing: use all neurons for the computation.
Intuition: since any neuron may disappear, the network cannot rely on one fragile combination of features; it must spread the information. This acts like training many thinned networks and averaging them.
Slide 42: in a GNN, dropout is applied to the linear layer in the message function. For the simple message \(\mathbf{m}_u^{(l)}=\mathbf{W}^{(l)}\mathbf{h}_u^{(l-1)}\), the figure visualises \(\mathbf{W}^{(l)}\) as the connections between input units \(\mathbf{h}_u^{(l-1)}\) and output units \(\mathbf{m}_u^{(l)}\), and dropout removes some of those units during training.
Slide 43 summarises: modern deep-learning modules can be included in a GNN layer for better performance (the figure repeats the Linear → BatchNorm → Dropout → Activation → Attention → Aggregation stack). Designing novel GNN layers is still an active research frontier. Suggested resource: GraphGym, where you can explore diverse GNN designs or try out your own ideas.
Implementation detail you will meet in PyTorch: frameworks use "inverted dropout", scaling the kept units by \(1/(1-p)\) during training, so nothing needs to change at test time. Remember to call model.eval() before evaluation, or dropout stays on.
Stacking layers and the over-smoothing problem slides 45-50 ↗
Slide 45 turns to part 3, layer connectivity: how to connect GNN layers into a GNN — stack them sequentially, or add skip connections. Slide 46 gives the standard way: stack GNN layers one after another. Input: the raw node feature \(\mathbf{x}_v\), so \(\mathbf{h}_v^{(0)}=\mathbf{x}_v\). Output: the node embeddings \(\mathbf{h}_v^{(L)}\) after \(L\) GNN layers. The figure: \(\mathbf{h}^{(0)}\to\) GNN layer \(\to\mathbf{h}^{(1)}\to\) GNN layer \(\to\mathbf{h}^{(2)}\to\) GNN layer \(\to\mathbf{h}^{(3)}\).
Slide 47 names the problem with stacking many layers: over-smoothing — all node embeddings converge to the same value. This is bad because we use embeddings precisely to differentiate nodes. Why does it happen?
Slide 48 defines the receptive field: the set of nodes that determine the embedding of a node of interest. In a \(K\)-layer GNN, each node's receptive field is its \(K\)-hop neighbourhood. The figure shows one node in a random graph and its receptive field (in red) for 1, 2 and 3 layers; by 3 layers most of the graph is red.
Slide 49 looks at the overlap of the receptive fields of two nodes (yellow), with shared neighbours in red. The shared neighbours grow quickly with the number of hops:
- 1-hop overlap: only 1 node;
- 2-hop overlap: about 20 nodes;
- 3-hop overlap: almost all the nodes.
Slide 50 explains over-smoothing through this lens. The embedding of a node is determined by its receptive field. If two nodes have highly overlapping receptive fields, their embeddings are highly similar. So: stack many GNN layers → nodes have highly overlapping receptive fields → node embeddings are highly similar → over-smoothing. Next question: how to overcome it?
Check yourself: in a social network with a small diameter (say 5–6), roughly how many layers does it take before every node's receptive field is the whole graph?
Lesson 1: be careful with depth; make shallow GNNs expressive slides 51-53 ↗
Slide 51 draws the first lesson from over-smoothing: be cautious when adding GNN layers. Unlike neural networks in other domains (for example CNNs for image classification), adding more GNN layers does not always help.
- Step 1: analyse the receptive field needed to solve your problem, for example by computing the diameter of the graph.
- Step 2: set the number of GNN layers \(L\) to be a bit more than the receptive field you want. Do not make \(L\) unnecessarily large.
Then the question: how do we make a GNN expressive if the number of GNN layers is small? Two solutions.
Solution 1 (slide 52): increase the expressive power within each GNN layer. In the examples so far, each transformation or aggregation contained just one linear layer. We can make the aggregation and the transformation themselves deep neural networks — "if needed, each box could include a 3-layer MLP". The receptive field stays the same (it depends only on the number of message-passing rounds), but each round can compute a more complex function.
Solution 2 (slide 53): add layers that do not pass messages. A GNN need not consist only of GNN layers. We can add MLP layers, applied to each node separately, before and after the GNN layers:
- Pre-processing layers — important when encoding the node features is necessary, e.g. when nodes represent images or text.
- Post-processing layers — important when reasoning or transformation over node embeddings is needed, e.g. graph classification or knowledge graphs.
The slide's verdict: in practice, adding these layers works great.
Why do MLP layers not cause over-smoothing? They act on each node independently: they never mix information between nodes, so they cannot make different nodes more alike.
Lesson 2: skip connections and jumping knowledge slides 54-57 ↗
Slide 54: what if the problem still requires many GNN layers? Lesson 2: add skip connections. The observation from over-smoothing: embeddings in earlier GNN layers can sometimes differentiate nodes better. Solution: increase the impact of earlier layers on the final embeddings by adding shortcuts. The figure (from He et al., ResNets, CVPR 2015) shows the input \(\mathbf{x}\) duplicated into two branches; one goes through the layers to give \(F(\mathbf{x})\), the other skips them (identity), and the two are summed. Before the shortcut the block outputs \(F(\mathbf{x})\); after, \(F(\mathbf{x})+\mathbf{x}\).
Slide 55: why do skip connections work? Intuition: they create a mixture of models. With \(N\) skip connections there are \(2^N\) possible paths, since at each block a signal can either go through the module or skip it. Each path has up to \(N\) modules. So we automatically get a mixture of shallow and deep GNNs. The figure (Veit et al., 2016) unrolls a 3-block residual network into all \(2\cdot2\cdot2=2^3=8\) paths, from the empty path to the path through \(f_1,f_2,f_3\).
Slide 56 applies this to the GCN. The standard GCN layer is our \(F(\mathbf{x})\):
\[ \mathbf{h}_v^{(l)}=\sigma\Big(\sum_{u\in N(v)}\mathbf{W}^{(l)}\frac{\mathbf{h}_u^{(l-1)}}{|N(v)|}\Big), \]and the GCN layer with a skip connection adds \(\mathbf{x}=\mathbf{h}_v^{(l-1)}\) inside the activation:
\[ \mathbf{h}_v^{(l)}=\sigma\Big(\underbrace{\sum_{u\in N(v)}\mathbf{W}^{(l)}\frac{\mathbf{h}_u^{(l-1)}}{|N(v)|}}_{F(\mathbf{x})}+\underbrace{\mathbf{h}_v^{(l-1)}}_{\mathbf{x}}\Big). \]The side figure shows where skips can go in a full model: around the GNN layers, between the pre-process and post-process MLP layers.
Slide 57 (Xu et al., "Jumping Knowledge Networks", ICML 2018) gives another option: skip directly to the last layer. The final layer aggregates from all the node embeddings of the previous layers: \(\mathbf{h}_v^{(0)}\) (input), \(\mathbf{h}_v^{(1)},\mathbf{h}_v^{(2)},\mathbf{h}_v^{(3)}\) all feed into a "layer aggregation" box (concat, pooling or LSTM), which outputs \(\mathbf{h}_v^{(\text{final})}\). Each node can then use the receptive-field size that suits it.
Check yourself: in the skip-GCN formula, the self term \(\mathbf{h}_v^{(l-1)}\) has no weight matrix. What constraint does that put on the layer dimensions? show answer
Input and output dimensions must be equal, or you need a projection on the skip path.
Not shown (no new content): slides 1,2,3,14,37,44 — title page, announcements (HW 1, recitation, review session, feedback survey) and section-divider title pages.
Review: what to keep from this session
Carried forward. Lecture 5 fills in graph augmentation and the learning objective; Lecture 6 shows which aggregator is the most expressive; Lecture 8 reads a transformer as attention-weighted message passing on the complete graph.
Quick self-check
Where does GAT put its parameters that GCN does not have?
In the attention mechanism: a learned function of the pair (node, neighbour) that produces the aggregation weights, instead of fixed degree-based weights.
Explain over-smoothing in one sentence.
With many layers the receptive fields of different nodes become almost the same set of nodes, so their embeddings converge to the same vector.
Why add MLP layers before and after message passing?
Pre-processing encodes rich input features (text, images); post-processing lets the model reason over the embedding, e.g. for graph classification, without adding more hops.
Key idea
A GNN layer is "message, then order-free aggregation (including yourself)"; architectures differ in how neighbours are weighted, and depth must be matched to the receptive field you need because too many layers smooth everything into one vector.
GCN is the special case \(\alpha_{vu}=1/|N(v)|\) (fixed); GAT learns \(e_{vu}=a(\mathbf{W}\mathbf{h}_u,\mathbf{W}\mathbf{h}_v)\).
Worked example: GAT weights vs GCN weights
Node A has neighbours B, C, D. Suppose the attention network outputs raw scores \(e_{AB}=1,\ e_{AC}=0,\ e_{AD}=-1\).
- Exponentiate: \(e^1=2.718,\ e^0=1,\ e^{-1}=0.368\); sum = 4.086.
- Attention weights: \(\alpha_{AB}=0.665,\ \alpha_{AC}=0.245,\ \alpha_{AD}=0.090\).
- GCN would use \(1/3\) each. GAT gives B twice the GCN weight and almost ignores D.
- Output: \(\mathbf{h}_A=\sigma(0.665\,\mathbf{W}\mathbf{h}_B+0.245\,\mathbf{W}\mathbf{h}_C+0.090\,\mathbf{W}\mathbf{h}_D)\).
- If all scores were equal, softmax gives \(1/3\) each — GAT contains mean aggregation as a special case.
Strictly speaking: because GAT's weights sum to 1, it is still a weighted mean, so it cannot count neighbours (a node with 2 identical neighbours looks the same as one with 5). Lecture 6 shows why this limits expressive power and why sum aggregation (GIN) fixes it.
In code (PyG)
from torch_geometric.nn import SAGEConv, GATConv
sage = SAGEConv(in_channels=64, out_channels=64, aggr='mean') # or 'max', 'lstm'
gat = GATConv(64, 16, heads=4, concat=True, dropout=0.6) # 4 heads → 64 dims
h = F.elu(gat(x, edge_index))
# residual + norm, the "modern layer":
h = x + F.dropout(F.relu(torch.nn.BatchNorm1d(64)(sage(x, edge_index))), 0.2)
Proof workshop: Over-smoothing is a spectral gap
One problem in olympiad style. Give it fifteen minutes on paper before you open the first hint; the hints are graded, so open them one at a time.
Problem. Let \(G\) be connected, \(\tilde A=A+I\), \(\tilde D\) its degree matrix and \(\hat A=\tilde D^{-1/2}\tilde A\tilde D^{-1/2}\). Prove that \(\hat A^kX\to uu^\top X\) as \(k\to\infty\), where \(u=\tilde D^{1/2}\mathbf 1/\lVert\tilde D^{1/2}\mathbf 1\rVert\). Conclude that after many linear GCN steps every feature column is proportional to \(\sqrt{\tilde d_v}\), and that the rate is \(|\lambda_2|^k\) for the second-largest eigenvalue magnitude.
Hint 1
Hint 2
Solution
Why it matters. Depth multiplies by \(\hat A\); everything orthogonal to \(u\) decays geometrically, and what survives is degree, not content. Graphs with a small spectral gap (\(|\lambda_2|\) near 1: long chains, weakly linked communities) smooth slowly; expanders smooth fast. Residual connections add an \(I\) that stops the decay, which is the notebook's skip-connection result.
Sharper lens: depth, measured
Not on the slides. Three or four points where the lecture rounds something off: the exact statement, a second way to see it, and where it stops being true. Each is short and has a pointer for going further.
Over-smoothing and over-squashing are one matrix power
For a linear mean-aggregation GNN with self-loops, \(H^{(r)}=P^rX\) with \(P=\tilde D^{-1}\tilde A\). Row \(v\) of \(P^r\) answers two questions at once. What can reach \(v\)? \(\partial\mathbf h_v^{(r)}/\partial\mathbf x_u=(P^r)_{vu}\); for non-linear MPNNs this is an upper bound up to a factor \(c^r\) (Topping et al., ICLR 2022). What still distinguishes \(v\)? Every row converges to the same stationary distribution \(\pi_u\propto\tilde d_u\), at rate \(|\lambda_2|^r\).
Read the figure in two steps. Inside a community the walk mixes within a few layers, so \(v\) and \(w\) soon receive the same mixture of inputs: that is over-smoothing, and it is local and fast. Across the bridge the walk mixes at the rate of the whole graph's \(\lambda_2\), which Cheeger's inequality ties to the tightest bottleneck \(h\): \(\tfrac{h^2}{2}\le1-\lambda_2\le2h\). That is over-squashing, and it is global and slow. When the far side finally arrives, it arrives at a node that can no longer be told apart from its neighbours, so it can inform a community-level prediction but not a node-level one.
Rewiring or a virtual node widens the bottleneck and brings the far side much sooner (from 23 layers to 7 or 5 in the figure); neither moves the merging of \(v\) and \(w\) by more than a layer. Getting distant information and keeping node identity needs something that is not diffusion: content-dependent attention to chosen distant nodes (Lecture 8), or skip connections that keep the \(r=0\) row available (Lesson 2 above).
GAT's attention is static: every node ranks its neighbours the same way
GAT scores an edge by \(e_{vu}=\mathrm{LeakyReLU}\big(\mathbf a_1^\top W\mathbf h_v+\mathbf a_2^\top W\mathbf h_u\big)\). For a fixed query node \(v\) the first term is a constant and LeakyReLU is increasing, so the order of the scores is the order of \(\mathbf a_2^\top W\mathbf h_u\), whoever is asking. A node cannot attend most to the neighbour that is most similar to itself; all nodes share one global ranking of "interesting neighbours". Brody, Alon and Yahav (ICLR 2022) proved this and fixed it by moving the non-linearity: \(e_{vu}=\mathbf a^\top\mathrm{LeakyReLU}\big(W[\mathbf h_v\,\Vert\,\mathbf h_u]\big)\), which can approximate any score function. In PyG, GATv2Conv is a drop-in replacement; use it by default.
Over-smoothing is a theorem about operators, not about trained networks
The proof workshop handles the linear case. With weights and ReLU, Oono and Suzuki (ICLR 2020) show the distance to the "degree-only" subspace shrinks by a factor \(s\,\lambda\) per layer, where \(\lambda\) is the second eigenvalue magnitude and \(s\) the largest singular value of the weight matrix. If \(s\lambda\lt1\) the collapse is exponential; if training makes \(s\gt1/\lambda\), the bound says nothing. Trained weights can and do push back, which is why the audits in the Frontier section found smoothness only weakly related to accuracy. Two things the bound does not excuse: attention does not escape it (GAT also loses expressive power exponentially, Wu et al., NeurIPS 2023), and neither does normalisation by itself. Measure the Dirichlet energy \(\sum_{(u,v)\in E}\lVert\mathbf h_u-\mathbf h_v\rVert^2\) of your trained model layer by layer before blaming or crediting depth.
Lab: hands-on and practical tips
Try it live. In the Graph Explorer: apply the GCN operator 64 times to Cora and watch the energy fall, then compare GCN, GraphSAGE and an MLP as homophily changes, and train a GAT and compare its attention with GCN’s fixed weights. Each lesson has predict-then-check questions.
notebook · L04 general perspective implements GCN, GraphSAGE and GAT with PyG's MessagePassing, computes attention by hand, measures receptive fields and runs the depth experiment shown above.
GATConv(64, 64, heads=4) concatenates four heads: the output is 256-wide, and the next layer that expects 64 inputs crashes, or a Linear(-1, …) silently absorbs it and quadruples your parameters. Use concat=False on the last layer.Readings & lookup guide
lecture notes CS224W course notes (Leni Aniva, Autumn 2024 — in your course folder)
- Ch. 4 — A general perspective on GNNs (pp. 22–27)
If you only read one: GraphSAGE — it introduces inductiveness, neighbour sampling, and the aggregator zoo, all of which recur until the end of the course.
read first Hamilton, Ying, Leskovec — Inductive Representation Learning on Large Graphs (GraphSAGE, NeurIPS 2017)
- Read: §3.1 + Algorithm 1 (forward pass), §3.2 (unsupervised loss with random-walk positives & negative sampling — Lecture 2 meets Lecture 3), §3.3 (aggregators).
- Key figure: Fig. 1 (sample neighbourhood → aggregate → predict). Remember the fixed-size neighbour sampling: \(S_1=25, S_2=10\).
- Skim: §4 experiments (Reddit, citation, PPI); §5 theory on learning clustering coefficients.
core Veličković et al. — Graph Attention Networks (ICLR 2018)
- Read: §2.1 (Eqs. 1–4: the whole layer fits in four lines), Fig. 1 (attention + multi-head).
- Note: LeakyReLU inside \(a\); concat heads in hidden layers, average in the last.
- Follow-up: Brody et al. 2022, "How attentive are GATs?" (GATv2) — GAT's attention is "static": the ranking of neighbours doesn't depend on the query node. A beautiful small result.
practical You, Ying, Leskovec — Design Space of Graph Neural Networks (NeurIPS 2020)
- Read: §3 (the 12-dimensional design space, Fig. 1), §5 key findings (BatchNorm yes, dropout rarely, PReLU, sum aggregation, skip-sum, pre/post MLP layers).
- Use as a lookup table when choosing hyperparameters for your project. Also listed for Lecture 19.
Homework 1 — overview (released with this lecture)
Homework 1 due Thu 10/15, 11:59 pm PT
| Q | Topic | Pts | Lecture | What to think about |
|---|---|---|---|---|
| 1.1 | Depth vs expressiveness | 4 | L3, L6 | At which layer do the two red nodes' computation trees first differ? (Sum aggregation, all features = 1.) |
| 1.2 | Random-walk matrix & stationary distribution | 4 | L2 | \(M\) column-stochastic; solve \(r=Mr\), normalise. |
| 1.3–1.4 | Mean aggregation ⇔ random walk; with skip | 8 | L3, L4 | \(D^{-1}A\) (careful with row vs column convention); skip ⇒ \(\tfrac12(I+D^{-1}A)\). |
| 1.5 | Over-smoothing proof | 5 | L4 §4 | Irreducible + aperiodic Markov chain ⇒ unique stationary distribution ⇒ convergence. |
| 1.6 | Learn BFS with a GNN | 7 | L4 §1 | Message = neighbour's flag; AGG = max; update = max(self, agg). |
| 2.1–2.4 | Embeddings as matrix factorisation (+bonus eigen-decomposition) | 9+3 | L2 §5 | Decoder \(z_i^\top z_j\); bilinear \(z_i^\top Wz_j\); \(W\) diagonal + orthonormal Z; multi-hop adjacency. |
| 2.5–2.8 | node2vec vs struc2vec on two 10-cliques | 12 | L2 §6 | Walks can't jump between disconnected cliques; struc2vec walks on a similarity clique. |
| 3.1 | Isomorphism check | 2 | L6 | Find a bijection, or an invariant (degree sequence, triangles) that differs. |
| 3.2 | Sum vs mean vs max aggregation | 3 | L6 | Neighbour multisets {1} vs {1,1}: mean & max equal, sum differs. |
| 3.3 | GNNs are at most as powerful as WL | 6 | L6 | Induction on iterations: same WL colour ⇒ same GNN embedding. |
Strategy: do Q2 now (Lecture 2 material), Q1 after this lecture, Q3 after Lecture 6 (Thu 10/8). Budget 10–20 hours; the course's late-period rule gives +4 days once.
Colab 1 due Thu 10/8
Covers Lectures 1–4. See the Lecture 2 page.
Self-check
In GraphSAGE, how is the node's own embedding combined with the neighbourhood summary?
- Added with weight 1/|N(v)|
- Ignored
- Concatenated, then multiplied by W
- Through attention
\(\sigma(W[h_v \| \text{AGG}(\{h_u\})])\).
Which aggregator is not permutation invariant by construction?
- LSTM
- Mean
- Max-pool over MLP outputs
- Attention-weighted sum
An LSTM depends on input order; GraphSAGE feeds a random permutation to approximate invariance.
Over-smoothing is best explained by …
- vanishing gradients
- too few parameters
- dropout
- receptive fields of different nodes overlapping almost completely
Same inputs ⇒ similar outputs; with depth the K-hop neighbourhoods of all nodes converge to the whole graph.
Your task needs information from up to 3 hops, but 3 GCN layers underfit. Best first move?
- Use 12 layers
- Make each layer's MSG/AGG an MLP and add pre/post-processing MLP layers
- Remove the self-message
- Switch to LSTM aggregation
Increase expressiveness without growing the receptive field (Lesson 1).
N residual skip connections give how many paths?
- N
- N²
- 2^N
- N!
Each module can be included or skipped → mixture of shallow and deep models.
Flashcards (click to flip)
History & the bigger picture
- 2014–2015 — attention in machine translation (Bahdanau et al.), then "Attention is all you need" (2017). GAT (2018) imports it to graphs only months later.
- 2015 — ResNets (He et al.) solved depth for CNNs. The same trick only partly works for GNNs because the obstacle is different: not optimisation but information mixing.
- 2017 — MPNN (Gilmer et al.) unified a dozen chemistry models as "message + update + readout" — the ancestor of this lecture's framework.
- 2020 — the "design space" turn. Instead of proposing yet another layer, You et al. evaluated 315,000 designs and asked which choices actually matter. A healthy reaction to a field flooded with marginal novelty.
By 2020 the GNN literature had hundreds of architectures, many claiming small gains on Cora/Citeseer. Shchur et al. (2018) and Dwivedi et al. (2020) showed that with fair tuning many differences vanish. This is Lakatos in miniature: a research programme can be "progressive" (new predictions) or "degenerating" (patching to save benchmarks). Design-space studies are one way a field corrects itself.
Classic SNA bridge
| In this lecture | Classic SNA counterpart | What carried over, what changed |
|---|---|---|
| Skip connection to layer 0 | Friedkin–Johnsen (1990): agents anchored to an innate opinion \(s\) | Literally the same equation: \(x_{t+1}=(1-\alpha)Wx_t+\alpha x_0\). FJ proved disagreement never vanishes when \(\alpha>0\); that is why skips stop over-smoothing (see the stubborn-agents figure above). |
| Attention: not all neighbours are equal | Tie strength (Granovetter); weighted sociomatrices; valued ties in ERGMs | SNA weighted ties by observed frequency; GAT learns the weights from the task. Attention weights are therefore model-relative, not a measure of the relationship (Jain & Wallace 2019). |
| Over-smoothing with depth | DeGroot consensus; "small world" diameter (Milgram 1967; Watts–Strogatz 1998) | In a small world, \(K\) hops reach most of the graph for small \(K\), so averaging converges fast. The social fact (six degrees) is the reason deep GCNs fail on social graphs. |
| GraphSAGE: concatenate self with pooled neighbours | Contextual effects models: own attributes plus neighbourhood averages as separate regressors | Keeping the self term separate is what lets the model compare a node to its context, the same move as Doreian's contextual-effects regressions. |
| Design space, 315K designs | Methodological pluralism in SNA: dozens of centrality measures, each with a theory of "importance" | Both fields have a zoo. GraphGym's answer (controlled random search over a design space, Lecture 19) is a method SNA could borrow for its own measure zoo. |
Take the Friedkin–Johnsen equilibrium \(z^*=(I+L)^{-1}s\) and expand it as a power series in the normalised adjacency. Each term is one GCN-style propagation step with a decaying weight. That series is APPNP's personalised-PageRank propagation. You now have an opinion-dynamics interpretation of a modern GNN, and a GNN implementation of a 1990 sociology model; the Frontiers deck derives this identity step by step.
Go deeper in the SNA course. The twelve-unit course on social network analysis in this repository gives the classic side of this lecture in full, with labs and real-data analyses: Unit 3 · Centrality & link analysis (over-smoothing: deep linear GNNs converge to the top eigenvector); Unit 4 · Random graphs & small worlds (depth, receptive fields and over-squashing); Unit 8 · Epidemics & opinion dynamics (over-smoothing is consensus; skip connections play the stubborn agent); Unit 10 · Causality, interference & graph ML (depth, over-smoothing and over-squashing).
Connecting to your research
Running project. Section L02–L04 · community of notebooks/project/retweet_thread.py applies this lecture to one synthetic X world with coordinated rings, the same graph across the whole course.
Research extension. experiments/rings-in-communities (hypotheses written before running): community structure vs coordination: when a ring is a cluster and when it is not.
- GAT attention as an interpretive tool: which followers does the model "listen to" when classifying an account? Attention weights are not explanations (Jain & Wallace 2019 debate), but they're a useful hypothesis generator for influence analysis.
- Depth and the small world: Twitter's effective diameter is ~4–5. A 3-layer GNN on the follow graph already touches a huge fraction of the network for a hub — over-smoothing arrives fast. Use neighbour sampling (GraphSAGE) and keep \(L\le 2\)–3.
- Over-smoothing ↔ opinion consensus: skip connections are like "stubborn agents" in Friedkin–Johnsen opinion dynamics (each person keeps weight on their initial opinion). The Friedkin–Johnsen equation is literally a GCN with a skip to layer 0.
From the experiments: results and datasets
Generated by scripts/sync_guides.py from the experiments' committed results and the dataset catalogue; rerun it (make sync-guides) after an experiment changes.
rings-in-communities
Question. Do coordinated rings look like tiny communities, or hide inside real ones? experiment folder ↗
Datasets for this session
From the repo's catalogue (gl.datasets; the full list with sources and licences is in data/README.md). Load one with gl.datasets.graph(name), temporal(name) or node_data(name).
| name | dataset | nodes | ground truth | good for |
|---|---|---|---|---|
cora | Cora citations | 2,708 | topic (7) | the default GNN benchmark |
Frontier 2025–26: what changed since the slides
Frontiers · four settings of one template · one inequality, two failure modes · the pathologies were over-claimed
Words & phrases
| Term | Simple meaning | Persian | In context |
|---|---|---|---|
| remedyn. | a way of fixing a problem | چاره، راه درمان | "The remedies are shallow-but-expressive layers…" |
| compressv. | to make something take less space; here: summarise many vectors into one | فشرده کردن | "A layer compresses a set of vectors into one vector" |
| workaroundn. | a practical trick that avoids a problem without truly solving it | راهحل موقت، راه دور زدن مشکل | "the shuffle is a training-time workaround" |
| over-smoothingn. | the tendency of node vectors to become alike as layers are stacked | هموارسازی بیش از حد | "deep GCNs suffer from over-smoothing" |
| attentionn. | learned weights that decide how much each neighbour's message counts | سازوکار توجه | "GAT replaces fixed weights by attention" |
| residual (skip) connectionn. | adding a layer's input to its output, so information can bypass the layer | اتصال باقیمانده (پرشی) | "skip connections keep each node's own signal" |
| spectral gapn. | the distance between the largest and the next eigenvalue; it sets how fast diffusion mixes | شکاف طیفی | "a large spectral gap means fast smoothing" |
Go deeper
- Next: Lecture 5 — graph augmentation (features, virtual nodes, neighbour sampling) and how to set up training/validation splits on graphs.
- Over-smoothing theory: Oono & Suzuki (2020), "GNNs exponentially lose expressive power for node classification" — the rigorous version of the receptive-field story.
- Open question: is over-smoothing really the main obstacle to deep GNNs, or is it over-squashing (too much information through bottleneck edges; Alon & Yahav 2021)? Lecture 8's graph transformers are partly an answer to the latter.