LLGA · Course notes

Graph Machine and Deep Learning for Generative AI

CSC_52072_EP · Year 1 · Period 2

Contents

Introduction and overview

Module Graph Machine and Deep Learning for Generative AI
Code CSC_52072_EP
Team and workload Heads (“responsables” on the 2026–2027 sheet): Johannes Lutzeyer and Michalis Vazirgiannis (École Polytechnique); head of the scheduled X3A session: Johannes Lutzeyer · teaching team listed on the sheet: Guillaume Lachaud, Ye Zhu · teaching volume not displayed on the 2026–2027 sheet (36 h per the LLGA curriculum wiki, see the session plan · 4.5 ECTS) · from graph theory foundations to GNNs, graph generation and GraphRAG — the module that gives the master’s program its name, and the foundation of the M2 module “Advanced Graph Neural Networks”.
Period Autumn semester · period 2 (from 04/01/2027 to 19/03/2027) · X3A session “Graph Machine and Deep Learning for Generative AI”; course taught in English
Assessment Quizzes and team projects (the course description); the LLGA section of the 2026–2027 sheet displays no assessment modality, resit rule or weighting
Status in the program MandatoryCore of the master

Audience: an engineer who has already trained an MLP / CNN and wants to keep structure (fraud, molecules, KGs) instead of flattening it away.

Empirical first: a fraud model whose impressive test score came only from edges leaking across the train/test split; message passing that oversmooths after 4 layers — then we name GNNs, spectra, GraphRAG.

From graph-theory foundations to GNNs, generation and GraphRAG. Core module of the master: concepts reappear in M2 (Advanced GNN, LLMs).

What you will be able to do

Official objectives and syllabus (2026-2027 catalog)

The official 2026–2027 sheet (X3A session of the same name, period X-3A-P2, from 04/01/2027 to 19/03/2027, taught in English) sets the objective of introducing students to graph networks and deep learning — their mathematical foundations, the design of architectures and their practical applications — a field it describes as especially important given the current volume of industrial and academic work.

The description announces machine- and deep-learning methods for graph-structured data, defined as an underlying graph with vector data observed on the nodes, the edges or both: fundamental descriptive statistics of graphs and probabilistic models that generate graphs, graph kernel methods, then a complete overview of deep learning on graphs, notably graph neural networks, closing with applications and a perspective on current challenges and future directions.

Assessment: quizzes and team projects (description; the LLGA section of the sheet displays no modality). Our proposal for the team project, started in session 9, is the Team project box of ch. 8; subjects, an exam and a rubric are in Projects and assessment. Prerequisites: not displayed. Teaching volume: not displayed. The sheet lists a nine-lecture programme (“changes may occur during the semester”), matched below.

Official programme (2026–2027 sheet) Course section
1. Introduction to Graph Machine Learning Chapters 1 (why graphs?) and 2 (learning tasks, invariance and equivariance, transductive vs inductive)
2. Graph Exploration and Traditional Graph Algorithms Chapter 0: isomorphism, connectivity, Laplacian, random walks, modularity and Louvain; “Exploring and describing a graph” (BFS Algorithm 0.8, DFS and Dijkstra)
Description: fundamental descriptive statistics of graphs Definition 0.9 (degree distribution, clustering, distances, centralities, assortativity), Example 0.10
3. Graph Kernels and Similarity Measures Chapter 2, “Similarity measures and graph kernels”: node similarities (Definition 2.2), graph kernels (Definition 2.3), random-walk kernel (Proposition 2.4), Weisfeiler-Lehman kernel (Algorithm 2.5, Example 2.6)
4. Introduction to Graph Generative AI Chapter 9 (graphons, ER and SBM — the probabilistic generative models of the description — graph VAEs, GraphRNN, DiGress, evaluation, conditional generation); chapter 10 (graphs × LLMs)
5. Graph Neural Networks Chapter 5 (message passing, GCN, GraphSAGE, GAT, R-GCN, over-smoothing), with chapters 3 (node embeddings), 6 (link prediction, graph auto-encoders) and 7 (GNNs at scale)
6. The Spectral Domain of Graphs and Its Implications on GNNs Chapter 4 (graph Fourier transform, spectral clustering, ChebNet, spectral–spatial equivalence); Derivation 5.2 (GCN from the spectral filter); Theorem 5.3 (over-smoothing as low-pass filtering)
7. Heterophily and Temporal Graphs Chapter 5, “Heterophily” (Definition 5.4, Proposition 5.5, architectures note) and “Temporal graphs” (Definition 5.6, Models 5.7, Example 5.8)
8. Geometric Graphs and Applications in Biomedicine Chapter 8, “Geometric graphs and applications in biomedicine” (Definition 8.2, EGNN Proposition 8.3, Example 8.4, applications note); molecular generation in ch. 9
9. Benchmarking, Challenges and Future Directions in Graph Machine Learning Chapter 7 (OGB note), chapter 8 (leakage-free protocol, “Benchmarking, challenges and future directions” note), chapter 10 (frontiers with LLMs); chapter 11 (the team’s research, self-study)

Every lecture of the official programme now has a section in these notes. Our extensions, beyond the official syllabus: chapter 10 (GraphRAG and the graph × LLM hybrid, an application of lectures 4 and 9) and chapter 11 (the research work of Lutzeyer and Vazirgiannis, self-study).

Where this course fits in the program

Mandatory module of period 2 of M1 (teaching volume not displayed on the 2026–2027 sheet; 36 h and 4.5 ECTS per the LLGA curriculum wiki), of which Johannes Lutzeyer and Michalis Vazirgiannis are the official heads: it is the heart of the master’s program, the one that structures the “graph” axis around which the advanced M2 modules are organized.

Official prerequisites: not displayed on the 2026–2027 sheet.

Course outline

Session plan

36 h in class = 12 sessions of 3 h. The SynapseS 2026–2027 sheet of this course displays no teaching volume (neither in-person hours nor a lecture/tutorial split), but the LLGA curriculum page of the programme wiki (msct.dix.polytechnique.fr/llga, last modified on 9 September 2026 by the programme director) states that “all subsequent M1 courses are 36h and will credit 4.5 ECTS”.

The sheet does publish a nine-lecture programme, and the plan follows its order with two changes, both made so that no session relies on a notion taught later: the spectral lecture (official 6) comes before the GNN lecture (official 5), because the GCN layer is derived from the spectral filter (Derivation 5.2); and the introduction to graph generative AI (official 4) is taught after GNNs, because the deep generative models of ch. 9 use GNN encoders and denoisers.

Level 1 = foundations (reviews, definitions, first worked examples), 2 = core methods, 3 = advanced material and recent research; the level never goes down from one session to the next.

Session Hours Level Content Practice
1 3 h 1 ch. 0 Refresher: isomorphism, paths, spectral theorem and counting by the trace, the Laplacian, random walks, modularity (0.1–0.7) Ex. 1, 7
2 3 h 1 ch. 0 Exploring and describing a graph: BFS, DFS, Dijkstra, descriptive statistics and centralities (0.8–0.10); ch. 1 Why graphs?; ch. 2 Learning tasks, invariance and equivariance lab sheet after Example 0.10: Karate Club with NetworkX (degrees, BFS distances, betweenness, PageRank, Louvain)
3 3 h 2 ch. 2 Similarity measures and graph kernels: node similarities, graphlet, shortest-path, random-walk and Weisfeiler-Lehman kernels (2.2–2.6) Ex. 12; lab sheet at the end of the kernels section: WL kernel + SVM on MUTAG
4 3 h 2 ch. 3 Node embeddings: skip-gram (recall), DeepWalk, node2vec, NetMF Ex. 2, 3
5 3 h 2 ch. 4 Graph Fourier transform, Fiedler vector, spectral clustering, ChebNet, spectral-spatial equivalence (4.1–4.6) Ex. 5
6 3 h 2 ch. 5 Message passing and its 1-WL bound, the GCN derivation, GraphSAGE, attention and GAT, relational graphs, over-smoothing (5.1–5.3) Ex. 4, 8, 9
7 3 h 2 ch. 5 Heterophily (5.4–5.5), temporal graphs and their evaluation protocol (5.6–5.8) Ex. 13
8 3 h 2 ch. 6 Link prediction, graph auto-encoders (ELBO recall), PinSage, knowledge graph completion; ch. 7 GNNs at scale: neighbor sampling, Cluster-GCN, GraphSAINT, OGB Ex. 6, 10
9 3 h 2 ch. 8 Applications and hands-on: use cases, a leakage-free protocol (8.1), the team project, geometric graphs and EGNN with its unit test (8.2–8.4), biomedicine, benchmarking and open challenges Ex. 14; lab: Example 8.1 (start the team project)
10 3 h 3 ch. 9.1–9.3 Graphons, Erdős-Rényi and SBM, graph VAEs Ex. 11 (a)
11 3 h 3 ch. 9.4–9.7 GraphRNN, discrete diffusion (DDPM recap, D3PM posterior and loss), evaluation (MMD, Fréchet distance), conditional generation Ex. 11 (b), 16
12 3 h 3 ch. 10 Graphs × LLMs: GraphRAG, pseudo-code prompting, GNN + LLM hybrids, GraphRAG worked (10.1–10.4) Ex. 15; final lab (mini-GraphRAG on 2WikiMultiHopQA)

Read ahead for the team project (week 1 = session 9): sections 10.1–10.2 by project week 2 and 9.4–9.7 by week 3, before they are taught in sessions 11–12.

Self-study, outside the 36 h (about 3 h in total): ch. 11 Research at DaSciM — Graph of Words, Path Neural Networks, GOAT, NGG (≈ 3 h, with Ex. 17).

How to study this module

independent note The “graph” half of the master: GraphRAG (ch. 10) is the junction with the LLM axis, extended in M2 by Advanced GNN and LLMs. Fraud, recommendation, chemistry, enterprise KGs — cases where discarding structure costs more than a bad hyperparameter.

0. Refresher: graph theory

Every later chapter manipulates the same few objects — the adjacency matrix, the degrees, the Laplacian, random walks — and uses their properties without stopping to prove them. This refresher states and proves those properties once, so that the walks of ch. 3 and the spectral arguments of ch. 4 rest on solid ground.

L3 prerequisites — the “graph” object (cf. Refresher CS)

  • Definitions: G = (V, E); directed/undirected, weighted; degree d_v, neighbors \mathcal{N}(v), adjacency matrix A, degree matrix D = \mathrm{diag}(d_v). Paths, connectivity, components, cycles, DAGs.
  • Euler and Königsberg (1736): crossing the 7 bridges is impossible because more than two vertices have odd degree — the first theorem of graph theory; the abstraction (nodes + edges) founded the discipline.
  • Linear algebra: (A^k)_{ij} counts the walks of length k from i to j (vertices may repeat); eigenvalues of A = spectrum of the graph; symmetric matrices diagonalizable in an orthonormal basis (algebra reminder).
  • Stochastic matrices: P = D^{-1}A = random walk (the only meaning of P on this page); stationary distribution; PageRank with teleport probability \alpha (typically 0.15), \pi^\top = (1 - \alpha)\, \pi^\top P + \alpha\, \mathbf{1}^\top / n \iff \pi = \frac{\alpha}{n}\, \big(I - (1 - \alpha) P^\top\big)^{-1} \mathbf{1}.

Definition 0.1 — Isomorphism, automorphism, subgraph Two graphs G = (V, E) and G' = (V', E') are isomorphic if there exists a bijection \pi : V \to V' such that (u, v) \in E \iff (\pi(u), \pi(v)) \in E'.

An automorphism is an isomorphism of G onto itself; their set forms a group \mathrm{Aut}(G). A subgraph of G is formed of S \subseteq V and a subset of E \cap (S \times S); the induced subgraph keeps all the internal edges.

Deciding isomorphism is a problem known neither NP-complete nor polynomial; the Weisfeiler-Lehman test (M2 module, ch. 2) is its fundamental heuristic — and the expressivity bound of GNNs.

Proposition 0.2 — Connectivity and shortest paths The relation “u \sim v if there exists a path from u to v” is an equivalence relation; its classes are the connected components. Between two vertices of the same component, every path of minimal length (shortest path) is a simple path (without repeated vertex).

Proof. Reflexivity (path of length 0), symmetry (undirected graph: reverse the path) and transitivity (concatenate) are immediate. If a path from u to v visits a vertex w twice, we delete the cycle between the two visits: the path strictly shortens. A path of minimal length therefore cannot contain a cycle, so every vertex appears there only once: it is simple, of length \leq n - 1. ∎

Theorem 0.3 (spectral theorem) and counting by the trace Every real symmetric matrix S \in \mathbb{R}^{n \times n} writes S = U \Lambda U^\top with U orthogonal and \Lambda real diagonal.

For the adjacency of a simple graph, three counting identities follow: \mathrm{tr}(A) = 0, \qquad \mathrm{tr}(A^2) = 2|E|, \qquad \mathrm{tr}(A^3) = 6\,|\{\text{triangles}\}|.

Proof. \mathrm{tr}(A^2) = \sum_i (A^2)_{ii} = \sum_i d_i, each edge contributing to two degrees.

(A^3)_{ii} counts the closed walks of length 3 through i: these are exactly the triangles containing i, each traversed in both directions from i. Each triangle \{i, j, k\} thus produces 2 closed walks for each of its 3 vertices, i.e. 6 countings.

Conversely a closed walk of length 3 i \to j \to k \to i visits three pairwise distinct, pairwise adjacent vertices. ∎

Immediate application in learning: counting triangles (motifs) by matrix products — the basic ingredient of the structural features of ch. 9 and of the expressivity of the M2 module (ch. 2).

Definition 0.4 — The Laplacian of a graph L = D - A, \qquad \text{or normalized: } L_{\mathrm{sym}} = I - D^{-1/2} A\, D^{-1/2}. For every vector x \in \mathbb{R}^n (n = |V|):

Key result — the Laplacian quadratic form x^\top L x = \sum_{(u,v) \in E} (x_u - x_v)^2 \ \geq\ 0

— L is positive semi-definite; its eigenvalues 0 = \lambda_1 \leq \lambda_2 \leq \dots \leq \lambda_n encode connectivity.

\lambda_2 (the algebraic connectivity, Fiedler 1973) measures the difficulty of cutting the graph, and the number of zero eigenvalues equals the number of connected components.

Proof. x^\top D x = \sum_v d_v x_v^2 and x^\top A x = 2 \sum_{(u,v) \in E} x_u x_v (symmetric matrix); hence x^\top L x = \sum_{(u,v) \in E} (x_u^2 + x_v^2 - 2 x_u x_v).

For the multiplicity of 0: reordering the vertices by components makes A (and L) block-diagonal; each block L_C has the indicator \mathbf{1}_C as kernel, since x^\top L_C x = 0 forces x constant on each connected component (the sum of squares cancels edge by edge, and connectivity propagates the constant — Prop. 0.2). ∎

Example 0.5 — The spectrum tells the story

  • Path of n vertices: \lambda_k = 2(1 - \cos\frac{k\pi}{n}), k = 0, \dots, n-1;
  • complete graph: 0 then n (multiplicity n-1);
  • cycle of n vertices: \lambda_k = 2(1 - \cos\frac{2k\pi}{n}), k = 0, \dots, n-1.

A “two-community” graph has a small \lambda_2; the Fiedler eigenvector separates the communities — this is the heart of spectral clustering, developed in ch. 4 (direct bridge with the PCA of the Machine Learning module).

Proposition 0.6 — Random walks: stationarity and ergodicity Let G be connected undirected, P = D^{-1}A, m = |E|. The distribution \pi_v = d_v / (2m) is stationary: \pi^\top P = \pi^\top.

If moreover G is not bipartite, the chain is irreducible and aperiodic, hence ergodic: P^t(x, \cdot) \xrightarrow[t \to \infty]{} \pi \qquad \text{whatever the starting point } x.

Proof. Detailed balance: \pi_u P_{uv} = \frac{d_u}{2m} \cdot \frac{\mathbb{1}[(u,v) \in E]}{d_u} = \frac{\mathbb{1}[(u,v) \in E]}{2m}, a quantity symmetric in u, v; summing over u, (\pi^\top P)_v = \pi_v.

Irreducibility: connectivity makes every vertex reachable.

Periodicity: on a bipartite graph, every closed walk has even length (P^t(x, x) = 0 for odd t), so the chain has period 2.

Conversely, a connected non-bipartite graph contains a cycle of odd length \ell. From any vertex x the walk can come back in 2 steps (along an edge and back) or in an odd number of steps (walk k steps to the cycle, go around it, walk back: 2k + \ell steps), and \gcd(2, 2k + \ell) = 1 — period 1.

The convergence theorem for Markov chains concludes: see Refresher Statistics, 2.7, or Reinforcement Learning, 0.1. ∎

Practical consequence: the walks of DeepWalk (ch. 3) “mix” the distribution toward \pi \propto degrees — hence the bias of embeddings toward hubs, partly corrected by node2vec and by NetMF.

Definition 0.7 — Modularity (Newman & Girvan, 2004) For a partition \mathcal{C} = \{C_1, \dots, C_k\} of the vertices: Q(\mathcal{C}) = \frac{1}{2m} \sum_{i,j} \Big[ A_{ij} - \frac{d_i\, d_j}{2m} \Big]\, \delta(c_i, c_j), where c_i is the community of i and \delta the indicator.

Q compares the observed density of intra-community edges to the expected one under the configuration model (edges redistributed while preserving degrees, term d_i d_j / 2m).

Maximization sketch: maximizing Q exactly is NP-hard; Louvain does it greedily. Each node i in turn moves to the neighboring community C that most increases the modularity — the gain of moving an isolated node i into C is \Delta Q = \frac{k_{i,C}}{m} - \frac{\Sigma_C\, d_i}{2m^2}, with k_{i,C} the number of edges from i to C and \Sigma_C the sum of the degrees in C. Then each community is contracted into a single node and the procedure restarts; hence hierarchies of communities used as-is by GraphRAG (ch. 10).

Known limit — resolution (Fortunato & Barthélemy, 2007). Merging two communities C_1, C_2 with total degrees d_{C_1}, d_{C_2}, joined by e_{12} edges, changes Q by \Delta Q = \frac{e_{12}}{m} - \frac{d_{C_1}\, d_{C_2}}{2m^2}. With a single edge between them and d_{C_1} \approx d_{C_2} \approx 2\ell (\ell internal edges each), the merge wins as soon as \ell < \sqrt{m/2}: on a large graph, Q cannot “see” well-separated communities of fewer than about \sqrt{m/2} edges (as in Social Media, ch. 7). The nested SBM (ch. 9) is a statistical alternative that largely lifts this limit.

Exploring and describing a graph

The second lecture of the official programme covers graph exploration and traditional graph algorithms, and the course description opens with the fundamental descriptive statistics of graphs. Before any learning, these are the first things computed on a new graph: they reveal its scale, its hubs and its local density, and they remain strong hand-crafted features for classical models.

