Hands-on: Filter a Network, Then Let It Learn the Filter
Two halves, in the same order as the concepts chapter: first a hand-designed spectral filter applied to a real network, then a GCN that learns its own filter from eight labelled nodes.
This module has no hosted notebook. PyTorch is a compiled package that the browser runtime cannot load, so this one runs locally only.
The notebook is in the repository at notebooks/m09-graph-neural-nets/coding.py. Run it with marimo edit notebooks/m09-graph-neural-nets/coding.py in an environment that has PyTorch and PyTorch Geometric installed: pip install torch torch_geometric on a CPU machine, or follow the PyTorch Geometric install guide if you want GPU wheels. Everything in the first half runs without PyTorch.
What you will build
Part 1 — a filter you designed yourself. On Zachary’s karate club:
- Form the Laplacian {\bf L} = {\bf D} - {\bf A} and eigendecompose it.
- Build the low-pass and high-pass filter matrices straight from the formulas of the concepts chapter, h_{\text{low}}(\lambda) = 1/(1+\alpha\lambda) and h_{\text{high}}(\lambda) = \alpha\lambda/(1+\alpha\lambda), by rescaling each eigenvalue and reassembling.
- Apply both to a random signal on the nodes, and then to eigenvector centrality, and draw the network colored by the result.
Part 2 — a filter the model learns. On the same network:
- Turn the network into a PyTorch Geometric
Dataobject: an edge list, node features (the leading nontrivial eigenvectors of the normalized Laplacian), and the true club membership as labels. - Label only 8 of the 34 nodes, 4 per side, and train a 2-layer
GCNConvmodel on those alone. - Plot the loss and the train/test accuracy over 200 epochs, then draw the network with predicted labels beside the true ones and count the mistakes.
What to watch for
- In Part 1, compare the two pictures of the same signal. The low-pass version has neighbors sharing a color; the high-pass version keeps only the places where neighbors disagree. That is the filter-response figure of the concepts chapter happening on a real network.
- In Part 2, notice how few labels the model needs. Eight nodes out of thirty-four, and the rest are classified by message passing alone — the semi-supervised advantage in its smallest form.
- The nodes it gets wrong are worth staring at. They are usually the ones sitting between the two factions, which is a statement about the network, not about the model.
Take it further
Two extensions worth the time, neither of them in the notebook yet:
- Rebuild the GCN with 2, 4, 8 and 16 layers and plot final accuracy against depth. It will peak early and then fall. Over-smoothing is much more convincing when you have caused it yourself.
- Replace the node features with a column of ones and re-run. Whatever accuracy survives came from topology alone.
Also in this module
Image processing preliminaries — edge detection, kernels, and the Fourier transform worked through on real images: the runnable version of How a Camera Finds an Edge. notebooks/m09-graph-neural-nets/image-processing.py — run locally.
A GCN from scratch — Bruna’s spectral GCN and ChebNet implemented directly from the equations, without PyTorch Geometric’s layers. See the appendix.