Hands-on: Filter a Network, Then Let It Learn the Filter

Author

Sadamori Kojaku

Published

August 25, 2026

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.

NoteWhere the code lives

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:

  1. Form the Laplacian {\bf L} = {\bf D} - {\bf A} and eigendecompose it.
  2. 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.
  3. 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:

  1. Turn the network into a PyTorch Geometric Data object: an edge list, node features (the leading nontrivial eigenvectors of the normalized Laplacian), and the true club membership as labels.
  2. Label only 8 of the 34 nodes, 4 per side, and train a 2-layer GCNConv model on those alone.
  3. 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.