Algorithm 0.8 — Breadth-first search and unweighted shortest paths From a source s:

  1. set \mathrm{dist}(s) = 0, put s in a FIFO queue;
  2. repeatedly pop a vertex v and, for every neighbor u not yet discovered, set \mathrm{dist}(u) = \mathrm{dist}(v) + 1, \mathrm{parent}(u) = v, and push u.

Cost \mathcal{O}(|V| + |E|): each vertex is pushed once, each edge examined twice.

Claim: \mathrm{dist}(u) is the length of a shortest path from s to u, and the parent pointers form a shortest-path tree.

Proof. The queue always holds vertices whose \mathrm{dist} values are non-decreasing and differ by at most 1 (true at the start; popping v and pushing vertices with \mathrm{dist}(v) + 1 preserves it). Hence vertices are popped in non-decreasing order of \mathrm{dist}.

Suppose some vertex u gets \mathrm{dist}(u) > \delta(u), the true distance, and take such a u with smallest \delta(u).

Let w be its predecessor on a shortest path, so \delta(w) = \delta(u) - 1 and \mathrm{dist}(w) = \delta(w) by minimality.

When w was popped, u was either undiscovered — then it received \mathrm{dist}(w) + 1 = \delta(u), a contradiction.

Or it was already discovered from a vertex popped before w, whose \mathrm{dist} is \leq \mathrm{dist}(w), giving \mathrm{dist}(u) \leq \delta(u), again a contradiction.

Conversely \mathrm{dist}(u) \geq \delta(u) always, since the parent pointers trace an actual path of that length. ∎

Replacing the queue by a stack gives depth-first search, used for connected components, cycle detection and topological order (DAGs); with non-negative edge weights, Dijkstra’s algorithm replaces the queue by a priority queue on tentative distances, in \mathcal{O}((|V| + |E|)\log |V|). All three are recalled in the Refresher in Computer Science; here they are the primitives of the statistics below and of the neighborhood sampling of ch. 7.

Definition 0.9 — Descriptive statistics and centralities With n = |V|, m = |E|:

  • degrees: mean degree 2m/n, density 2m / (n(n-1)), and the degree distribution p_k — often heavy-tailed in real networks (p_k \propto k^{-\gamma} over a range of k), which produces hubs;
  • clustering: the local coefficient C_v = \frac{|\{\text{edges among the neighbors of } v\}|}{\binom{d_v}{2}} = \frac{(A^3)_{vv}}{d_v(d_v - 1)} (Theorem 0.3), and the global transitivity 3 \times \#\text{triangles} / \#\text{connected triples};
  • distances: eccentricity of v (largest BFS distance), diameter (largest eccentricity), average shortest-path length; a small world combines short paths with high clustering (Watts & Strogatz, 1998);
  • centralities:
    • degree;
    • closeness c(v) = (n-1) / \sum_{u} \mathrm{dist}(v, u);
    • betweenness b(v) = \sum_{s \neq v \neq t} \sigma_{st}(v)/\sigma_{st}, where \sigma_{st} counts the shortest s–t paths and \sigma_{st}(v) those through v (Brandes’ algorithm computes all of them in \mathcal{O}(nm));
    • eigenvector centrality Ax = \mu_1 x, with \mu_1 \geq \mu_2 \geq \dots the eigenvalues of A (written \mu to keep \lambda for the Laplacian);
    • PageRank, the stationary law of the walk of Proposition 0.6 with teleportation: with probability \alpha (typically 0.15) the walker jumps to a uniform node, \pi^\top = (1 - \alpha)\, \pi^\top P + \alpha\,\mathbf{1}^\top / n;
  • assortativity: the correlation between the degrees at the two ends of an edge (social networks: positive; technological and biological networks: often negative).

These numbers are the classical features of node and graph classification, and the statistics compared by the MMD evaluation of generated graphs (9.6).

Example 0.10 — The statistics of a small graph, computed Take the “kite” with vertices a, b, c, d, e and edges ab, ac, bc, cd, de (a triangle abc with a tail c - d - e).

Here n = m = 5, density 5/10 = 0.5, degrees (2, 2, 3, 2, 1).

  • BFS from a: layers \{a\}, \{b, c\}, \{d\}, \{e\}, so the eccentricity of a is 3, which is also the diameter.

  • Clustering: C_a = C_b = 1; C_c = 1/3 (among its neighbors a, b, d only ab is an edge); C_d = 0; C_e = 0 by convention.

    One triangle and \sum_v \binom{d_v}{2} = 1 + 1 + 3 + 1 + 0 = 6 connected triples give a transitivity 3/6 = 0.5.

  • Closeness: the distances from c sum to 1 + 1 + 1 + 2 = 5, so c(c) = 4/5 = 0.8.

    From d: 6, so c(d) \approx 0.67; from a: 7, so c(a) \approx 0.57.

  • Betweenness (unordered pairs): every shortest path from \{a, b\} to \{d, e\} passes through c, so b(c) = 4.

    The paths from \{a, b, c\} to e pass through d, so b(d) = 3; b(a) = b(b) = b(e) = 0.

Vertex c has only one more edge than the others, but it controls all traffic between the two halves — what degree alone does not show.

Lab sheet — session 2: the Karate Club with NetworkX Zachary’s club (34 members, 78 friendships, split into two factions) is small enough to check each statistic of Definition 0.9 against a drawing.

import networkx as nx
G = nx.karate_club_graph()                       # 34 members, 78 friendships
deg = dict(G.degree())
dist = nx.single_source_shortest_path_length(G, 0)       # BFS from member 0, the instructor
bc = nx.betweenness_centrality(G)                         # Brandes, normalized
pr = nx.pagerank(G, alpha=0.85, weight=None)              # NetworkX alpha = 1 - our teleport α
comms = nx.community.louvain_communities(G, weight=None, seed=0)
print(sorted(deg, key=deg.get)[-2:], max(dist.values()), nx.diameter(G))
print(sorted(bc, key=bc.get)[-2:], sorted(pr, key=pr.get)[-2:])
print(len(comms), nx.community.modularity(G, comms, weight=None))
print(nx.transitivity(G), nx.average_clustering(G), nx.degree_assortativity_coefficient(G))

Expected output, to compare with yours:

  • The two leaders, 0 and 33, have the largest degrees (16 and 17). The eccentricity of 0 is 3 and the diameter is 5.
  • They also have the largest betweenness (0.44 for 0, 0.30 for 33) and the largest PageRank (0.10 for 33).
  • Louvain finds 4 communities with Q \approx 0.42.
  • Transitivity is 0.26, average clustering 0.57, and degree assortativity -0.48: hubs connect to small-degree members.

Questions for the session:

  1. Which members have a betweenness rank much higher than their degree rank?
  2. How far is the Louvain partition from the club attribute? Use the NMI.
  3. Rerun PageRank with teleport \alpha = 0.5 (alpha=0.5 in NetworkX) and explain why the scores flatten.

1. Why graphs?

Concrete scene: fraud detection on a transaction graph (nodes = accounts, edges = transfers). A tabular classifier on account features hits 0.71 AUC; the same model enriched with a 2-hop neighborhood reaches 0.89 — until a random split leaks train↔︎test edges and inflates the score. This chapter states why structure matters, before writing a GNN.

What breaks Treating nodes as i.i.d. (signal lost); splitting without blocking edges (leakage); stacking GCN layers until every embedding looks the same (over-smoothing). All three sabotage a GraphRAG as much as a toy Karate Club.

Real-world data is relational: the structure carries information that i.i.d. methods ignore.

Social networks (friendships), molecules (bonds), transaction networks (fraud!), enterprise knowledge graphs (customers, products, processes), computer networks, citation clusters, legal ontologies… All are naturally graphs, often heterogeneous (typed nodes/edges: “buys”, “owns”, “works with”) and dynamic (timestamped edges: transactions second by second).

Also typically: few labels (a few dozen annotated nodes out of millions) — the semi-supervised regime of ch. 5 — and distributions biased by sampling (the observed edges are not a uniform sample of the interactions).

independent note LLMs excel at text but struggle with: structured relations, factual fidelity (hallucinations), and non-textual data. Graphs fill exactly these gaps:

  • GraphRAG: connecting the LLM to structured proprietary data — today the most effective approach for making an LLM reliable in the enterprise (ch. 10);
  • GNN + LLM: generative AI on structured data (generating molecules, plans, recommendations);
  • Industrial applications: pharma/biotech (molecules = graphs), finance (transaction networks, systemic risk), recommendation, supply chain, multi-agent systems (agent workflows are DAGs — RL module).

Common thread of the master’s program Three places of the graph in generative AI: inside the model (the attention of transformers is a complete dynamic graph — Deep Learning module), for the model (GraphRAG, structural encoding — ch. 10), between models (agent orchestration = DAG programming). This module lays the foundations of all three; the M2 module “Advanced GNN” extends each one.

2. Learning tasks on graphs

Before choosing a model, one must say what is predicted: a label per node, a score per pair of nodes, or a property of the whole graph. This chapter fixes that taxonomy, then the two constraints that every later model must respect: the symmetry under renumbering of the nodes, and the distinction between predicting on the training graph and on new graphs.

Level Task Examples
node node classification / regression labeling an article (topic), detecting a fraudulent user
link link prediction recommendation, knowledge graph completion (ch. 6)
graph graph classification / regression property of a molecule (toxic?), performance prediction
graph graph generation molecule design, networks, synthetic graphs (ch. 9)
structure community clustering segmentation, anomaly detection (modularity, ch. 0; SBM, ch. 9)

Definition 2.1 — Permutation invariance and equivariance A graph has neither a fixed size nor a canonical order of the nodes: the model must be permutation-invariant (graph output) or permutation-equivariant (per-node output): for every permutation matrix \Pi, f(\Pi X, \Pi A \Pi^\top) = f(X, A) \quad \text{(invariant)}, \qquad f(\Pi X, \Pi A \Pi^\top) = \Pi f(X, A) \quad \text{(equivariant)}.

CNNs (grid), RNNs (sequence) violate these constraints — hence dedicated architectures (ch. 5) and the whole expressivity theory of the M2 module (ch. 2).

Transductive vs inductive — a distinction that structures the whole module

  • Transductive: training and testing on the same graph (embeddings ch. 3); impossible to predict for a node arriving after training;
  • Inductive: the model (its weights) reapplies to new graphs (GraphSAGE, GNNs ch. 5) — indispensable in production;
  • Structural semi-supervised: on Cora (2,708 nodes), 140 labels suffice — the structure relays the information (homophily hypothesis: neighbors share the label; when it fails, one needs “virtual” edges or heterophilous models — ch. 5, “Heterophily”).

Similarity measures and graph kernels

The third lecture of the official programme is devoted to graph kernels and similarity measures — the way graphs were learned on before neural networks, and still the strongest baselines on many small benchmarks. Two questions are asked: how similar are two nodes of one graph (the basis of link prediction, ch. 6), and how similar are two whole graphs of different sizes, without any correspondence between their nodes (the basis of graph classification with kernel machines).

Definition 2.2 — Node similarity measures For nodes u, v with neighborhoods \mathcal{N}(u), \mathcal{N}(v):

  • common neighbors |\mathcal{N}(u) \cap \mathcal{N}(v)| = (A^2)_{uv};
  • Jaccard \frac{|\mathcal{N}(u) \cap \mathcal{N}(v)|}{|\mathcal{N}(u) \cup \mathcal{N}(v)|};
  • Adamic-Adar (a shared neighbor counts more if it is not a hub) \sum_{w \in \mathcal{N}(u) \cap \mathcal{N}(v)} \frac{1}{\log d_w};
  • Katz S = \sum_{k \geq 1} \beta^k A^k = (I - \beta A)^{-1} - I, which counts all paths with a weight decaying with length and converges for \beta < 1/\mu_1(A);
  • personalized PageRank from u, evaluated at v.

The first three are local (two hops), the last two global.

In the kite of Example 0.10, a and d share the neighbor c (\mathcal{N}(a) = \{b, c\}, \mathcal{N}(d) = \{c, e\}).

Common neighbors 1, Jaccard 1/3, Adamic-Adar 1/\log 3 \approx 0.91.

These heuristics are the baselines any learned link predictor (ch. 6) must beat (Liben-Nowell & Kleinberg, 2007).

Definition 2.3 — Graph kernel A graph kernel is a function k(G, G') = \langle \varphi(G), \varphi(G') \rangle_{\mathcal{H}} for some feature map \varphi into a Hilbert space — equivalently, a symmetric function whose Gram matrix on any finite set of graphs is positive semi-definite — and which is invariant under isomorphism.

Any kernel method of the Machine Learning module (SVM, kernel ridge regression, kernel PCA) then applies to a dataset of graphs of different sizes.

A complete kernel (\varphi injective on isomorphism classes) would decide graph isomorphism, so computing one is at least as hard as that problem (Gärtner et al., 2003); practical kernels therefore compare substructures (R-convolution, Haussler, 1999): k(G, G') = \sum_{s \in S(G)} \sum_{s' \in S(G')} \kappa(s, s').

Main families: graphlet kernels (histograms of the induced subgraphs on 3–5 vertices), shortest-path kernels (compare the multisets of shortest-path lengths, with end labels), random-walk kernels and Weisfeiler-Lehman kernels, detailed below.

Proposition 2.4 — The random-walk kernel through the product graph The direct product graph G_\times of G and G' has the vertex pairs (v, v') as nodes.

It has an edge between (u, u') and (v, v') iff (u, v) \in E and (u', v') \in E'; for unlabeled graphs its adjacency is the Kronecker product A_\times = A \otimes A'.

The geometric random-walk kernel counts pairs of walks of equal length, with weight \lambda^k for length k: k_{\mathrm{RW}}(G, G') = \sum_{k \geq 0} \lambda^k\, \mathbf{1}^\top A_\times^k\, \mathbf{1} = \mathbf{1}^\top (I - \lambda A_\times)^{-1}\, \mathbf{1}, \qquad \lambda < 1/\mu_1(A_\times). It is a valid kernel; for unlabeled graphs it reduces to \sum_k \lambda^k\, w_k(G)\, w_k(G') with w_k(G) = \mathbf{1}^\top A^k \mathbf{1} the number of walks of length k.

Proof. By the mixed-product rule of Kronecker products, (A \otimes A')^k = A^k \otimes A'^k, so (A_\times^k)_{(u,u'),(v,v')} = (A^k)_{uv}\,(A'^k)_{u'v'}: a walk of length k in G_\times is exactly a pair of walks of length k, one in each graph.

Summing over all start and end pairs, \mathbf{1}^\top A_\times^k \mathbf{1} = (\mathbf{1}^\top A^k \mathbf{1})(\mathbf{1}^\top A'^k \mathbf{1}) = w_k(G)\, w_k(G'). Hence k_{\mathrm{RW}} = \sum_k \lambda^k w_k(G) w_k(G') = \langle \varphi(G), \varphi(G') \rangle, \qquad \varphi(G) = (\lambda^{k/2} w_k(G))_{k \geq 0} — an inner product, so positive semi-definite.

The geometric series converges when \lambda\, \mu_1(A_\times) < 1 (\mu_1 the largest adjacency eigenvalue), and then equals the matrix inverse. ∎

Cost: a naive inversion of the nn' \times nn' system takes \mathcal{O}(n^6); Sylvester-equation and conjugate-gradient methods bring it to about \mathcal{O}(n^3) (Vishwanathan et al., 2010). Weakness: walks may totter back and forth along one edge, which inflates similarity between unrelated graphs.

Algorithm 2.5 — Weisfeiler-Lehman subtree kernel (Shervashidze et al., 2011) Start from labels \ell_0(v) (node labels, or a constant). At iteration h = 1, \dots, H, give each node the new label \ell_h(v) = \mathrm{relabel}\Big(\ell_{h-1}(v),\ \{\!\{\ell_{h-1}(u) : u \in \mathcal{N}(v)\}\!\}\Big), where \{\!\{\cdot\}\!\} is a multiset and \mathrm{relabel} is an injective dictionary shared by all the graphs of the dataset.

Let \varphi_h(G) count how many nodes carry each label at iteration h; the kernel is k_{\mathrm{WL}}(G, G') = \sum_{h=0}^{H} \langle \varphi_h(G), \varphi_h(G') \rangle .

The label \ell_h(v) encodes the rooted subtree of depth h obtained by unfolding the neighborhood of v; computing all features costs \mathcal{O}(H\,m) per graph — linear, which makes the WL kernel usable on thousands of graphs.

It is the 1-WL isomorphism test (Definition 0.1) turned into features; message passing (ch. 5) is the same iteration with a learned, continuous relabeling, which is why GNNs are at most as discriminating as 1-WL (M2, ch. 2).

Example 2.6 — Two WL iterations, computed Compare the path G_1 = 1{-}2{-}3{-}4 and the star G_2 (center 0, leaves 1, 2, 3): both have 4 nodes and 3 edges. Start with a constant label \circ.

  1. h = 0: both histograms are \{\circ : 4\}, contribution 16.

  2. h = 1: a node with one neighbor gets A = (\circ, \{\circ\}), two neighbors B = (\circ, \{\circ, \circ\}), three C.

    G_1: \{A : 2, B : 2\}; G_2: \{A : 3, C : 1\}; contribution 2 \cdot 3 = 6.

  3. h = 2: in G_1 the ends become D = (A, \{B\}) and the inner nodes E = (B, \{A, B\}).

    In G_2 the center becomes F = (C, \{A, A, A\}) and the leaves G = (A, \{C\}); no label is shared, contribution 0.

So k_{\mathrm{WL}}(G_1, G_2) = 22, while k(G_1, G_1) = 16 + 8 + 8 = 32, \qquad k(G_2, G_2) = 16 + 10 + 10 = 36; the normalized kernel is 22/\sqrt{32 \cdot 36} \approx 0.65 .

Limit: on regular graphs all labels stay equal — two disjoint triangles and the 6-cycle get identical WL features, although they are not isomorphic.

Kernels or GNNs? A kernel fixes the features (\varphi) and learns only the classifier; a GNN learns the features too, and uses continuous node attributes naturally.

On small graph-classification datasets (MUTAG, PROTEINS, NCI1), the WL kernel with an SVM remains a strong baseline (survey by Kriege, Johansson & Morris, 2020), and under a fair protocol even structure-agnostic baselines are hard for GNNs to beat (Errica et al., 2020); kernels lose ground on large datasets, continuous features and node-level tasks.

The node similarities above also reappear inside learned models: the shared-neighbor counts of A^2 are the structural features added to GNN link predictors (for example SEAL, Zhang & Chen, 2018).

Lab sheet — session 3: Weisfeiler-Lehman kernel + SVM on MUTAG MUTAG (Debnath et al., 1991) holds 188 nitroaromatic compounds, 125 of them mutagenic, with about 18 atoms each. Download it from the TUDataset collection (Morris et al., 2020), which stores each dataset as plain text files.

import collections, numpy as np, networkx as nx
from sklearn.svm import SVC
from sklearn.model_selection import GridSearchCV, StratifiedKFold, cross_val_score

def load_tu(path, name="MUTAG"):                 # the TUDataset text format
    f = lambda s: np.loadtxt(f"{path}/{name}_{s}.txt", delimiter=",", dtype=int)
    gid, lab, y = f("graph_indicator"), f("node_labels"), f("graph_labels")
    Gs = [nx.Graph() for _ in y]
    for v, (g, l) in enumerate(zip(gid, lab)): Gs[g - 1].add_node(v, label=str(l))
    for u, v in f("A") - 1: Gs[gid[u] - 1].add_edge(u, v)
    return Gs, y

def wl_features(Gs, H):                          # Algorithm 2.5, one dictionary for all graphs
    labels = [{v: G.nodes[v]["label"] for v in G} for G in Gs]
    vocab, rows = {}, [collections.Counter() for _ in Gs]
    for h in range(H + 1):
        for i, G in enumerate(Gs):
            for v in G: rows[i][vocab.setdefault((h, labels[i][v]), len(vocab))] += 1
        labels = [{v: lab[v] + "|" + ",".join(sorted(lab[u] for u in G[v])) for v in G}
                  for G, lab in zip(Gs, labels)]  # the string is the injective relabel
    X = np.zeros((len(Gs), len(vocab)))
    for i, r in enumerate(rows): X[i, list(r)] = list(r.values())
    return X

Gs, y = load_tu("MUTAG")
for H in (0, 3):
    X = wl_features(Gs, H)
    K = X @ X.T
    K /= np.sqrt(np.outer(np.diag(K), np.diag(K)))     # normalized kernel
    svm = GridSearchCV(SVC(kernel="precomputed"), {"C": [0.01, 0.1, 1, 10, 100]}, cv=5)
    outer = StratifiedKFold(10, shuffle=True, random_state=0)
    print(H, cross_val_score(svm, K, y, cv=outer).mean())   # nested CV: C chosen inside

Expected: about 0.73 for H = 0, where only the atom-type histograms are compared, and about 0.87 for H = 3. Over five outer splits (random_state 0 to 4), H = 3 gives 0.86 \pm 0.01.

The penalty C is chosen inside each training fold. Choosing it on the test folds is the leakage of Example 8.1 in another form.

Questions for the session:

  1. Plot the accuracy for H = 0, \dots, 5. Where does it stop improving, and why can more iterations hurt?
  2. Replace the WL features by shortest-path-length histograms, the shortest-path kernel, and compare.
  3. Check the blind spot of Example 2.6 with wl_features on two disjoint triangles and the 6-cycle (Exercise 12).

3. Node embeddings

A classical model (logistic regression, k-means) needs one vector per node, but a graph only gives relations. Node embeddings solve this by learning a vector z_v \in \mathbb{R}^d for each node from the structure alone, so that nodes close in the graph get close vectors.

Objective Learn z_v \in \mathbb{R}^d such that the similarity of the embeddings reflects proximity in the graph: \mathrm{sim}(z_u, z_v) \approx P(u \text{ neighbor of } v) — an implicit factorization of the adjacency matrix (or of a matrix of derived proximities), in contrast with the GNNs of ch. 5 which condition the embedding on the features X.

DeepWalk (Perozzi et al., 2014) and node2vec (Grover & Leskovec, 2016)

  1. generate random walks from each node (length \ell, r walks per node); node2vec biases the walk with (p, q) — developed below;
  2. apply word2vec skip-gram to the walks: the “sentences” are sequences of nodes; the window T defines the (center, context) pairs, nodes at most T steps apart in a walk, and k negatives are drawn per pair (Recall 3.1);
  3. afterwards: any vector method (k-means, classification…).

The random walk defines proximity: two often co-visited nodes get close embeddings — the NetMF theory (Qiu et al., 2018) shows retrospectively that DeepWalk factorizes a deterministic matrix of walks (Theorem 3.3).

Recall 3.1 — Skip-gram with negative sampling (derived in NLP, Theorem 4.1)

Two tables of vectors: v_w when w is the center, u_c when c is a context.

For one (center, context) pair (w, c) and k negatives n_1, \dots, n_k drawn from p_n \propto \mathrm{freq}^{3/4}, with \sigma the logistic sigmoid: \mathcal{L} = -\log \sigma(u_c^\top v_w) - \sum_{i=1}^{k} \log \sigma(-u_{n_i}^\top v_w), \nabla_{v_w} \mathcal{L} = \big(\sigma(u_c^\top v_w) - 1\big)\, u_c + \sum_{i=1}^{k} \sigma(u_{n_i}^\top v_w)\, u_{n_i}.

The context attracts the center, and each negative repels it in proportion to its current score. The cost per pair is \mathcal{O}(kd), independent of the number of nodes, which made DeepWalk scalable.

On a graph, words become nodes and sentences become walks; the embedding of node v is its center vector, written z_v below. Two hyperparameters must not be confused: the window T and the number k of negatives. Both appear in NetMF (Theorem 3.3).

Derivation 3.2 — node2vec: the biases p and q via transition probabilities At step i, the walk comes from t, is at v; it moves to the candidate x \in \mathcal{N}(v) with probability \pi_{vx} = \frac{\alpha_{pq}(t, x)\, w_{vx}}{Z}, \qquad \alpha_{pq}(t, x) = \begin{cases} 1/p & \text{if } d_{tx} = 0 \\ 1 & \text{if } d_{tx} = 1 \\ 1/q & \text{if } d_{tx} = 2 \end{cases} (d_{tx} = distance in the graph; Z normalizes over \mathcal{N}(v).)

In a simple graph, d_{tx} \leq 2 for every x \in \mathcal{N}(v) \cup \{t\} if t and v are adjacent.

Three regimes:

  • p \lt 1: return toward t favored — the walk stays in the close neighborhood (BFS): two nodes with analogous structural roles (hubs, bridges) get close embeddings — structural equivalence;
  • q \lt 1: vertices at d_{tx} = 2 are favored — the walk moves away (DFS): two nodes of the same community/cluster are close — homophily;
  • p = q = 1: uniform random walk — DeepWalk is a special case of node2vec.

The qualitative proof: with p \to 0, the probability of returning to t dominates and the walk samples the 2-hop neighborhood of t almost uniformly; with q \to 0, the chain avoids t and behaves like a large-scale exploratory walk — find these behaviors again in exercise 2.

Theorem 3.3 — NetMF: DeepWalk as matrix factorization (Qiu et al., 2018) Let T be the window size and k the number of negatives per pair (the paper writes b). As the length of the walks grows, DeepWalk converges to the (truncated, element-wise) factorization of the matrix: M = \log\Big( \frac{\mathrm{vol}(G)}{k\, T} \Big( \sum_{r=1}^{T} P^r \Big) D^{-1} \Big), \qquad \mathrm{vol}(G) = \sum_v d_v = 2m, that is, we look for Z Z'^\top \approx M, with Z the center and Z' the context table. The term P^r weights the pairs that a walk visits r \leq T steps apart, inside the window.

Consequences:

(i) a theoretical bridge — DeepWalk, LINE, PTE and node2vec are all factorizations of variants of M (hence the name “NetMF”, Network Embedding as Matrix Factorization);

(ii) a deterministic algorithm — factorizing M directly (truncated SVD) matches or beats DeepWalk without drawing a single walk;

(iii) a diagnostic — the target matrix is built on P = D^{-1}A: the embeddings encode the walks, not the features, and remain transductive (a new node requires recomputing everything — direct motivation for the inductive GNNs of ch. 5).

The “word2vec on the graph” intuition — and its converse This is the historical NLP ↔︎ graphs bridge: a corpus of walks ≈ a corpus of sentences. DaSciM pushed the reverse idea — Graph of Words (ch. 11): representing a document by a graph of co-occurring terms and classifying it with graph tools. Both directions converge today in LLMs on graphs (ch. 10). To go beyond walks (with repetitions) toward paths (simple), see the Path Neural Networks (ch. 11; M2, ch. 2 and 9).

Example 3.4 — Karate Club: complete code Zachary’s graph (34 nodes, 78 edges, 2 factions at the club split) is the “MNIST of graphs”.

import numpy as np, networkx as nx
from gensim.models import Word2Vec
from sklearn.cluster import KMeans
from sklearn.metrics import normalized_mutual_info_score

G = nx.karate_club_graph()
y = np.array([0 if G.nodes[v]["club"] == "Mr. Hi" else 1 for v in G])

def biased_walk(G, v, p, q, length):
    walk, prev = [v], None
    for _ in range(length):
        cand = list(G.neighbors(walk[-1]))
        probs = []
        for x in cand:
            d = 0 if x == prev else nx.shortest_path_length(G, prev, x) if prev is not None else 1
            probs.append({0: 1/p, 1: 1.0, 2: 1/q}[d])
        probs = np.array(probs) / sum(probs)
        prev, nxt = walk[-1], np.random.choice(cand, p=probs)
        walk.append(nxt)
    return walk

walks = [ [str(u) for u in biased_walk(G, v, p=1, q=0.25, length=30)]
          for _ in range(80) for v in G.nodes() ]
model = Word2Vec(walks, vector_size=64, window=5, min_count=0, sg=1, epochs=10)
Z = np.array([model.wv[str(v)] for v in sorted(G.nodes())])
km = KMeans(n_clusters=2, n_init=10, random_state=0).fit(Z)
print("NMI :", normalized_mutual_info_score(y, km.labels_))   # ~0.5-0.8 depending on p, q, seed

Exercise 2: vary (p, q) and relate the NMI to the BFS/DFS regime.

4. Spectral filters and spectral clustering

To filter a signal carried by the nodes (smooth it, detect its sharp variations) or to cut a graph into communities, one needs a notion of frequency on a graph. The eigenvectors of the Laplacian (Definition 0.4) provide it; this chapter builds the graph Fourier transform, uses it for spectral clustering, then turns it into the first graph convolutions.

Definition 4.1 — Graph Fourier transform Let L = U \Lambda U^\top (spectral decomposition, U orthogonal, columns u_1, \dots, u_n). For a signal x \in \mathbb{R}^n carried by the nodes:

Key result — graph Fourier transform \hat x = U^\top x \quad (\text{analysis}), \qquad x = U \hat x \quad (\text{synthesis}).

The “frequencies” are the eigenvalues \lambda_k — small = slow variations over the graph (low frequencies), large = local alternations (high frequencies). This is the convolution of the Signal Processing module, with the Laplacian in place of -\frac{d^2}{dt^2}: on a path, (Lx)_v = 2x_v - x_{v-1} - x_{v+1} is minus a discrete second derivative. Each \lambda_k plays the role of a squared frequency, as \omega^2 for the mode e^{i\omega t}.

Theorem 4.2 — Variational characterization of \lambda_2 (Fiedler) For a connected graph: \lambda_2 \;=\; \min_{x \neq 0,\ x \perp \mathbf{1}} \frac{x^\top L x}{x^\top x}, attained at the Fiedler vector u_2. The smaller \lambda_2, the more there exists a quasi-constant signal “almost orthogonal” to \mathbf{1} — that is, two large blocks of weakly connected opposite values.

Proof. Write x = \sum_i c_i u_i (orthonormal basis); x \perp \mathbf{1} forces c_1 = 0 since u_1 = \mathbf{1}/\sqrt{n} (for a connected graph the kernel of L is exactly spanned by \mathbf{1} — the multiplicity computation of Definition 0.4).

Then x^\top L x = \sum_{i \geq 2} \lambda_i c_i^2 and x^\top x = \sum_{i \geq 2} c_i^2; the quotient is a weighted average of the \lambda_i, i \geq 2, hence lower-bounded by \lambda_2, with equality for x = u_2. ∎

Example 4.3 — Fiedler vector on two linked cliques (exact computation) Two K_5s (\{u, x_1, \dots, x_4\} and \{v, y_1, \dots, y_4\}) linked by the bridge (u, v). By symmetry, look for an antisymmetric eigenvector: x_i = a on the 4 non-bridge nodes of the left, u \mapsto b, and opposite values on the right.

The equations L x = \lambda x at a non-bridge node (degree 4) and at u (degree 5) give: \lambda a = a - b \qquad \text{and} \qquad \lambda b = 6b - 4a \;\;\Rightarrow\;\; \lambda^2 - 7\lambda + 2 = 0. Hence \lambda_2 = \frac{7 - \sqrt{41}}{2} \approx 0.298, \qquad b = (1 - \lambda_2)\, a \approx 0.70\, a; the Fiedler vector equals, up to normalization: (\underbrace{1, 1, 1, 1}_{x_i}, \underbrace{0.70}_{u}, \underbrace{-0.70}_{v}, \underbrace{-1, -1, -1, -1}_{y_j}) — the sign exactly separates the two communities, and the bridge node takes an intermediate value. This is the picture to remember about spectral clustering.

Theorem 4.4 — Spectral clustering: complete algorithm and justification (RatioCut relaxation) Algorithm (for k communities):

  1. compute the first k eigenvectors u_1, \dots, u_k of L; form F = [u_1 \| \dots \| u_k] \in \mathbb{R}^{n \times k};
  2. normalize each row of F;
  3. apply k-means to the n rows of F (spectral descriptor).

Justification: the RatioCut of a partition \{C_1, \dots, C_k\} is \mathrm{RatioCut} = \sum_{j=1}^{k} \frac{\mathrm{cut}(C_j, \bar{C}_j)}{|C_j|} (cutting a small community is costly — unlike the plain minimization of the cut). Let H \in \mathbb{R}^{n \times k} denote the renormalized indicators H_{ij} = \mathbb{1}[v_i \in C_j] / \sqrt{|C_j|}.

Proof.

  1. Exactness on the discrete class. H^\top H = I (orthogonal columns of norm 1). Moreover h_j^\top L h_j = \sum_{(u,v) \in E} (h_j(u) - h_j(v))^2 = \frac{1}{|C_j|} \times |\{(u,v) \in E : |\{u, v\} \cap C_j| = 1\}| = \frac{\mathrm{cut}(C_j, \bar{C_j})}{|C_j|}. So \mathrm{tr}(H^\top L H) = \mathrm{RatioCut}: minimizing RatioCut = minimizing \mathrm{tr}(H^\top L H) over orthonormal indicators.
  2. Relaxation. We allow any F \in \mathbb{R}^{n \times k} with F^\top F = I; the relaxed problem \min_{F^\top F = I} \mathrm{tr}(F^\top L F) has as solution the first k eigenvectors (Ky Fan’s theorem: shown by writing L = \sum_i \lambda_i u_i u_i^\top, so that \mathrm{tr}(F^\top L F) = \sum_{i} \lambda_i\, \|F^\top u_i\|^2, \qquad 0 \leq \|F^\top u_i\|^2 \leq 1, \quad \sum_i \|F^\top u_i\|^2 = k, a weighted sum minimized by putting the weight on the k smallest \lambda_i).
  3. Back to the discrete. The rows of F remain close to the rows of renormalized indicators; k-means groups them. ∎

Normalized Cut variant (Shi & Malik): weighting by the volumes d(C_j) leads to the generalized problem L y = \lambda D y, solved by the eigenvectors of L_{\mathrm{sym}} — this is the version used in practice (and by scikit-learn).

Links: PCA (Machine Learning module — the matrix F is the spectral counterpart of the projection); SBM (ch. 9) for the statistical approach; sign ambiguities of the eigenvectors — a real problem for GNNs, solved by SignNet (M2, ch. 4).

Theorem 4.5 — ChebNet: Chebyshev polynomials (Defferrard et al., 2016) Filtering exactly costs y = U\, g_\theta(\Lambda)\, U^\top x — a full decomposition (\mathcal{O}(n^3)) specific to each graph.

Trick: take g_\theta a polynomial of degree K in the Chebyshev basis. Set T_0(x) = 1, \qquad T_1(x) = x, \qquad T_{k+1}(x) = 2x T_k(x) - T_{k-1}(x), and \tilde\Lambda = \frac{2\Lambda}{\lambda_{\max}} - I (rescaling to [-1, 1]); then y = \sum_{k=0}^K \theta_k\, T_k(\tilde L)\, x, \qquad \tilde L = \frac{2L}{\lambda_{\max}} - I, without eigenvectors: K-localized filter, weights \theta shared by all graphs.

Proof.

  1. Chebyshev recursion. For x = \cos\theta, T_k(x) = \cos(k\theta); the addition formula \cos((k{+}1)\theta) = 2\cos\theta \cos(k\theta) - \cos((k{-}1)\theta) gives the recursion (it propagates to all x \in \mathbb{R} by polynomial identity).

  2. Functional calculus. Let us show T_k(\tilde L) = U T_k(\tilde\Lambda) U^\top: this is true for the monomials by recursion, \tilde L^m = (U \tilde\Lambda U^\top)^m = U \tilde\Lambda^m U^\top, the inner products U^\top U canceling — hence for every polynomial. Thus y = U\, g_\theta(\tilde\Lambda)\, U^\top x = g_\theta(\tilde L)\, x: the spectral filter is expressed as a polynomial of L applied directly to x.

  3. Locality. \tilde L x at a node only combines x_v and \{x_u : u \in \mathcal{N}(v)\}.

    By recursion on the Chebyshev recursion (linear combination of \tilde L^k x, k \leq K), the output at v depends only on the K-neighborhood. ∎

Cost: \mathcal{O}(K |E|) per application — linear in the size of the graph.

Proposition 4.6 — From spectral to spatial: the equality demonstrated Every filter that is a polynomial of degree K in L is exactly a K-localized operator.

Conversely, a linear message passing with K layers whose propagation is a polynomial of a fixed symmetric shift operator S realizes a polynomial spectral filter in the eigenbasis of S. Typical shifts are A, L, L_{\mathrm{sym}}, or the GCN propagator of Derivation 5.2, \hat A = \tilde D^{-1/2} \tilde A \tilde D^{-1/2}.

Proof. Forward direction: step 3 of the proof of Theorem 4.5 (locality).

Conversely: a local layer with one weight for the node and one shared by its neighbors writes y = (c_0 I + c_1 S)\, x, a polynomial of degree 1 in S.

Composing K layers without non-linearity gives y = p(S)\, x with \deg p \leq K. Diagonalizing S = U_S \Lambda_S U_S^\top, p(S) = U_S\, p(\Lambda_S)\, U_S^\top: a spectral filter with frequency response p on the spectrum of S.

For S = L_{\mathrm{sym}}, or \hat A = I - \tilde L_{\mathrm{sym}} with \tilde L_{\mathrm{sym}} the Laplacian of the graph with self-loops, this is a polynomial filter of that Laplacian.

Caution: the Laplacian L = D - A is a polynomial in A only on a regular graph, where D = dI. Otherwise the degree matrix does not commute with A, and a polynomial of the adjacency is not a polynomial of the Laplacian; the spectral reading must use the operator the layer actually applies.

The non-linearities between layers break the exact equality — this is precisely the gap between the spectral “CNN on graph” and the spatial GNN: the GNN generalizes the filter by inserting point-wise non-linearities, like a 1D CNN. ∎

5. GNNs and message passing

Spectral filters are tied to the eigenvectors of one fixed graph. We want instead a layer that applies to any graph, costs time linear in the number of edges and trains like an ordinary network layer; message passing is that layer — each node updates its vector from the vectors of its neighbors.

Definition 5.1 — The message passing layer (MPNN, Gilmer et al., 2017) h_v^{(\ell+1)} = \phi\Big(h_v^{(\ell)},\ \underset{u \in \mathcal{N}(v)}{\mathrm{AGG}}\ \big\{\psi\big(h_v^{(\ell)}, h_u^{(\ell)}\big)\big\}\Big) message \psi (computed by the neighbor), aggregation \mathrm{AGG} (permutation-invariant: sum, mean, max, attention), update \phi.

One layer = one round of message passing = one convolution = one diffusion step on the graph. The choice of \mathrm{AGG} is not innocent: mean/max lose cardinality ({a, a} and {a} have the same mean and the same max); this is the subject of the GIN theorem below.

Proposition 5.1b — Expressivity: MPNN ≤ 1-WL, and a sum aggregator reaches it (Xu et al., 2019; Morris et al., 2019)

  1. If 1-WL (Algorithm 2.5, with one dictionary shared by both graphs) gives two nodes the same color after \ell rounds, every MPNN gives them the same h^{(\ell)}. Two graphs that 1-WL does not separate therefore get the same invariant readout.
  2. With sum aggregation, an injective update and an injective readout, an MPNN separates every pair of graphs that 1-WL separates (countable input features). GIN is such a model: h_v^{(\ell+1)} = \mathrm{MLP}\Big((1 + \varepsilon)\, h_v^{(\ell)} + \sum_{u \in \mathcal{N}(v)} h_u^{(\ell)}\Big).

Proof. Sketch. (1) Induction on the round; at round 0, equal colors mean equal features. If two nodes share a color at round \ell + 1, they shared one at round \ell, and so did the multisets of their neighbors.

By induction their states and the multisets of their neighbors’ states coincide, and the message, aggregation and update functions only see these.

  1. Mean and max are not injective on multisets: \{\!\{a, a\}\!\} and \{\!\{a\}\!\} have the same mean and max. The sum separates them, since 2f(a) \neq f(a) when f(a) \neq 0.

For countable features, some f makes \sum_{x \in S} f(x) injective over multisets S of bounded size (Xu et al., 2019, Lemma 5), and the MLP approximates the injective update.

Full proofs, and what lies beyond 1-WL: Advanced GNN, ch. 2. ∎

Derivation 5.2 — GCN from spectral convolution (Kipf & Welling, 2017) Start from the Chebyshev filter of Theorem 4.5 truncated at K = 1, on the normalized Laplacian L_{\mathrm{sym}} = I - D^{-1/2} A D^{-1/2}, whose eigenvalues lie in [0, 2].

  1. Approximating \lambda_{\max} \approx 2 gives \tilde L = L_{\mathrm{sym}} - I, hence g_\theta(L)\, x \approx \theta_0\, x + \theta_1 (L_{\mathrm{sym}} - I)\, x = \theta_0\, x - \theta_1\, D^{-1/2} A D^{-1/2}\, x.
  2. Keeping a single parameter \theta = \theta_0 = -\theta_1 (fewer parameters, less overfitting on small graphs): g_\theta(L)\, x \approx \theta\,\big(I + D^{-1/2} A D^{-1/2}\big)\, x.
  3. The operator I + D^{-1/2} A D^{-1/2} has its eigenvalues in [0, 2]: applied \ell times it can multiply some components by up to 2^\ell, and deep stacks become numerically unstable.
  4. The renormalization trick replaces it by the propagator \hat A = \tilde D^{-1/2} \tilde A \tilde D^{-1/2}, where \tilde A = A + I adds a self-loop to each node and \tilde D is the degree matrix of \tilde A; its eigenvalues lie in (-1, 1].

Adding the features X, a weight matrix and a non-linearity, we obtain the GCN layer:

Key result — the GCN layer H^{(\ell+1)} = \sigma\Big(\tilde D^{-1/2}\, \tilde A\, \tilde D^{-1/2}\, H^{(\ell)}\, W^{(\ell)}\Big), \qquad H^{(0)} = X,

a degree-normalized mean of the transformed representations of the node and of its neighbors; L layers give a receptive field of L hops.

Because the gains of the propagator stay in (-1, 1], depth no longer makes the signal explode — but repeated averaging makes it collapse instead: this is the over-smoothing of Theorem 5.3.

GraphSAGE (Hamilton et al., 2017) — algorithm and pseudo-code For each node, aggregate a sample of neighbors then concatenate with the current representation:

input : G, features X, depth K, sample sizes s_1..s_K
for v in V : h_v^(0) = x_v
for l = 1 .. K :
    for v in V :
        S_v = uniform sample of N(v) of size s_l               # K neighbors in the paper
        a_v^(l) = AGG({ h_u^(l-1) : u in S_v })                 # mean / LSTM / pool
        h_v^(l) = sigma( W_l . [ h_v^(l-1) || a_v^(l) ] )       # concatenation!
        h_v^(l) = h_v^(l) / ||h_v^(l)||                          # L2 normalization
output : z_v = h_v^(K)

The concatenation preserves the information specific to the node (otherwise the mean of the neighbors crushes the local signal); the fixed per-layer sampling bounds the minibatch (ch. 7); the whole scheme is inductive: the weights W_l are re-applied to unseen nodes/graphs.

Special cases: AGG = mean ≈ GCN without renormalization; AGG = pool (MLP + max); AGG = LSTM over neighbors randomly ordered (the ordering breaks invariance… an accepted approximation; the ordering problem is addressed by GOAT, ch. 11).

Attention in one formula (Deep Learning P1, ch. 6; Deep Learning P2, ch. 0)

For n tokens X \in \mathbb{R}^{n \times d}, with Q = XW_Q, K = XW_K and V = XW_V: \mathrm{Attn}(X) = \mathrm{softmax}\Big(\frac{QK^\top}{\sqrt{d_k}} + M\Big)\, V, with the softmax taken row by row. The mask M holds 0 where token i may look at token j and -\infty elsewhere: all zeros in an encoder, -\infty above the diagonal in a decoder.

GAT is this formula with the graph as mask, M_{vu} = 0 if u \in \mathcal{N}(v) \cup \{v\} and -\infty otherwise, and an additive score in place of the scaled dot product: attention masked by A.

GAT (Veličković et al., 2018) — equations and complexity Edge weights learned by attention: e_{uv} = \mathrm{LeakyReLU}\big(a^\top [\,W h_u \| W h_v\,]\big), \qquad \alpha_{uv} = \frac{\exp(e_{uv})}{\sum_{u' \in \mathcal{N}(v)} \exp(e_{u'v})}, \qquad h_v^{(\ell+1)} = \sigma\Big(\sum_{u \in \mathcal{N}(v)} \alpha_{uv}\, W h_u^{(\ell)}\Big) with T parallel attention heads (T projections W^{(t)}) concatenated or averaged.

Per-layer complexity, with F and F' the input and output dimensions: \mathcal{O}(|V| F F' + |E| F') — linear in edges, comparable to GCN, but with weights tailored to each edge: useful when the graph is noisy or some relations matter more (suspicious transactions!).

Structurally identical to the attention of transformers (Deep Learning module): here the attention mask is given by the graph, there it is computed — the graph transformers of M2 (ch. 5) close the loop by learning the attention and biasing it with structure.

Beyond the homogeneous graph: R-GCN, edge features

  • R-GCN (Schlichtkrull et al., 2018): relational graph (edge types r in \mathcal{R}); h_v^{(\ell+1)} = \sigma\big(W_0 h_v^{(\ell)} + \sum_{r \in \mathcal{R}} \sum_{u \in \mathcal{N}_r(v)} \frac{1}{c_{v,r}} W_r\, h_u^{(\ell)}\big). To avoid the parameter explosion (|\mathcal{R}| \times F \times F'): basis decomposition W_r = \sum_b a_{rb} V_b or block-diagonal. Typical use: encoding knowledge graphs for link prediction (ch. 6).
  • Edge features: (a) line graph (each edge becomes a node); (b) convolution over edges (NNConv): \psi(h_u, e_{uv}) instead of \psi(h_u) — the chemical bond carries a type; (c) conditioned attention (GAT can inject e_{uv} into the e_{uv}-score).
  • Hierarchical pooling: DiffPool (Ying et al., 2018) learns a soft assignment matrix S^{(\ell)} = \mathrm{softmax}(\mathrm{GNN}_A(H^{(\ell)})) and contracts the graph: H^{(\ell+1)} = S^{(\ell)\top} H^{(\ell)}, A^{(\ell+1)} = S^{(\ell)\top} A^{(\ell)} S^{(\ell)} — neural coarse-graining, costly but hierarchical; alternatives: sort/TopK pooling, pyramidal readout.

Theorem 5.3 — Over-smoothing: proof on a regular graph On a connected d-regular graph, GCN propagation without weights/non-linearity satisfies H^{(\ell)} = \hat A^\ell X with \hat A = \frac{A + I}{d + 1}. Then H^{(\ell)} \xrightarrow[\ell \to \infty]{} \frac{\mathbf{1}\mathbf{1}^\top}{n}\, X, the harmonic solution (global mean), at geometric rate \rho^\ell with \rho = \max_{i \geq 2} \frac{|\mu_i + 1|}{d + 1} < 1, where \mu_1 \geq \mu_2 \geq \dots are the eigenvalues of A.

Proof. On a d-regular graph, \tilde D = (d+1)I, hence \hat A = \tilde D^{-1/2} \tilde A \tilde D^{-1/2} = \frac{A + I}{d+1}.

Since A is real symmetric, write X in its eigenbasis: A = \sum_i \mu_i u_i u_i^\top, with u_1 = \mathbf{1}/\sqrt{n}, \mu_1 = d > \mu_2 \geq \dots, and \mu_i < d for i \geq 2 (equality only if there is a distinct connected component). Then \hat A^\ell = \sum_i \big(\frac{\mu_i + 1}{d+1}\big)^\ell u_i u_i^\top .

The i = 1 term equals exactly \frac{\mathbf{1}\mathbf{1}^\top}{n}; all the others have a ratio \frac{\mu_i + 1}{d + 1} in \big[\frac{1-d}{d+1}, 1\big) (since -d \leq \mu_i < d), hence of absolute value < 1, and decay geometrically.

All the information of the non-constant components is erased: every node converges to the same mean row vector — the embeddings collapse. ∎

With weights and non-linearities, the phenomenon persists (rank collapse; Oono & Suzuki, ICLR 2020): this is a structural limit of GCN depth. Remedies:

  • Jumping Knowledge (Xu et al., 2018): the readout aggregates all the depths h_v = \mathrm{JK}(h_v^{(1)}, \dots, h_v^{(L)}) (concat / max / LSTM-attention): each node chooses its scale;
  • residuals and normalizations (GCNII, APPNP — developed in M2, ch. 3);
  • in practice, 2-4 layers usually suffice: the useful depth is the range of the statistical dependence of the task.

A second structural limit — over-squashing (topological bottlenecks) — is different: it concerns the channel rather than the representation, and is addressed by rewiring; the whole topic is in M2, ch. 3. A third limit: expressivity bounded by 1-WL (M2, ch. 2).

Heterophily: when neighbors differ

The seventh lecture of the official programme treats heterophily and temporal graphs. GCN-style averaging implicitly assumes homophily — linked nodes tend to share their label. Fraud rings (fraudsters link to honest accounts they exploit), dating networks, protein interactions or the “is a student of” relation violate it.

Definition 5.4 — Homophily ratio For a labeled graph, the edge homophily is h = \frac{|\{(u,v) \in E : y_u = y_v\}|}{|E|} \in [0, 1].

Citation graphs are strongly homophilous (Cora h \approx 0.81, Citeseer \approx 0.74). The standard heterophilous benchmarks are far lower (Texas \approx 0.11, Wisconsin \approx 0.21, Chameleon \approx 0.23, Squirrel \approx 0.22; Pei et al., 2020; Zhu et al., 2020).

A low h is not harmful in itself: what matters is whether the label distribution of a node’s neighbors is informative about its own label (Ma et al., 2022).

Proposition 5.5 — Mean aggregation on a perfectly heterophilous graph, computed Take a connected d-regular bipartite graph whose two sides are the two classes, with a scalar feature x_v = +1 on one side and -1 on the other (h = 0). One GCN propagation (Theorem 5.3, \hat A = (A + I)/(d+1)) gives (\hat A x)_v = \frac{x_v + \sum_{u \in \mathcal{N}(v)} x_u}{d + 1} = \frac{1 - d}{d + 1}\, x_v.

For d = 1 the signal is erased; for d = 3 it becomes -0.5\,x_v: sign flipped, magnitude halved; with L layers it shrinks as \big(\frac{d-1}{d+1}\big)^L.

Spectral reading (Definition 0.4): this label signal has x^\top L x = \sum_{(u,v) \in E}(x_u - x_v)^2 = 4m, the largest possible value for \pm 1 signals — it is a high-frequency signal, and GCN propagation is a low-pass filter (ch. 4) that attenuates exactly such components.

Mixing the node with its neighbors inside one average makes the two cancel; keeping them separate, h_v = W_1 x_v \,\|\, W_2\, \mathrm{mean}_{u \in \mathcal{N}(v)} x_u, \quad \text{here } (x_v, -x_v), preserves the information fully.

Architectures for heterophily H2GCN (Zhu et al., 2020) combines three designs: ego/neighbor separation (as above, and as in GraphSAGE’s concatenation), aggregation over 2-hop neighborhoods (in a bipartite graph the same class sits two hops away) and combination of all intermediate layers (as Jumping Knowledge).

GPR-GNN (Chien et al., 2021) learns the coefficients \gamma_k of a polynomial filter \sum_k \gamma_k \hat A^k X; negative coefficients produce high-pass filters (Proposition 4.6 makes this a spectral design).

FAGCN uses signed attention weights, letting a node subtract the messages of dissimilar neighbors. The interaction of heterophily with over-smoothing and over-squashing is developed in M2, ch. 3.

Temporal graphs

Definition 5.6 — Discrete- and continuous-time dynamic graphs A discrete-time dynamic graph is a sequence of snapshots G_1, \dots, G_T (one per day, per week); a continuous-time dynamic graph is a stream of timestamped events (u, v, t, e_{uv}) — transactions, messages, citations.

Tasks: temporal link prediction (will u interact with v at time t?), dynamic node classification (is this account fraudulent now?), and forecasting node signals on a fixed graph (traffic: spatio-temporal graphs).

The causality rule: a prediction at time t may use only events with timestamps < t.

Models 5.7 — Snapshot models, TGAT and TGN Snapshot models run a GNN on each G_\tau and an RNN over time, either on the node embeddings (GCRN) or on the GNN weights themselves (EvolveGCN, Pareja et al., 2020).

TGAT (Xu et al., 2020) handles continuous time with a GAT-like attention over a node’s past neighbors, each message concatenated with a functional time encoding of the elapsed time \Delta t: \Phi(\Delta t) = \big[\cos(\omega_1 \Delta t + b_1), \dots, \cos(\omega_k \Delta t + b_k)\big], with learned frequencies — a random-feature form of a translation-invariant kernel in time (Bochner’s theorem).

TGN (Rossi et al., 2020) adds a memory s_v(t) per node, updated at each event involving v by a recurrent cell, s_v(t) \leftarrow \mathrm{GRU}\big(s_v(t^-),\ \mathrm{msg}(s_v(t^-), s_u(t^-), \Delta t, e_{uv})\big); embeddings are computed by temporal attention over recent neighbors and their memories, and an MLP decodes link probabilities.

Events are processed in chronological batches, and the memory is updated after the batch has been predicted, so that no event informs its own prediction.

Example 5.8 — Temporal neighborhoods and leakage, computed Events: (a, b, 1), \quad (b, c, 2), \quad (a, c, 5), \quad (c, d, 7). Query at t = 6: will c interact with d?

The admissible history is the first three events. The temporal neighbors of c are b (elapsed \Delta t = 4) and a (\Delta t = 1).

Their time encodings \Phi(4) and \Phi(1) differ, so the attention can favour the recent contact.

Node d has no past event: the prediction is inductive and rests on its features and on the time encoding only.

A static GNN trained on the aggregated graph would contain the edge (c, d) — the very event to be predicted — and report an inflated score; the honest protocol splits events chronologically (train on t \leq 5, test on t > 5), as in Example 8.1. Memory-based models and temporal benchmarks are developed in M2, ch. 6.

Protocol — temporal link prediction without leakage Scores in this field can move by tens of points with the protocol, so fix it before comparing models.

  1. Causal split. Sort the events by time and cut twice, for example 70 / 15 / 15 % of the events for training, validation and test. At test time, memories and temporal neighbors use only the events before each query; events are revealed batch by batch, after their batch has been predicted.
  2. Transductive or inductive. A transductive test event joins two nodes seen in training; an inductive one involves at least one node never seen. Report both, since memory models degrade on the second.
  3. Negatives. Each positive (u, v, t) is scored against negative pairs at the same time t. Random negatives (uniform pairs, or (u, v') with a uniform v') are easy and inflate the score. Historical negatives are pairs seen in the training period but absent at t, and test whether the model only predicts repeats. Inductive negatives are pairs first seen earlier in the test period and absent at t (Poursafaei et al., 2022).
  4. Loss and metric. TGN trains by binary cross-entropy on each positive and one sampled negative, \mathcal{L} = -\sum_{(u, v, t)} \Big[\log \sigma\big(s_t(u, v)\big) + \log\big(1 - \sigma(s_t(u, v'))\big)\Big], and is evaluated by AP or AUC, or by the MRR of the true destination among many negatives (TGB, Huang et al., 2023).
import torch
from torch_geometric.nn import GCNConv, GATConv
from torch_geometric.datasets import Planetoid

dataset = Planetoid(root="/tmp/Cora", name="Cora")   # 2708 nodes, 5278 undirected edges, 7 classes
data = dataset[0]

class GCN(torch.nn.Module):
    def __init__(self, d_in, d_hid, n_classes):
        super().__init__()
        self.c1, self.c2 = GCNConv(d_in, d_hid), GCNConv(d_hid, n_classes)
    def forward(self, x, edge_index):
        return self.c2(torch.relu(self.c1(x, edge_index)), edge_index)

model = GCN(dataset.num_features, 64, dataset.num_classes)
opt = torch.optim.Adam(model.parameters(), lr=0.01, weight_decay=5e-4)
for epoch in range(200):
    opt.zero_grad()
    out = model(data.x, data.edge_index)
    loss = torch.nn.functional.cross_entropy(out[data.train_mask], data.y[data.train_mask])
    loss.backward(); opt.step()
acc = (model(data.x, data.edge_index).argmax(1)[data.test_mask]
       == data.y[data.test_mask]).float().mean()
print(f"Cora test accuracy : {acc:.3f}")   # ~0.81 with this simple setting

6. Link prediction and graph auto-encoders

Many graphs are incomplete: a recommender wants the purchases that have not happened yet, a knowledge graph misses true facts. This chapter turns the node representations of ch. 3 and 5 into scores for pairs of nodes, and trains them to recover the missing edges.

Definition 6.1 — Link prediction Predicting the existence (or the type) of a missing edge (u, v): the most widespread task in industry — recommendation (“who will like what?”), completion of knowledge graphs (“does this drug target this protein?”), prediction of future interactions (M2 ch. 6 for the temporal case).

Protocol: mask a fraction of the edges (10%), sample as many “negatives” (non-adjacent pairs), score all the pairs, measure AUC / Hits@k.

ELBO and reparameterization in three lines (Machine Learning, 7.2)

  • For any distribution q_\phi(z \mid x), \log p_\theta(x) = \mathrm{ELBO} + \mathrm{KL}\big(q_\phi(z \mid x) \,\|\, p_\theta(z \mid x)\big) \geq \mathrm{ELBO}, \mathrm{ELBO}(\theta, \phi; x) = \mathbb{E}_{q_\phi}[\log p_\theta(x \mid z)] - \mathrm{KL}\big(q_\phi(z \mid x) \,\|\, p(z)\big). This is the bound of EM in Machine Learning 7.2, where q is the exact posterior; here q is a network, and the ELBO is maximized.
  • To differentiate through the sampling, write z = \mu + \sigma \odot \varepsilon with \varepsilon \sim \mathcal{N}(0, I): the randomness moves into \varepsilon, and gradients reach \mu and \sigma.
  • For a Gaussian q and the prior \mathcal{N}(0, I), the KL term is explicit: \mathrm{KL} = \frac12 \sum_j \big(\mu_j^2 + \sigma_j^2 - 1 - \log \sigma_j^2\big).

GAE / VGAE (Kipf & Welling, 2016) — graph auto-encoders GAE: encoder Z = \mathrm{GCN}(X, A); decode by dot product — the reconstruction probability of an edge:

Key result — the GAE decoder p(A_{uv} = 1 \mid z_u, z_v) = \sigma(z_u^\top z_v).

Training: maximize the likelihood of the observed edges and minimize that of the negatives — the cross-entropy of the negative sampling of ch. 3, transposed: \mathcal{L} = -\sum_{(u,v) \in E^+} \log \sigma(z_u^\top z_v) \; - \sum_{(u,v') \in E^-} \log \big(1 - \sigma(z_u^\top z_{v'})\big).

VGAE: variational Gaussian encoder q(Z \mid X, A) = \prod_i \mathcal{N}(z_i;\ \mu_i, \mathrm{diag}(\sigma_i^2)) with \mu = \mathrm{GCN}_\mu(X, A), \log\sigma = \mathrm{GCN}_\sigma(X, A), prior \mathcal{N}(0, I). One maximizes the ELBO of the recall above, \mathrm{ELBO} = \mathbb{E}_{q}[\log p(A \mid Z)] - \mathrm{KL}\big(q(Z \mid X,A)\,\|\,\mathcal{N}(0, I)\big), that is, one minimizes \mathcal{L}_{\mathrm{VGAE}} = -\mathrm{ELBO}, with the reparameterization z_i = \mu_i + \sigma_i \odot \varepsilon, \varepsilon \sim \mathcal{N}(0, I).

Results on Cora (Kipf & Welling, 2016): AUC 0.910 for GAE and 0.914 for VGAE, average precision 0.920 and 0.926. The prior regularizes the dot product (cf. the connection with SBM inference, ch. 9).

Scoring pairs: the choice of the decision function

  • dot product z_u^\top z_v — rank-d decomposition, symmetric, related to NetMF (ch. 3);
  • MLP over (z_u \odot z_v, z_u - z_v) or concatenation — asymmetric (important in recommendation: “A buys B” ≠ “B buys A”);
  • relational distances (KGC, below);
  • negatives: uniform (easy) vs hard — pairs sharing a neighbor (popularity-biased); the choice of negatives changes the learned ranking, as the k negatives of skip-gram do (Recall 3.1) and the in-batch negatives of Sentence-BERT (NLP, ch. 7).

PinSage (Ying et al., 2018) — recommendation at industrial scale The Pinterest deployment of GraphSAGE: a user-pin graph of 3 billion nodes and 18 billion edges, trained by minibatches. Two key differences from GraphSAGE:

  1. importance sampling: instead of uniform neighbors, the T neighbors most often visited by short random walks started at the node (a personalized PageRank score); their normalized visit counts also weight the aggregation;
  2. ranking loss (hinge margin): \max(0, m - s(u, v^+) + s(u, v^-_h)) with v^-_h a hard negative (a pin popular but not clicked); production requires candidates ranked by approximate score (vector search — NLP/Multimodal module).

LLGA lesson: at this scale, the architecture matters less than the system (sampling, cache, GPU) — this is the bridge to ch. 7.

Knowledge graph completion (KGC) Link prediction on a typed heterogeneous graph (heads h, relations r, tails t):

  • TransE (Bordes et al., 2013): embeddings in \mathbb{R}^d with the energy score f(h, r, t) = -\|h + r - t\| — the relation is a translation; margin-based training (positives vs corrupted negatives); illuminating but limited (1-N, symmetric relations);
  • R-GCN + score (ch. 5): the encoder propagates over the typed graph, a decoder (DistMult: \langle h, \mathrm{diag}(r), t \rangle) scores the triples — the “encode-decode” architecture dominates;
  • GraphRAG link: an enterprise KG completed by KGC becomes queryable by an LLM (ch. 10); the completion deficits guide the collection of data — a data/model loop specific to the LLGA trade.

7. GNNs at scale

The models of ch. 5 were trained on Cora, which fits in memory; industrial graphs have millions of nodes and billions of edges. This chapter explains why full-batch training breaks at that scale and presents the three standard ways of training on pieces of the graph.

Why full-batch does not fit The gradient of a GCN layer mobilizes the whole graph: activation memory \mathcal{O}((|V| + |E|) d) per layer, not to mention the densification of the deep layers.

On ogbn-products (2.4 million nodes, 61.9 million edges), the full-batch does not fit on a GPU; three families of solutions, all grounded on the same observation: the dependence of a node over L layers is limited to its L-neighborhood.

7.1 — Neighborhood minibatching (GraphSAGE / NeighborSampler) For a batch of target nodes \mathcal{B} and a depth L with sampling sizes (s_L, \dots, s_1) (fanouts):

N_L = B                                             # the target nodes of the batch
for l = L .. 1 :                                    # from the output layer down to the input
    N_{l-1} = N_l + (s_l sampled neighbors of each node of N_l)
compute h^(1), ..., h^(L) layer by layer, layer l only on the nodes of N_l
update the parameters with the loss on the outputs of B only

Subgraph size: |\mathcal{B}| \times (1 + s_L (1 + s_{L-1}(\dots))). With L = 2, s_1 = s_2 = 10, a batch of 1 node touches at most 1 + 10 + 100 = 111 nodes — bounded, independent of n.

Two subtleties: (i) the estimator is unbiased in expectation for the mean over neighbors, but the variance explodes at the hubs (hence decreasing fanouts); (ii) the nested samplings create redundant computation across batches (the “expansive neighborhood”; PyG’s NeighborLoader implements exactly this).

7.2 — Cluster-GCN (Chiang et al., 2019): partitioning Partition the graph into k clusters (METIS), each batch = one whole cluster: GCN training on the induced subgraph costs \mathcal{O}(|E_c| d + |V_c| d^2) and each full epoch costs \mathcal{O}(|E|) — like the full-batch, but in constant memory, and deep GCNs become trainable again.

The price: the partition bias — the edges between clusters are invisible during the step.

The correction of the paper builds each batch from several clusters drawn at random, which restores the edges between the chosen clusters and varies the batches from one epoch to the next; for deep models it also enlarges the diagonal of the normalized adjacency, \bar A = \tilde A + \lambda\,\mathrm{diag}(\tilde A), so that each node keeps weight on its own representation.

Even better: link the clusters by a “virtual graph” of clusters — a precursor of the GraphRAG hierarchies (ch. 10).

7.3 — GraphSAINT (Zeng et al., 2020): sampling subgraphs, unbiasedly Flip the perspective: first sample a subgraph \mathcal{G}_s (by nodes, by edges, or by random walks), then compute a corrected gradient on it.

The key is the normalization by inclusion probabilities. Let p_v be the probability that the sampler includes node v and p_{uv} the probability that it includes edge (u, v) (both estimated once, by pre-sampling).

Inside the subgraph, the message from u to v is divided by \alpha_{uv} = p_{uv}/p_v, which makes each aggregation an unbiased estimator of the full-graph aggregation, and the loss is reweighted as \mathcal{L}_{\mathrm{batch}} = \sum_{v \in \mathcal{G}_s} \frac{\mathcal{L}_v}{\lambda_v}, \qquad \lambda_v = |V|\, p_v, whose expectation is exactly the mean loss over all the nodes: \mathbb{E}\big[\sum_{v \in \mathcal{G}_s} \mathcal{L}_v / \lambda_v\big] = \sum_{v \in V} p_v \mathcal{L}_v / (|V| p_v). The paper proves both statements by writing the expectation over the sampling scheme.

Hidden benefit: the batches are “dense” (no expansive neighborhood), and walk-based sampling captures the community structure.

The general picture: bias-variance-memory — neighbor-sampling (high variance, zero bias); cluster-GCN (partition bias, zero variance); GraphSAINT (unbiased by reweighting, variance controlled by RW sampling).

These trade-offs are the daily bread of M2, ch. 1 (and of the Emerging ML module for the federated parallel: partitions = clients).

OGB — measuring honestly at scale (Hu et al., 2020)

Benchmark Size Task
ogbn-arxiv 169,343 nodes, 1.2M edges node classification
ogbn-products 2.4M nodes, 61.9M edges node classification
ogbg-molhiv / molpcba 41,127 / 437k molecules graph classification
ogbl-ppa / citation2 large bipartite/citation graphs link prediction

Rules of the game: fixed splits, defined model selection protocols, public leaderboards — the experimental hygiene of M2 (ch. 1; Dwivedi et al., “Benchmarking GNNs”) is not optional: at this scale, progress is measured in tenths of a point and only strict protocols distinguish it from noise.

8. Applications and hands-on

The previous chapters gave the models; this chapter maps them onto the use cases met in industry, then gives the protocol of a first honest experiment — the step where most graph projects go wrong.

Architecture choice — quick decision sheet

  • Homogeneous graph, rich features: GCN (baseline);
  • noisy/heterogeneous edges (fraud): GAT / R-GCN;
  • inductive production: GraphSAGE;
  • need to distinguish local structures (cycles): GIN + motif features (M2, ch. 2);
  • long-range dependencies (molecules, QA over KGs): graph transformer (M2, ch. 5).

Always: 2-4 layers, skip connections, light dropedge as a first choice.

Example 8.1 — Hands-on: evaluating link prediction without leakage Take a graph with 10,000 edges and the task “predict the missing edges”. The tempting protocol trains a GAE (ch. 6) on all the edges, then scores 1,000 of them as “test” edges.

The encoder has already passed messages along those edges, so their endpoints have similar embeddings by construction, and the AUC is optimistic. The honest protocol has three steps.

  1. Split before training. Remove 1,000 test edges (10%) and 500 validation edges (5%) from the graph, and draw as many non-adjacent pairs as negatives for each set.
  2. Train on what remains. The encoder sees only the 8,500 training edges, both as supervision and as the graph along which messages are passed; node features computed from the structure (degrees, PageRank) are computed on this training graph too.
  3. Score the held-out pairs. Report the AUC (or Hits@k) of the test positives against the test negatives, after choosing the hyperparameters on the validation set only.

When the edges carry timestamps (transactions, citations), replace the random split by a temporal one — train on the edges before a date, test on those after it — since a random split lets the model see the future.

In PyG, RandomLinkSplit implements steps 1 and 2; the same discipline applies to node classification, where the test labels must never be used, even through the features of their neighbors.

Team project (proposal) The course description announces “quizzes and team projects”. We propose to make the team project the graph work package of a Year 1 capstone: one team repository, three graded work packages. The graph package is graded here; the RL and NLP packages are graded by those courses.

  • Start: session 9, with the leakage-free protocol of Example 8.1; six weeks in all.
  • Subjects: the capstones Y1.1–Y1.5 of the end-of-year projects page (GraphRAG router, fleet dispatch, news recommendation, molecules from words, scene-graph QA), or a graph-only subject of Projects and assessment.
  • Read ahead: sections 10.1–10.2 by week 2 and 9.4–9.7 by week 3, since they are taught in sessions 11–12.
  • Grading: the graph package is one row of the shared capstone rubric (10–15 points out of 100); this course grades it with the proposed rubric of Projects and assessment.

Geometric graphs and applications in biomedicine

The eighth lecture of the official programme concerns geometric graphs — graphs whose nodes live in physical space — and their applications in biomedicine, where molecules and proteins are the central objects. The new ingredient is a second symmetry, on top of the permutations of Definition 2.1: moving or rotating a molecule does not change its chemistry.

Definition 8.2 — Geometric graph and E(3) symmetry A geometric graph has node features h_v (atom type, residue) and coordinates x_v \in \mathbb{R}^3; its edges are chemical bonds or the pairs closer than a cutoff r (radius graph).

The Euclidean group E(3) acts by x \mapsto Qx + t with Q orthogonal (Q^\top Q = I: rotations and reflections) and t a translation.

A model predicting a scalar property (energy, solubility) must be invariant; one predicting vectors (forces) must be equivariant: f(QX + t, H) = f(X, H), \qquad F(QX + t, H) = Q\,F(X, H), and for updated positions X' \mapsto QX' + t.

Feeding raw coordinates into an ordinary MPNN breaks this symmetry; training with random rotations only enforces it approximately.

Proposition 8.3 — The EGNN layer is E(n)-equivariant (Satorras, Hoogeboom & Welling, 2021) The layer m_{uv} = \phi_e\big(h_u, h_v, \|x_u - x_v\|^2, a_{uv}\big), \qquad x_v' = x_v + C \sum_{u \neq v} (x_v - x_u)\, \phi_x(m_{uv}), \qquad h_v' = \phi_h\Big(h_v, \sum_{u \in \mathcal{N}(v)} m_{uv}\Big), with MLPs \phi_e, \phi_x, \phi_h and a constant C, maps (QX + t, H) to (QX' + t, H'): the features are invariant and the coordinates equivariant.

Proof. Distances are invariant since Q is orthogonal: \|(Qx_u + t) - (Qx_v + t)\|^2 = \|Q(x_u - x_v)\|^2 = \|x_u - x_v\|^2 . Hence every message m_{uv}, and therefore h_v', is unchanged.

For the coordinates, the translation cancels in the differences and Q factors out of the linear combination: (Qx_v + t) + C\sum_u Q(x_v - x_u)\,\phi_x(m_{uv}) = Q\big(x_v + C\sum_u (x_v - x_u)\,\phi_x(m_{uv})\big) + t = Q x_v' + t . ∎

The cost is that of an ordinary MPNN. Invariant models that use only distances (SchNet) or distances and angles (DimeNet), and higher-order equivariant networks built on spherical harmonics (tensor field networks, MACE), trade cost for expressivity; they are named here for orientation only. M2, ch. 8 takes up the EGNN itself: 3D applications and equivariant diffusion.

This proof is the site’s reference for the equivariance of EGNN: Geometric Data, ch. 7, and Advanced GNN, 8.1, recall it.

The EGNN layer in PyTorch, with its unit test A dense version of Proposition 8.3, with all pairs in the coordinate update and C = 1/(n-1). The test rotates or reflects, translates and permutes the input at once, using the permutation action (\Pi X, \Pi A \Pi^\top) of Definition 2.1.

import torch, torch.nn as nn

class EGNNLayer(nn.Module):                      # Proposition 8.3, dense version
    def __init__(self, d, hidden=64):
        super().__init__()
        mlp = lambda i, o: nn.Sequential(nn.Linear(i, hidden), nn.SiLU(), nn.Linear(hidden, o))
        self.phi_e, self.phi_x, self.phi_h = mlp(2 * d + 1, hidden), mlp(hidden, 1), mlp(d + hidden, d)

    def forward(self, h, x, A):                  # h: n x d, x: n x 3, A: n x n adjacency
        n = h.shape[0]
        diff = x[:, None, :] - x[None, :, :]      # diff[v, u] = x_v - x_u
        pair = torch.cat([h[:, None].expand(n, n, -1), h[None, :].expand(n, n, -1),
                          (diff ** 2).sum(-1, keepdim=True)], -1)
        m = self.phi_e(pair)                      # m[v, u] = phi_e(h_v, h_u, |x_v - x_u|^2)
        off = 1 - torch.eye(n, dtype=x.dtype)     # all u != v
        x_new = x + (diff * self.phi_x(m) * off[..., None]).sum(1) / (n - 1)
        h_new = self.phi_h(torch.cat([h, (A[..., None] * m).sum(1)], -1))
        return h_new, x_new

def test_egnn(n=8, d=5):
    torch.manual_seed(0)
    layer, dt = EGNNLayer(d).double(), torch.double
    h, x = torch.randn(n, d, dtype=dt), torch.randn(n, 3, dtype=dt)
    A = torch.triu((torch.rand(n, n) < 0.4).to(dt), 1); A = A + A.T
    Q, _ = torch.linalg.qr(torch.randn(3, 3, dtype=dt))           # random orthogonal matrix
    t, Pi = torch.randn(3, dtype=dt), torch.eye(n, dtype=dt)[torch.randperm(n)]
    h1, x1 = layer(h, x, A)
    h2, x2 = layer(Pi @ h, (Pi @ x) @ Q.T + t, Pi @ A @ Pi.T)      # move and renumber
    assert torch.allclose(h2, Pi @ h1, atol=1e-10)                 # features: invariant
    assert torch.allclose(x2, (Pi @ x1) @ Q.T + t, atol=1e-10)     # coordinates: equivariant

test_egnn()

The test passes to rounding error. Fed the raw coordinates as extra node features, the same layer fails it, with errors of order 0.1 to 1 (Exercise 14).

Example 8.4 — What a rotation changes, and what it does not A water molecule: O at (0, 0, 0), H_1 at (0.96, 0, 0), H_2 at (-0.24, 0.93, 0) (Å).

  • Distances: O–H_1 = 0.96, O–H_2 = \sqrt{0.0576 + 0.8649} \approx 0.96, H_1–H_2 = \sqrt{1.2^2 + 0.93^2} \approx 1.52.
  • The H–O–H angle is \arccos\big(\frac{-0.2304}{0.96 \cdot 0.9605}\big) \approx 104.5° .
  • Rotate by 90° about the z-axis, (x, y, z) \mapsto (-y, x, z): H_1 \mapsto (0, 0.96, 0), H_2 \mapsto (-0.93, -0.24, 0).

Every coordinate changed, yet the three distances (H_1–H_2: \sqrt{0.93^2 + 1.2^2} \approx 1.52) and the angle are identical, so an energy model built on them returns the same value, and an EGNN’s predicted positions rotate with the molecule.

Applications in biomedicine

  • Molecular property prediction: QM9 (about 134k small molecules, 12 quantum-chemical targets) and ogbg-molhiv (ch. 7) for graph regression and classification.
  • Machine-learned force fields: forces are -\nabla_x E, automatically equivariant when the energy model E is invariant.
  • Proteins: AlphaFold 2’s structure module reasons over residue frames with invariant point attention; RFdiffusion generates protein backbones by diffusion over residue frames; DiffDock predicts how a drug binds to a protein by diffusion over ligand poses.
  • Biomedical knowledge graphs: drug repurposing as link prediction (ch. 6) on heterogeneous graphs linking drugs, genes and diseases (Hetionet); protein–protein interaction networks for node classification.

Generation of molecules is treated in ch. 9.

Benchmarking, challenges and future directions The last lecture of the official programme steps back.

Benchmarking: results on the small Planetoid splits change with the random split (Shchur et al., 2018), and fair protocols showed that many graph-classification gains vanish against structure-agnostic baselines (Errica et al., 2020); hence standardized suites — Benchmarking GNNs (Dwivedi et al.), OGB (ch. 7), the Long Range Graph Benchmark (Dwivedi et al., 2022) — and leakage-free protocols (Example 8.1).

Open challenges: expressivity beyond 1-WL (Example 2.6), over-smoothing and over-squashing (Theorem 5.3), heterophily (Definition 5.4), scale (ch. 7), distribution shift between training and deployment graphs, time (Definition 5.6) and geometry (Definition 8.2).

Directions: graph transformers, pretrained “graph foundation models” that transfer across graphs, and the coupling with LLMs of ch. 10.

9. Graph generation

The previous chapters analyzed given graphs; this chapter learns to produce new ones — molecules with a target property, synthetic networks for testing — which raises difficulties that images and text do not have.

Problem Sample G \sim p_\theta(G) where p is learned over a family of graphs (active molecules, road networks…) — possibly conditioned on a target property (“generate a molecule with this activity”) or on text (text-to-graph). This is the “Generative AI” side of the title of the master.

Three difficulties specific to graphs: (i) variable size (n random); (ii) discrete outputs (atom types, edge types); (iii) a space quotiented by isomorphism — two permuted adjacencies are the same graph: one needs exchangeable models (theory below).

9.1 — The limiting model: graphons and exchangeability A graphon is a measurable function W : [0,1]^2 \to [0,1]. Given W and n:

  1. draw x_i \sim \mathcal{U}([0,1]);
  2. then draw each edge (i, j) independently with probability W(x_i, x_j) — a graph G_n on n vertices.

Two results justify the object. The Aldous-Hoover theorem states that every infinite exchangeable random graph (distribution invariant under permutation of the vertices) is a mixture of such graphon models; and Lovász and Szegedy showed that every convergent sequence of dense graphs has a graphon as its limit for the cut metric (Lovász, Large Networks and Graph Limits, 2012).

The learning connection:

  • estimation: estimating W from a large graph = approximating it by a step function constant per block. Partition the n vertices into k blocks of sizes n_b, and set \hat W = \frac{e_{bb'}}{n_b n_{b'}} \quad \text{on the block } (b, b') (empirical densities); the partition is the problem — and SBM/clustering solves it;
  • generation: a learned graph model implicitly targets a \hat W (large molecules: large n, structured target distribution);
  • theory of deep generative models of graphs: the exchangeable architectures (invariant to permutations of the nodes) are those that approximate graphons — this is the consistency criterion of the models below.

9.2 — Classical random models: ER and SBM (with the math)

  • Erdős-Rényi G(n, p): all the edges iid with probability p; degrees \sim \mathrm{Bin}(n-1, p), no community; threshold phenomena (at \frac{\log n}{n}) for connectivity — the “null” reference against which to test structure (Refresher Statistics module);

  • SBM (Holland et al., 1983): each node has a latent block z_i \in \{1..k\} (uniform), and P(A_{ij} = 1 \mid z_i = a, z_j = b) = B_{ab}.

    Likelihood (with n_{ab} = observed edges between blocks a, b): \log P(A \mid z, B) = \sum_{a,b} n_{ab} \log B_{ab} + (n_a n_b - n_{ab}) \log(1 - B_{ab}); inference by maximum of likelihood (EM) or Bayesian (MCMC sampling).

    Detectability: for two symmetric blocks, below the Kesten-Stigum threshold no algorithm recovers the blocks better than chance; spectral methods built on the non-backtracking matrix reach this threshold, whereas the plain Laplacian spectral clustering of ch. 4 degrades on very sparse graphs.

    Generation: sample z then A; DCSBM variant (corrected degrees).

    The SBM is used in both directions: generating realistic synthetic graphs (benefit: total control) and inferring the blocks (statistically grounded clustering). Flat SBM inference also has a resolution limit, about \sqrt{n} detectable blocks (Peixoto, 2013); its nested, hierarchical version raises it to about n / \log n (Peixoto, 2014), which the modularity of ch. 0 cannot do. Topic modeling by SBM (TopSBM, Gerlach et al., 2018) treats a document-term corpus as a bipartite SBM — the “statistical” generalization of the Graph of Words of ch. 11.

9.3 — Graph VAEs: GraphVAE and NeVAE GraphVAE (Simonovsky & Komodakis, 2018): a GNN encoder, decoder in one block \hat A, \hat X, \hat E (full adjacency); the mismatch of the outputs to the ground truth requires a matching matrix (Hungarian matching) — the node ordering problem is paid for here (cf. GOAT, ch. 11).

NeVAE (Samanta et al., AAAI 2019): a granular VAE designed for chemistry:

  1. sparse encoder: one embedding per atom (no full adjacency — memory \mathcal{O}(n) instead of \mathcal{O}(n^2)), MPNN messages between atoms;
  2. sequential decoder constrained by valence: at each step, a new atom is added and its bonds drawn by probability heads conditioned on the remaining valence — a carbon cannot receive 5 bonds; aromaticity is handled by dedicated heads;
  3. noise correction: local resampling of the invalid bonds during training — the penalty of forbidden solutions is softened;
  4. result: chemical validity > 90% before post-processing, where unconstrained GraphVAEs produce very few.

Moral: injecting domain knowledge (valence) into the architecture beats the post-processing (RDKit sanitization) — reused by all the following methods.

9.4 — Autoregressive models: GraphRNN (You et al., 2018) Generating a graph = generating a sequence. Order the nodes 1, 2, \dots (any order: the model must be robust to this choice — in practice canonical BFS orders); the graph is then the sequence of adjacency rows S^i = (A_{i1}, \dots, A_{i,i-1}) \in \{0,1\}^{i-1}.

Two levels: \text{node level: } h_i = \mathrm{RNN}_{node}(h_{i-1}, s_i), \qquad \text{edge level: } P(S^i \mid h_i) = \prod_{j < i} \mathrm{RNN}_{edge}(s_{ij}), where the state h_i conditions the edge RNN which emits S^i bit by bit (Bernoulli categorical per position); training maximizes the sequential likelihood (teacher forcing).

Properties: exchangeability approximated by the use of BFS orders (the prefix is invariant to intra-level permutations); complexity \mathcal{O}(n) decoding steps, \mathcal{O}(n) per step → quadratic — very reasonable for n \leq 100.

Limits: sensitivity to order (aromatic rings depend on the starting point); conditioning on properties is awkward (hence the models below). This “sequentialize the graph” scheme is exactly that of the LLM on text — the text-to-graph convergence is natural (ch. 10).

9.5 — Discrete diffusion: DiGress (Vignac et al., 2023) The molecular state of the art 2023-2026 transposes diffusion to categories (atom types, bond types).

Recap — continuous diffusion (DDPM), from Deep Learning P1 9.4, Deep Learning P2 7.3 or Multimodal GenAI ch. 3:

  1. a schedule \beta_t, with \alpha_t = 1 - \beta_t and \bar\alpha_t = \prod_{s \leq t} \alpha_s;
  2. noising in closed form, with \varepsilon \sim \mathcal{N}(0, I): x_t = \sqrt{\bar\alpha_t}\, x_0 + \sqrt{1 - \bar\alpha_t}\, \varepsilon;
  3. training: a network \varepsilon_\theta(x_t, t) regresses the noise by least squares;
  4. sampling: from x_T \sim \mathcal{N}(0, I), step back with the posterior q(x_{t-1} \mid x_t, x_0), the unknown x_0 replaced by its prediction;
  5. DiGress keeps the frame of steps 2–4: closed-form noising, a trained denoiser, posterior sampling. It replaces Gaussian noise by categorical resampling, and the noise regression by a prediction of the clean graph.

Forward process (noising), with one-hot row vectors: at each step, each node and edge type is re-drawn q(X_t \mid X_{t-1}) = \mathrm{Cat}\big(X_t;\ X_{t-1} Q^X_t\big), \qquad q(E_t \mid E_{t-1}) = \mathrm{Cat}\big(E_t;\ E_{t-1} Q^E_t\big), where Q^X_t, Q^E_t are row-stochastic transition matrices (one row = law of the new type given the old one). In closed form, q(x_t \mid x_0) = \mathrm{Cat}(x_t;\ x_0 \bar Q_t) with \bar Q_t = Q_1 \cdots Q_t. After T steps, the stationary law is the marginal of the dataset (distribution of the atoms/bonds).

The posterior, by Bayes’ rule on one node or one edge (D3PM, Austin et al., 2021): q(x_{t-1} \mid x_t, x_0) = \mathrm{Cat}\Big(x_{t-1};\ \frac{x_t Q_t^\top \odot x_0 \bar Q_{t-1}}{x_0 \bar Q_t\, x_t^\top}\Big). Read it factor by factor: x_t Q_t^\top is q(x_t \mid x_{t-1}) as a function of x_{t-1}, x_0 \bar Q_{t-1} is q(x_{t-1} \mid x_0), and the denominator is q(x_t \mid x_0).

Backward process (denoising): a graph transformer predicts, from (X_t, E_t), the probabilities \hat p^X_i and \hat p^E_{ij} of the clean types. It is trained by cross-entropy, \mathcal{L} = \mathbb{E}_{t,\, G_0,\, G_t} \Big[\sum_i \mathrm{CE}\big(x_i, \hat p^X_i\big) + \lambda_E \sum_{i,j} \mathrm{CE}\big(e_{ij}, \hat p^E_{ij}\big)\Big], with \lambda_E > 0 weighting the edges. A reverse step averages the posterior over the predicted clean type: p_\theta(x_{t-1} \mid G_t) = \sum_{x} q(x_{t-1} \mid x_t, x_0 = x)\, \hat p(x). Since edge types include “no edge”, edges are added and removed along the way.

Three winning choices: extra input features recomputed at each step (cycle counts, spectral features, and valency for molecules), which compensate for the limited expressivity of message passing; guaranteed exchangeability — the model never sees a node order (unlike GraphRNN); conditioning by graph (inpainting): freeze a skeleton and generate the rest — “target molecule” conditional generation.

3D cousin: EDM/EDT (equivariant positions — M2, ch. 8). The team’s NGG paper (ch. 11) transposes this recipe into latent space to condition on graph features.

9.6 — Evaluating generated graphs: distributional fidelity A generator is not graded image by image but distribution against distribution:

  • validity / uniqueness / novelty (chemistry): % of syntactically valid, distinct molecules, absent from training — a model that memorizes has a novelty of 0;
  • structural MMDs: maximum mean discrepancy \mathrm{MMD}^2 = \big\| \mathbb{E}_{G \sim p}[\phi(G)] - \mathbb{E}_{G \sim q}[\phi(G)] \big\|^2 with \phi = degree histograms, clustering coefficients, motif/orbit counts (the triangles of ch. 0!) — the remark: these features are exactly what 1-WL does not always capture (M2, ch. 2);
  • FCD (Fréchet ChemNet Distance): Fréchet distance between the Gaussians of the ChemNet embeddings of the generated vs real molecules — the exact analogue of the FID of images (Multimodal GenAI module);
  • OT distances: comparing graphs without node correspondence = Gromov-Wasserstein optimal transport (Optimal Transport, ch. 5). This is a different object from the MMDs above, which compare distributions of graph statistics. For samples in one common space, the bridge between the two families is the Sinkhorn divergence, which interpolates between a Wasserstein distance (small regularization) and an MMD (large regularization; Feydy et al., 2019).

Fréchet distance (FID, FCD) Fit a Gaussian to each set of embeddings, \mathcal{N}(\mu_1, \Sigma_1) for the real samples and \mathcal{N}(\mu_2, \Sigma_2) for the generated ones: \mathrm{FD} = \|\mu_1 - \mu_2\|^2 + \mathrm{Tr}\big(\Sigma_1 + \Sigma_2 - 2\,(\Sigma_1 \Sigma_2)^{1/2}\big). It is the squared 2-Wasserstein distance between the two Gaussians: 0 when means and covariances match, and sensitive both to a shift of the mean (quality) and to a collapse of the covariance (diversity). FCD uses the penultimate layer of ChemNet, FID that of Inception.

9.7 — Conditional generation: the real industrial product Rank by target property (solubility, docking), condition on text (“an antibiotic against X”), on a skeleton (R-group optimization), on a partial graph (inpainting).

Three mechanisms: (i) input conditioning (concat of the descriptor — NGG); (ii) gradient guidance through a property predictor during sampling (the classifier guidance of images); (iii) search in latent space (Bayesian optimization — the classic QSAR pipeline).

This is where the GNN × LLM encounter is most fertile (ch. 10): the LLM proposes, the GNN evaluates, the loop optimizes.

10. Graphs × LLMs: GraphRAG and the hybrid

A large language model answers fluently but does not know the private documents of a company, and it loses track of relations spread across many of them. GraphRAG addresses both problems: it builds a knowledge graph from the documents with the LLM itself, then uses the graph — its entities, relations and communities — to retrieve what the model needs in order to answer.

10.1 — The complete industrial GraphRAG pipeline (after Edge et al., 2024)

  1. ingestion: splitting the corpus into chunks; LLM extraction of the entities (NER) and relations (typed relation extraction, cf. NLP module) in the triplet format (subject, relation, object, source passage); entity resolution (aliases); the graph is built incrementally — each edge keeps its source or sources;
  2. communities: community detection (Leiden — a Louvain variant, ch. 0) on the entity graph; for each community (at each level of the hierarchy), an LLM summarizes the entities, relations and themes; the summaries aggregate bottom-up;
  3. hybrid index: the graph plus a vector index of the chunks and the summaries (classic RAG remains useful for local queries);
  4. global queries (“what are the major themes of the corpus?”): map-reduce over the community summaries — each community answers partially, an LLM synthesizes; local queries (“who works with whom on X?”): expanding the neighborhood of entity X (linked entities, source chunks) then a grounded answer;
  5. evaluation: comparison of vector-text RAG vs GraphRAG on the completeness and diversity of the answers; cost: LLM ingestion is expensive — amortized over thousands of queries.

LLGA reading: each stage is an object of the course — clustering (ch. 0), link prediction for the completion of the KG (ch. 6), embeddings for the vector index (ch. 3).

10.2 — Making the LLM reason over the graph: encoding and pseudo-code

  • serialization: describing the (sub)graph as text (edge lists, adjacency, incidences); the NLGraph benchmark (Wang et al., 2023) shows that LLMs fail on elementary tasks (cycles, connectivity, shortest paths) as soon as size grows, even few-shot (worked examples in the prompt, see the few-shot box of NLP, ch. 7); the “Talk like a Graph” study (Fatemi et al., 2024) compares the encodings — none dominates everywhere;

  • pseudo-code prompting (Skianis, Nikolentzos & Vazirgiannis, 2024 — the master’s team): give the LLM the algorithm in pseudo-code rather than a description in natural language;

    input : edge list E, node s
    visited = {s} ; stack = [s]
    while stack not empty :
        v = stack.pop()
        for u in neighbors(v) in E :
            if u not in visited : visited.add(u) ; stack.push(u)
    output : visited   # connected component of s

    the LLM executes the trace — systematic gains over natural instructions, across all LLM families; the lesson: on discrete structures, the programming language is a better “prompt” than natural language;

  • GNN + LLM hybrids: the GNN encodes the structure (ch. 5) and injects: (a) soft tokens into the prompt (projecting the GNN embeddings into the LLM space); (b) structural recall — the GNN retrieves the connected passages (like the KG of 10.1, but learned); (c) cross-distillation — the annotated LLM trains the GNN, the GNN filters the LLM’s hallucinations.

    This three-way taxonomy (soft tokens, structural recall, cross-distillation) is the reference for the whole site: Advanced GNN 8.3 and Advanced Topics in LLMs 8.3 map their categories onto it.

10.3 — GraphRAG limits and hygiene

  • extraction hallucinates (non-existent entities): control with a double pass and anchoring on chunks;
  • the graph is an approximation — queries depend on its quality; harden with KGC (ch. 6) before querying;
  • the ingestion cost vs the gain on relational queries: for a single-document FAQ, vector RAG is enough; GraphRAG pays off when the questions are multi-hop, aggregative or global;
  • privacy: the graph aggregates scattered facts — re-identification risk (M2, ch. 7).

10.4 — GraphRAG, worked: from paragraphs to cited answers The pipeline of 10.1, written out once in about 60 lines of Python. The LLM (llm) and the sentence encoder (embed) are parameters; the rest is NetworkX and NumPy.

  1. Extraction: one prompt per chunk, with a JSON schema. A triple whose evidence is not found verbatim in its chunk is dropped, which is the anchoring rule of 10.3.
  2. Entity resolution: two names are merged when their normalized strings are close (ratio ≥ 0.9) or their embeddings are (cosine ≥ 0.9).
  3. Communities: Leiden on the entity graph; the summaries of 10.1 are then written community by community.
  4. Local search: the seed entities are those closest to the question. The k-hop neighborhood of the seeds selects the candidate chunks, and each chunk is scored by the relations it supports, discounted by their distance to the seeds.
  5. Global search: map-reduce over the community summaries.
  6. Evaluation: EM and F1 after normalization, supporting-paragraph recall, citation faithfulness, and the tokens and latency of every call. Here a citation is faithful when the cited chunk was retrieved and contains the answer, a cheap proxy for the NLI check of ALCE (Gao et al., 2023).
import json, re, time, difflib, unicodedata, collections
import numpy as np, networkx as nx

FIELDS = ("subject", "relation", "object", "evidence")
SCHEMA = {"type": "array", "items": {"type": "object", "required": list(FIELDS),
          "properties": {f: {"type": "string"} for f in FIELDS}}}
PROMPT = ("Extract every factual triple stated in the passage. Reply with JSON only, valid "
          "against this schema: {schema}. Copy 'evidence' verbatim from the passage.\n"
          "Passage [{cid}]: {text}")

class Metered:                                   # tokens and latency of every LLM call
    def __init__(self, llm): self.llm, self.tokens, self.seconds = llm, 0, 0.0
    def __call__(self, prompt):
        t0 = time.perf_counter(); out = self.llm(prompt)
        self.seconds += time.perf_counter() - t0
        self.tokens += (len(prompt) + len(out)) // 4      # about 4 characters per token
        return out

def extract(llm, cid, text):                     # 1. triples, anchored on their chunk
    out = json.loads(llm(PROMPT.format(schema=json.dumps(SCHEMA), cid=cid, text=text)))
    return [(t["subject"], t["relation"], t["object"], cid)
            for t in out if t["evidence"] in text]

def norm(s):
    s = unicodedata.normalize("NFKD", s).encode("ascii", "ignore").decode()
    return " ".join(re.sub(r"[^\w\s]", " ", s.lower()).split())

def resolve(names, embed, tau_str=0.9, tau_emb=0.9):     # 2. entity resolution
    canon, alias = [], {}
    for n in sorted(set(names), key=lambda n: (-len(n), n)):
        alias[n] = next((c for c in canon
                         if difflib.SequenceMatcher(None, norm(n), norm(c)).ratio() >= tau_str
                         or embed(n) @ embed(c) >= tau_emb), n)
        if alias[n] == n: canon.append(n)
    return alias

def build_graph(triples, alias):                 # one edge per entity pair, with its chunks
    G = nx.Graph()
    for s, r, o, cid in triples:
        u, v = alias[s], alias[o]
        if not G.has_edge(u, v): G.add_edge(u, v, relation=r, chunks=set())
        G[u][v]["chunks"].add(cid)
    return G

def communities(G, seed=0):                      # 3. Leiden (NetworkX 3.7, or leidenalg)
    return nx.community.leiden_communities(G, metric="modularity", seed=seed)

def local_search(G, q, embed, n_seeds=1, k=2, top=2):    # 4. seeds, k hops, chunk ranking
    ents = list(G)
    sims = np.array([embed(e) @ embed(q) for e in ents])
    hop = {}
    for s in [ents[i] for i in np.argsort(-sims)[:n_seeds]]:
        for v, d in nx.single_source_shortest_path_length(G, s, cutoff=k).items():
            hop[v] = min(d, hop.get(v, k))
    score = collections.Counter()
    for u, v, a in G.subgraph(hop).edges(data=True):
        for c in a["chunks"]: score[c] += 1 / (1 + min(hop[u], hop[v]))
    return [c for c, _ in score.most_common(top)]

def global_search(llm, q, summaries, top=3):     # 5. map-reduce over community summaries
    maps = [json.loads(llm(f"Answer '{q}' from this community summary only. Reply as "
                           f'JSON {{"answer": str, "score": 0-100}}.\n{s}')) for s in summaries]
    best = sorted(maps, key=lambda m: -m["score"])[:top]
    return llm(f"Merge these partial answers to '{q}' into one answer: {json.dumps(best)}")

def em_f1(pred, gold):                           # 6. evaluation, SQuAD-style normalization
    p, g = ([w for w in norm(s).split() if w not in ("a", "an", "the")] for s in (pred, gold))
    common = sum((collections.Counter(p) & collections.Counter(g)).values())
    return float(p == g), (2 * common / (len(p) + len(g)) if common else 0.0)

def support_recall(retrieved, gold):
    return len(set(retrieved) & set(gold)) / len(gold)

def citation_faithfulness(cited, retrieved, answer, chunks):
    return np.mean([c in retrieved and norm(answer) in norm(chunks[c]) for c in cited])

A toy corpus lets every step be checked by hand. It describes three projects of ten entities each (the project, six people, two datasets, a client), with a memo of cross-project facts that also spells three names differently. The triples are given, as if extracted.

import zlib

def embed(s, dim=512):                           # toy encoder: hashed character trigrams
    s, v = f"  {norm(s)} ", np.zeros(dim)
    for i in range(len(s) - 2): v[zlib.crc32(s[i:i + 3].encode()) % dim] += 1
    return v / np.linalg.norm(v)

P = {"Atlas":  ("Ana Ben Chen Dina Eli Fay", "TaxiZones FleetLogs", "Rhone Freight"),
     "Boreal": ("Gus Hana Ivo Jade Kai Lea", "ClaimsDB PolicyText", "Helios Bank"),
     "Cirrus": ("Mia Noor Omar Pia Quin Rui", "ScanSet TrialNotes", "Medina Clinic")}
T = [("Fay", "works on", "Boreal", "memo"), ("Lea", "works on", "Cirrus", "memo"),
     ("Cirrus", "uses", "Policy Text", "memo"), ("Atlas", "uses", "Taxi Zones", "memo"),
     ("Rhône Freight", "pays", "Atlas", "memo")]
for p, (team, data, client) in P.items():
    m = team.split()
    T += [(x, "works on", p, p + "/team") for x in m] + [(m[1], "reports to", m[0], p + "/team")]
    T += [(p, "uses", d, p + "/delivery") for d in data.split()]
    T += [(p, "delivers to", client, p + "/delivery")]
chunks = collections.defaultdict(str)
for s, r, o, c in T: chunks[c] += f"{s} {r} {o}. "

G = build_graph(T, resolve([x for s, _, o, _ in T for x in (s, o)], embed))
C = communities(G)
print(G.number_of_nodes(), G.number_of_edges(), len(C), nx.community.modularity(G, C))
q, gold = "Which client receives the work of Gus?", ["Boreal/team", "Boreal/delivery"]
top = local_search(G, q, embed)
print(top, support_recall(top, gold), em_f1("Helios", "Helios Bank"))

What the toy shows (NetworkX 3.7):

  • Resolution merges the three variant spellings, leaving 30 entities and 33 relations.
  • Leiden returns one community per project, with modularity 0.57. Each of the three entities shared by two projects lands in one of them.
  • The question needs two hops, Gus → Boreal → Helios Bank, spread over two chunks. Local search returns exactly these two chunks, a support recall of 1.0.
  • Ranking the chunks by their similarity to the question alone, with the same toy encoder, returns two Cirrus chunks instead (recall 0). The chunk that names Helios Bank never mentions Gus; only the graph links the two.
  • The partial answer “Helios” scores EM 0 and F1 0.67.

Final lab — mini-GraphRAG on 2WikiMultiHopQA A fixed setting, so that the numbers of all groups can be compared.

  1. Data: the first 200 questions of the 2WikiMultiHopQA dev split (Ho et al., 2020). The paragraphs given with these questions form the corpus, and their supporting facts are the gold.
  2. Baselines: BM25 and dense retrieval of the top 5 paragraphs, each passed to the same LLM reader. They are the minimal RAG of NLP 7.4, a prerequisite of this lab.
  3. GraphRAG: the pipeline of 10.4 (extraction with the JSON schema, entity resolution, Leiden, local search), with pseudo-code prompting (10.2) for path questions.
  4. Protocol: one open 7–8B instruct model for every method, temperature 0, every call cached.
  5. Report, per question type (comparison, inference, compositional, bridge comparison): EM and F1, supporting-paragraph recall at 5, citation faithfulness, tokens and latency per question.

Deliverable: report + reproducible notebook. The capstone Y1.1 starts from it.

11. Research at DaSciM (Lutzeyer, Vazirgiannis)

The LLGA master is taught by the DaSciM laboratory (Data Science and Mining, LIX, École Polytechnique): M. Vazirgiannis, J. Lutzeyer and their PhD students. This chapter presents four research directions of the laboratory in direct connection with the program; the papers are to be read and presented as a project — this is the module’s “paper” exercise (and the daily bread of M2, ch. 9).

11.1 — Graph of Words: from document to graph (Rousseau & Vazirgiannis; Tixier, Malliaros & Vazirgiannis) The “bag-of-words” representation ignores the order of words; the graph of words partially restores it:

  1. construction: sliding window of size w (typically 2-10); nodes = unique terms (weighted by frequency); edge (u, v) if u and v co-occur in a window, weighted by the number of co-occurrences; a document = one graph;
  2. keywords: extract the “central” nodes of the graph; Rousseau & Vazirgiannis (ECIR 2015) keep the main k-core (the maximal k-core: the largest subgraph with min degree \geq k), Tixier et al. (EMNLP 2016) rank the words by degeneracy (keywords lie among the influential nodes of the dense cores, not among those of highest eigenvector centrality);
  3. document classification: a corpus = a set of graphs → graph classification (ch. 2); moving from bag-of-words → graph-of-words enriches the co-occurrence features and improves the classic text classifiers.

Positioning: this is the symmetric twin of ch. 3 — DeepWalk applies word2vec to graphs, Graph of Words applies graphs to text. Posterity: graph-of-words + graph CNNs for hierarchical classification; topic modeling by bipartite SBM (TopSBM, Gerlach et al., 2018); and the GraphRAG indexes (ch. 10) that index entities and co-occurrences — an enterprise graph of words.

11.2 — Path Neural Networks (Michel, Nikolentzos, Lutzeyer & Vazirgiannis, ICML 2023) Idea: the GNN layer of ch. 5 aggregates walks of length 1 (the neighbors); paths of length \ell carry more structural information.

The path operator: for each node v, consider the set \mathcal{P}_v^{(\ell)} of simple paths of length \ell starting from v; each path p = (v, u_1, \dots, u_\ell) is encoded by an RNN (GRU): m_p = \mathrm{GRU}\big(h_{u_\ell}^{(\ell)}, \mathrm{GRU}(\dots \mathrm{GRU}(h_{u_1}^{(0)}, h_v^{(0)})\dots)\big), \qquad h_v^{(\ell)} = \mathrm{AGG}\big(\{m_p : p \in \mathcal{P}_v^{(\ell)}\}\big).

Three variants depending on \mathcal{P}_v: shortest paths (PathNN-s), random walks (PathNN-r), paths sampled in the neighborhood (PathNN-n) — sampling bounds the cost, since the number of simple paths grows exponentially.

Results: accuracies greater than or equal to the canonical GNNs on the classification benchmarks (nodes and graphs, including ZINC for molecules), with controlled complexity; the expressivity analysis (what the paths see that the walks miss — cycles, distances) is developed in M2, ch. 2 and 9.

Positioning in the course: the “natural” generalization of ch. 3 (DeepWalk walks) and of ch. 5 (1-hop neighborhoods).

11.3 — Graph Ordering Attention Networks (Chatzianastasis, Lutzeyer, Dasoulas & Vazirgiannis, AAAI 2023) — J. Lutzeyer’s work on ordering and expressivity Invariant aggregators (sum/mean/max) throw away all ordering information — but the local order of the neighbors carries signal (think of a text: the bag of words loses the syntax). GOAT learns a local order:

  1. an attention orders the neighbors of v (scores learned on (h_v, h_u), sorting);
  2. the ordered sequence is processed by an RNN — a local sequence model, hence strictly more expressive than invariant aggregation;
  3. the GOAT levels (order at increasing radius) compose layer after layer.

The double positioning: in expressivity, GOAT distinguishes graphs that 1-WL confuses (joins M2, ch. 2); in generation, the order choice is THE Gordian knot of autoregressive models (GraphRNN, ch. 9.4; GraphVAE, ch. 9.3) — learning the order rather than suffering it is a transverse contribution. It is also an elegant answer to the GraphSAGE-LSTM question of ch. 5 (the neighborhood there was ordered randomly).

11.4 — Two recent bridges to GenAI: NGG and pseudo-code prompting

  • NGG — Neural Graph Generator (Evdaimon et al., with Nikolentzos & Vazirgiannis, 2024): latent diffusion conditioned on graph features (spectrum, degrees…): a GNN encoder compresses graphs into latent vectors, a diffusion model learns the distribution and the conditioning there; one then generates graphs exhibiting the requested features — ch. 9.5 transposed into latent space, with the spectrum (ch. 4) as descriptor; applications: synthetic data, anonymization, distributional anomaly detection;
  • Pseudo-code prompting (Skianis, Nikolentzos & Vazirgiannis, 2024): make the LLMs reason about graphs (connected components, shortest paths…) by giving them instructions in pseudo-code rather than in natural language — systematic gains across all the LLM sizes tested; detailed in ch. 10.

These four directions (text↔︎graph, paths, order, generation/diffusion, LLM) cover exactly the map of the master — M2, ch. 9, develops them on the theory side.

Exercises

  1. ★ Triangles by the trace. From \mathrm{tr}(A^3), count the triangles of the “two K_4s sharing an edge” graph. Generalize: what does \mathrm{tr}(A^4) count?

    Solution: each K_4 contains \binom{4}{3} = 4 triangles, and no triangle belongs to both (it would need a third common vertex); total 8, hence \mathrm{tr}(A^3) = 48.

    \mathrm{tr}(A^4) counts the closed walks of length 4 (squares, back-and-forths…) — not only the squares; one must subtract the degree contributions (formula with \sum_v d_v^2 for the back-and-forths).

  2. ★ node2vec. Simulate walks with (p, q) = (1, 1), (0.25, 4), (4, 0.25) on the karate club graph (code 3.4); project the embeddings in 2D (t-SNE) and relate p, q to the BFS/DFS strategies.

    Expected solution: (p,q) = (0.25, 4) — strong return, weak exploration → BFS, embeddings grouped by role (the two hubs “Mr. Hi” and “Officer” move closer); (4, 0.25) → DFS, clustering by factions (homophily), higher NMI for the split task; (1,1) intermediate.

  3. ★ NetMF by hand. For the triangle K_3, compute M = \log\big(\frac{\mathrm{vol}}{kT}(\sum_{r=1}^T P^r) D^{-1}\big) with window T = 2 and k = 1 negative per pair, and interpret the signs.

    Solution: the adjacency is J - I (J = all-ones matrix) and every degree is 2, so P = \frac12 (J - I) and, using J^2 = 3J, P^2 = \frac14 (J + I).

    Hence \sum_{r \leq 2} P^r = \frac14 (3J - I), with \frac12 on the diagonal and \frac34 off it. With \mathrm{vol} = 6 and D^{-1} = \frac12 I: M = \log\big(\frac{6}{2} \cdot \frac14 (3J - I) \cdot \frac12\big) = \log\big(\frac38 (3J - I)\big) \quad \text{entrywise}, i.e. \log\frac98 > 0 off the diagonal and \log\frac34 < 0 on it.

    Reading: two distinct vertices co-occur in the walks a little more than the degree baseline predicts, a vertex with itself less; all the off-diagonal entries are equal because the triangle has no structure to reveal — DeepWalk on a structureless graph can only reflect the degrees; conclusion: the target matrix is the signal.

  4. ★ GCN by hand. Implement a GCN layer without PyG (compute \tilde A, \tilde D), check the equality of the outputs with GCNConv at fixed weights, then measure the over-smoothing: mean cosine similarity of the embeddings as a function of the number of layers (1 to 10). Solution (PyG-guided):

    import torch, torch_geometric
    from torch_geometric.datasets import Planetoid
    data = Planetoid(root="/tmp/Cora", name="Cora")[0]
    A = torch.zeros(2708, 2708)
    A[data.edge_index[0], data.edge_index[1]] = 1.0
    A_tilde = A + torch.eye(2708)
    D_inv_sqrt = A_tilde.sum(1).pow(-0.5).diag()
    A_hat = D_inv_sqrt @ A_tilde @ D_inv_sqrt        # renormalized propagator
    H = data.x
    for L in range(1, 11):
        H = A_hat @ H                                 # pure propagation (thm. 5.3)
        Hn = torch.nn.functional.normalize(H, dim=1)  # unit rows
        cos = Hn @ Hn.T                               # 2708 x 2708, not 2708 x 2708 x 1433
        print(L, ((cos.sum() - 2708) / (2708 * 2707)).item())
    # 0.15 at L = 1, 0.52 at L = 10, 0.82 at L = 64; the limit is 0.89, not 1

    Reading: the mean cosine rises steadily, which is over-smoothing, but it does not tend to 1. Theorem 5.3 assumes a connected regular graph, and Cora has 78 connected components (the largest has 2,485 nodes). On each component C, \hat A^L tends to the projection onto \tilde D^{1/2} \mathbf{1}_C: rows become parallel inside a component, not across components.

  5. ★ Spectral clustering. Apply algorithm 4.4 (k = 2) to the “two K_5s + bridge” graph, validating the Fiedler vector of example 4.3; compare Ncut and RatioCut for the found partition.

    Solution: signs of the vector (1,1,1,1,0.70,-0.70,-1,-1,-1,-1) → exact partition.

    \mathrm{cut} = 1, RatioCut = \frac{1}{5} + \frac{1}{5} = 0.4; Ncut = \frac{1}{21} + \frac{1}{21} \approx 0.095 (each side has volume 4 \times 4 + 5 = 21).

    A cut isolating a single node removes at least 4 edges, hence a RatioCut of at least \frac{4}{1} + \frac{4}{9} \approx 4.4 — the weighting by size does the job.

  6. ★ Link prediction. On Cora: mask 10% of the edges, encode with a GAE (ch. 6), score the pairs by \sigma(z_u^\top z_v); evaluate the AUC against sampled negatives; compare GAE vs VGAE vs DeepWalk embeddings (ch. 3). Solution (PyG-guided):

    import torch.nn as nn
    from torch_geometric.nn import GCNConv
    from torch_geometric.utils import negative_sampling
    
    class GAE(nn.Module):
        def __init__(self, d_in, d_hid):
            super().__init__()
            self.e1, self.e2 = GCNConv(d_in, d_hid), GCNConv(d_hid, d_hid)
        def forward(self, x, ei):
            return self.e2(torch.relu(self.e1(x, ei)), ei)
    
    model, opt = GAE(1433, 64), None
    opt = torch.optim.Adam(model.parameters(), lr=0.01)
    # split: train_pos = 90% of the edges; test_pos = 10% + as many negatives
    for ep in range(200):
        Z = model(data.x, train_pos_ei)
        neg = negative_sampling(train_pos_ei, num_nodes=2708)
        ei_all = torch.cat([train_pos_ei, neg], dim=1)
        lbl = torch.cat([torch.ones(train_pos_ei.size(1)),
                         torch.zeros(neg.size(1))])
        score = (Z[ei_all[0]] * Z[ei_all[1]]).sum(-1)
        loss = nn.functional.binary_cross_entropy_with_logits(score, lbl)
        opt.zero_grad(); loss.backward(); opt.step()
    # AUC: rank the scores of the test edges and of fresh negatives

    Expected: AUC \approx 0.90–0.92.

  7. ★★ Laplacian. Show x^\top L x = \sum_{(u,v) \in E}(x_u - x_v)^2, then that \lambda_2 > 0 \iff connected. Compute the spectrum of the path and of the cycle.

    Solution (sketch): expand x^\top D x - x^\top A x = \sum_v d_v x_v^2 - 2\sum_{(u,v)} x_u x_v and group by edges.

    \lambda_2 = 0 is equivalent to the existence of a non-zero x \perp \mathbf{1} constant per component (the multiplicity computation of Definition 0.4), hence \lambda_2 > 0 \iff a single component.

    Path: 2(1 - \cos\frac{k\pi}{n}); cycle: 2(1 - \cos\frac{2k\pi}{n}).

  8. ★★ Permutation equivariance. Check that the GCN layer satisfies f(\Pi X, \Pi A \Pi^\top) = \Pi f(X, A) and interpret; show that a classic dense layer (MLP over concatenated features) does not satisfy it.

    Solution (sketch): \tilde D_{\Pi A \Pi^\top} = \Pi \tilde D \Pi^\top (the degrees follow the permutation), hence \tilde D_{\Pi A \Pi^\top}^{-1/2} (\Pi \tilde A \Pi^\top) \tilde D_{\Pi A \Pi^\top}^{-1/2}\, \Pi X = \Pi\, \tilde D^{-1/2} \tilde A \tilde D^{-1/2} X; a dense MLP over the concatenation [x_1 \| \dots \| x_n] applies different weights to each position — permuting the nodes changes the output other than through \Pi.

  9. ★★ GAT. Show that the memory complexity of the T-head attention is \mathcal{O}(T |E| F'), and that with self-loops GCN is obtained as a special case of uniform attention. How does GAT handle the irregular graphs that GCN normalizes poorly?

  10. ★★ Scale. Derive the bound 1 + s_L(1 + s_{L-1}(\dots)) of the NeighborSampler; for ogbn-arxiv (mean degrees \approx 7, max 200+), which fanout (s_1, s_2) do you recommend and why? Evaluate the accuracy gap vs full-batch on Cora while increasing the variance (fanouts (2,2), (5,5), (10,10)).

  11. ★★ Random generation. (a) After 9.2: implement ER and SBM (SBM: 4 blocks, B_{aa} = 0.8, B_{ab} = 0.05) and generate 500 graphs of each. Which minimal k of the spectral k-means (ch. 4) recovers the blocks? (b) After 9.6: check with degree-MMD that an ER model of the same density does not reproduce the degree distribution of the SBM.

  12. ★★ WL kernel and its blind spot. (a) Run two iterations of Algorithm 2.5 on the kite of Example 0.10 and on the 5-cycle, starting from constant labels, and compute the normalized kernel between them. (b) Show that two disjoint triangles and the 6-cycle receive identical WL feature vectors at every iteration, and name a graph statistic of Definition 0.9 that tells them apart. Solution (b): both graphs are 2-regular, so every node keeps the same label at every iteration; the number of triangles (\mathrm{tr}(A^3)/6 = 2 versus 0) or the transitivity (1 versus 0) separates them.

  13. ★★ Heterophily and time. (a) For the bipartite example of Proposition 5.5 with d = 4, compute the output after one and two GCN propagations, then with ego/neighbor separation. (b) For the event stream of Example 5.8 extended by (b, d, 8), list the temporal neighbors of d admissible for a query at t = 9, with their elapsed times.

    Solution: (a) -0.6\,x_v, then 0.36\,x_v; with separation the pair (x_v, -x_v) is kept intact.

    (b) c (\Delta t = 2) and b (\Delta t = 1).

  14. ★★ Equivariance check. Implement one EGNN layer (Proposition 8.3) in NumPy with random small MLPs, apply it to a random 3D point cloud, then to the same cloud rotated by a random orthogonal matrix and translated; verify numerically that the features are unchanged and the coordinates transformed, and that a layer fed raw coordinates as features fails the test.

    Solution: port the PyTorch layer that follows Proposition 8.3, with fixed random two-layer maps as MLPs. In double precision the features agree to rounding error (below 10^{-10}) and the coordinates satisfy x' \mapsto Qx' + t: the distances, hence the messages, do not move, and Q factors out of the update. With [h_v \| x_v] as input features, the messages see absolute positions, and the test fails with errors of order 0.1 to 1.

  15. ★★ GraphRAG on the toy graph. Run the code of 10.4 on its toy corpus. (a) Use k = 1 hop instead of 2: which chunks come back, and what is the support recall? (b) Use two seeds instead of one. (c) Lower the string threshold of resolve to 0.85: which names merge, what false fact does the graph now state, and how many Leiden communities remain? (d) Compute EM and F1 of the answers “Helios” and “the Helios bank” against the gold “Helios Bank”.

    Solution: (a) Only Boreal/team, a recall of 0.5: Helios Bank is two hops from Gus, so the delivery chunk is never a candidate. The number of hops must match the question.

    (b) The second seed is Cirrus, a spurious match of the toy encoder. Its chunks crowd out Boreal/delivery: the top two are Cirrus/team and Boreal/team, recall 0.5. Seeds need a similarity threshold, not only a count.

    (c) “Ana” and “Hana” have ratio 2 \cdot 3 / 7 \approx 0.857 \geq 0.85, so Ana is merged into Hana. The graph now states that Hana works on Atlas and that Ben reports to Hana. With 29 entities, Leiden (seed 0) returns 4 communities, one of them {Ben, Gus, Hana}, and the modularity drops from 0.57 to 0.51. Short names need a stricter rule, such as an exact match or the embedding of the name in its context.

    (d) “Helios”: EM 0 and F1 = 2 \cdot 1 / (1 + 2) \approx 0.67. “The Helios bank”: EM 1 and F1 1, since case, punctuation and articles are normalized away.

  16. ★★★ Neural generation. Train a small autoregressive model (sequential addition of nodes/edges, MLP + softmax — the GraphRNN scheme of ch. 9.4) on ZINC molecules; measure validity (chemical valence) and uniqueness of the generated graphs; compare with an Erdős-Rényi sampler of the same density. Hints: encode the binary S^i (max 4 atom types), teacher forcing, 200 epochs are enough for the lab; reading: low validity (< 50\%) without a valence constraint — explain why the NeVAE architecture (ch. 9.3) changes everything.

    Solution sketch:

    • Order the atoms by BFS. At step i the model outputs a softmax over the atom types and one Bernoulli per earlier atom in a window of the last M atoms, with M the largest BFS bandwidth of the training set.
    • A sample is valid if it is connected and no atom exceeds its valence (C 4, N 3, O 2, F 1). Without constraints, violations accumulate over about 23 atoms, hence the low validity.
    • Masking every bond that would exceed the remaining valence, and forcing each new atom to bond to an earlier one, gives validity close to 100%. That is the NeVAE idea of 9.3: the constraint is in the decoder, not in post-processing.
    • ER at the same density (n \approx 23 atoms, about 25 bonds, p \approx 0.1) is disconnected in more than 90% of samples, so its validity stays below 10% before any valence check.
  17. ★★★ Paper. Choose a paper from ch. 11 (Graph of Words, PathNN, GOAT or NGG), read it, and present it in 10 minutes: problem, contribution, results, limits, position in the course. Grid: clarity of the key figure, reproduction of a number with commentary, one open question proposed.

Projects and assessment

The official assessment, from the course description, is “quizzes and team projects”; the LLGA section of the 2026–2027 sheet displays no modality, resit rule or weighting. Everything below is a proposal. The solo and group subjects can serve as the team project, the graph work package of a Year 1 capstone (Team project box, ch. 8), and the written exam is a model for the quizzes or a final test. The projects exercise O4 (graph-structured data) and O5 (graph × LLM) at their core, with O2 (graph generation), O3 (retrieval and LLM evaluation) and O7 (protocols, reproducibility, industry cases).

Solo projects

  1. [Solo · ≈ 20 h] Kernels versus GNNs under a fair protocol. Do graph kernels still match GNNs on small molecular benchmarks once model selection is honest? A paper study of Errica, Podda, Bacciu & Micheli, “A Fair Comparison of Graph Neural Networks for Graph Classification” (ICLR 2020).
    • Implement: GIN and GraphSAGE in PyG and the paper’s structure-agnostic baseline (an MLP on summed node features), under the paper’s protocol (10 outer folds, model selection on an inner holdout). Then add what the paper does not test: the WL-subtree and shortest-path kernels with an SVM (lab sheet of session 3), under the same protocol.
    • Data: NCI1, PROTEINS and D&D from TUDataset, three chemical datasets of the paper; MUTAG, which the paper does not use, for a first run.
    • Probe: the WL blind spot on regular graphs (Example 2.6). Do triangle counts (Theorem 0.3) added as features separate non-isomorphic regular pairs, such as the CSL graphs of Murphy et al. (2019)?
    • Deliverables: code, a 4–6 page report, a 10-minute talk. Chapters: ch. 0, 2, 5, 8.
    • Success: GIN, GraphSAGE and the baseline within the paper’s standard deviations on at least two of the three datasets, the kernels in the same table, and a measured answer on the blind spot.
  2. [Solo · ≈ 20 h] Heterophily as a spectral problem. Does a learned polynomial filter turn high-pass on heterophilous graphs, as Proposition 5.5 suggests? A paper study of Chien, Peng, Li & Milenkovic, “Adaptive Universal Generalized PageRank Graph Neural Network” (GPR-GNN, ICLR 2021).
    • Implement: edge homophily (Definition 5.4); GCN, an ego/neighbor-separation model in the style of H2GCN, and GPR-GNN, which learns the coefficients \gamma_k of \sum_k \gamma_k \hat A^k H.
    • Data: Cora, Texas and Chameleon (benchmarks of Pei et al., 2020), with ten random 60/20/20 splits, the paper’s dense setting (the paper itself averages 100 runs).
    • Analysis: plot the learned frequency response on the spectrum [0, 2) of \tilde L_{\mathrm{sym}}, using \hat A = I - \tilde L_{\mathrm{sym}} (Proposition 4.6): g(\lambda) = \sum_k \gamma_k\, (1 - \lambda)^k.
    • Deliverables: code, a 4–6 page report, a 10-minute talk. Chapters: ch. 4, 5.
    • Success: accuracies as mean ± standard deviation over the ten splits, and learned responses checked against Proposition 5.5: low-pass on Cora, and on Texas?
  3. [Solo · ≈ 15 h] Temporal link prediction: how much do the negatives matter? Does a temporal GNN still beat plain memorization once the negatives are hard? A paper study of Poursafaei, Huang, Pelrine & Rabbany, “Towards Better Evaluation for Dynamic Link Prediction” (NeurIPS 2022, Datasets and Benchmarks).
    • Implement: the protocol of ch. 5 (causal split, random, historical and inductive negatives); TGN with PyG’s TGNMemory, against EdgeBank, the memorization baseline of the paper.
    • Data: the Wikipedia (page edits) and Reddit (posts) interaction streams of JODIE (Kumar, Zhang & Leskovec, 2019).
    • Deliverables: code, a 4-page report, a 10-minute talk. Chapters: ch. 5, 8.
    • Success: AP under the three negative samplers, transductive and inductive, over 3 seeds, and a check of the paper’s finding that rankings change between random and historical negatives.

Group projects

  1. [Group of 3–4 · ≈ 30 h each] GraphRAG against vector RAG on multi-hop questions. When does an LLM-built knowledge graph beat BM25 and dense retrieval, and at what token cost? This is the graph work package of capstone Y1.1.
    • Implement: the final lab of ch. 10 at scale, on 1,000 questions of the 2WikiMultiHopQA dev split (Ho et al., COLING 2020), 600 to tune and 400 to test. Score the extraction against the gold evidence triples, complete the graph with R-GCN + DistMult on a leakage-free split (ch. 6, Example 8.1), then compare local search, global search and pseudo-code prompting.
    • Other modules: relation extraction from NLP, 6.4; a bandit router from Reinforcement Learning, ch. 4; RAG evaluation from Large Language Models, ch. 7.
    • Split: extraction and entity resolution; graph, completion and communities; retrieval, evaluation and statistics.
    • Deliverables: repository, an 8–10 page report, a 15-minute defence. Chapters: ch. 0, 3, 6, 8, 10.
    • Success: EM, F1 and support recall per question type with paired bootstrap intervals, token cost per question, a re-identification audit (10.3), and a clear verdict on where the graph helps.
  2. [Group of 3 · ≈ 30 h each] How much of the score is leakage? Temporal fraud detection. How much does a random split inflate graph-based fraud detection, and do GNNs survive a change of regime?
    • Data and paper: the Elliptic Bitcoin graph (203,769 transactions, 234,355 payment flows, 49 time steps, about 2% labelled illicit) of Weber et al., “Anti-Money Laundering in Bitcoin: Experimenting with Graph Convolutional Networks for Financial Forensics” (KDD workshop, 2019).
    • Implement: a tabular random forest, GCN and GAT, and EvolveGCN (Pareja et al., 2020), each under a random node split and under the paper’s temporal split (train on steps 1–34, test on 35–49).
    • Split: protocol and tabular baseline; static GNNs; temporal model and analysis.
    • Deliverables: repository, an 8-page report, a 15-minute defence. Chapters: ch. 1, 5, 8.
    • Success: illicit-class F1 under both splits over 3 seeds, the inflation quantified, and the collapse after the dark-market shutdown (step 43) explained.
  3. [Group of 3 · ≈ 30 h each] Valence-aware molecule generation. Do constraints inside the decoder beat post-processing, and can a property predictor steer the sampler? This is the graph work package of capstone Y1.4.
    • Implement: a GraphRNN-style generator with valence masking (the NeVAE idea, 9.3); a small discrete-diffusion model trained with the cross-entropy loss of 9.5; guidance (9.7) by a GIN predictor of logP, with an EGNN on RDKit conformers as an option.
    • Data: QM9 (about 134k molecules) and the 250k-molecule ZINC subset of Gómez-Bombarelli et al. (2018).
    • Other modules: diffusion and guidance from Multimodal GenAI, ch. 3–4.
    • Split: autoregressive model; diffusion model; evaluation and guidance.
    • Deliverables: repository, an 8-page report, a 15-minute defence. Chapters: ch. 5, 8, 9.
    • Success: validity, uniqueness, novelty, degree and orbit MMD and FCD, against an ER baseline; validity above 90% with masking; a measurable shift of the logP distribution under guidance.

Written exam (proposal)

Two hours, one handwritten A4 sheet allowed, no electronic device; four questions, 20 points.

  1. Question (4 points). A colleague reports an AUC of 0.95 for link prediction with a GAE trained on all the edges, then evaluated on 10% of them. Explain why the number is optimistic, give the three steps of a leakage-free protocol, and say what changes when the edges carry timestamps.

    Expected:

    • The encoder passed messages along the test edges, so their endpoints have similar embeddings by construction (1 pt).
    • Remove the test and validation edges and draw negatives before training; train, and compute structural features, on the remaining graph only; score the held-out positives against the negatives, with hyperparameters chosen on validation (2 pts).
    • With timestamps: a chronological split, the causality rule, and historical negatives (1 pt).
  2. Question (5 points). The star K_{1,3} has center 0 and leaves 1, 2, 3. (a) Give L = D - A, its spectrum and a Fiedler vector. (b) Compute \hat A e_0 for the GCN propagator \hat A. (c) Compute the PageRank of the center for a teleport probability \alpha.

    Expected:

      1. D = \mathrm{diag}(3, 1, 1, 1); spectrum 0, 1, 1, 4; a Fiedler vector is (0, 1, -1, 0), or any vector null at the center whose leaf values sum to zero (2 pts).
      1. The degrees with self-loops are (4, 2, 2, 2), so the first column of \hat A is (1.5 pts) \hat A e_0 = \Big(\frac14, \frac{1}{2\sqrt2}, \frac{1}{2\sqrt2}, \frac{1}{2\sqrt2}\Big) \approx (0.25, 0.35, 0.35, 0.35).
      1. The leaves share 1 - \pi_0 and send all their mass to the center, so \pi_0 = (1 - \alpha)(1 - \pi_0) + \alpha / 4 and \pi_0 = \frac{1 - 3\alpha/4}{2 - \alpha}, which is d_0 / 2m = 1/2 at \alpha = 0 and about 0.48 at \alpha = 0.15 (1.5 pts).
  3. Question (5 points). Show that the GCN layer f(X, A) = \sigma(\hat A X W), with \sigma applied entrywise, is permutation-equivariant: f(\Pi X, \Pi A \Pi^\top) = \Pi f(X, A) for every permutation matrix \Pi. Deduce that a sum readout makes the model invariant.

    Expected:

    • The new adjacency with self-loops is \Pi \tilde A \Pi^\top and its degree matrix is \Pi \tilde D \Pi^\top. Since \tilde D is diagonal and \Pi orthogonal, its inverse square root is \Pi \tilde D^{-1/2} \Pi^\top (2 pts).
    • Hence the new propagator is \Pi \hat A \Pi^\top, and \Pi \hat A \Pi^\top \Pi X W = \Pi \hat A X W because \Pi^\top \Pi = I (1.5 pts).
    • An entrywise \sigma commutes with a permutation of the rows (0.5 pt).
    • \mathbf{1}^\top \Pi = \mathbf{1}^\top, so the readout \mathbf{1}^\top H is invariant (1 pt).
  4. Question (6 points). On the 6-cycle C_6, consider pure GCN propagation H^{(\ell)} = \hat A^\ell X. (a) Give the eigenvalues of A and of \hat A. (b) Give the rate \rho of Theorem 5.3, and the number of layers after which the non-constant part of any signal has shrunk by a factor 100. (c) What happens to the alternating signal x = (1, -1, 1, -1, 1, -1)?

    Expected:

      1. \mu_k = 2\cos(2\pi k / 6), that is 2, 1, 1, -1, -1, -2. Since \hat A = (A + I)/3, its eigenvalues are 1, \frac23, \frac23, 0, 0, -\frac13 (2 pts).
      1. \rho = 2/3, and (2/3)^\ell \leq 1/100 requires \ell \geq \ln 100 / \ln 1.5 \approx 11.4, so 12 layers (2 pts).
      1. x is the eigenvector of \mu = -2, so \hat A x = -x/3: each layer flips its sign and divides it by 3, which is Proposition 5.5 with d = 2 (2 pts).

Grading rubric (proposal)

Criterion Weight What earns the marks
Question and baselines 15 % One precise question; the simple baselines (similarity heuristics of Definition 2.2, WL kernel, BM25, a tabular model) tuned before any GNN
Correctness 20 % Models, derivations and proofs right; shapes, normalizations and symmetries checked by unit tests, as for the EGNN layer of ch. 8
Evaluation protocol 25 % Leakage-free splits (Example 8.1, the temporal protocol of ch. 5), at least 3 seeds, confidence intervals, model selection on validation only
Analysis 20 % Ablations, failure cases read one by one, negative results reported, the link to a result of the course stated
Reproducibility 10 % One command reruns everything; seeds, library versions and data sources recorded
Communication 10 % Report and talk clear within the page and time limits; figures readable on a projector

References