A graph neural network has exactly one job that matters: take a node, look at its neighbours, and squeeze them into a better description of the node. A bank is partly defined by who it lends to; a wallet is partly defined by who it transacts with; a supplier is partly defined by who it ships to. The whole field is just a long argument about how to do that squeezing.
That argument produced a lineage. GCN averages neighbours with a fixed recipe. GraphSAGE samples a handful of them and learns the recipe, crucially without needing the whole graph up front. GAT lets the node decide which neighbours deserve more of its attention. Temporal GNNs admit the embarrassing truth that in finance the graph itself is a moving target — yesterday’s lending network is not today’s.
This lesson walks that lineage in order. Each architecture is a different answer to the same question, and the differences are exactly the things that decide whether your model survives contact with a real, growing, non-stationary financial network.
Why there’s a lineage at all
Before you read — take a guess
Every graph neural network layer has to do two things to update a node: combine information from its neighbours, and fold in the node's own previous state. What is the single design axis that most separates GCN, GraphSAGE, and GAT?
Analogy. Picture a node as a person deciding what to think after talking to their contacts. GCN is the person who gives everyone an equal, pre-set say (with a polite adjustment for how popular each contact is). GraphSAGE is the person who can’t possibly talk to all their contacts, so they poll a random sample and learn how to weigh the gossip. GAT is the person who listens hardest to the contacts who actually matter and tunes out the noise. Same room, three temperaments.
Definition. A GNN layer updates every node’s hidden vector from the previous layer’s vectors using two operations: an aggregate over the neighbourhood , and a combine with the node’s own previous vector . Stacking such layers lets information flow hops: after layer , node ‘s embedding has been touched by everything within steps in the graph. Generically,
Every architecture in this lesson is a specific choice of AGG and COMBINE — and a specific stance on whether the graph is fixed, growing, weighted, or moving. Here is the whole lineage on one axis before we dig in:
| Architecture | The one-line idea |
|---|---|
| GCN | Average neighbours with a fixed degree-normalised recipe |
| GraphSAGE | Sample a few neighbours, learn the aggregator, concatenate with self |
| GAT | Learn attention weights so important neighbours count more |
| Temporal GNN | Run a GNN per time slice and model how the graph changes |
Two hops is usually plenty
Each layer is one hop of message passing, so layers reach hops. Tempting as it is to stack ten layers, in financial networks 2–3 hops usually captures the relevant contagion (your counterparties, and their counterparties) before over-smoothing sets in — the failure where every node’s embedding blurs into the same mush. More on that trap as we go.
GCN — fixed degree-normalised averaging
Before you read — take a guess
A GCN aggregates a node's neighbours using a fixed weight per edge. What does that weight depend on?
Analogy. GCN is a town-hall meeting with a strict, pre-printed rule for who speaks and how loudly: everyone gets a turn, but the rule quietly turns down the volume of the loudmouths who know everyone (high-degree nodes) so they don’t dominate. Nobody chose the rule for tonight’s meeting — it was the same rule last week and will be next week.
Definition. The Graph Convolutional Network layer applies one shared linear transform to every node, then aggregates over the neighbourhood including the node itself (the self-loop), each term weighted by a fixed symmetric degree normalisation, then passes the sum through a nonlinearity :
The factor is the heart of it. It is not learned — it is read straight off the graph’s structure. It down-weights edges touching high-degree nodes so that a hub’s flood of connections doesn’t drown out a leaf node’s single meaningful link. (For the self-loop term the degree includes the added self-edge, but we keep the arithmetic simple below.)
Worked example. Let node be a small bank with two neighbours, and , and a self-loop. Suppose (after adding self-loops) the degrees are , , . Take a one-dimensional feature so the arithmetic is visible, with and the identity, and previous-layer values , , . The three edge weights are:
| Term | Weight | Value | Contribution |
|---|---|---|---|
| self () | 10 | 3.333 | |
| neighbour | 4 | 1.333 | |
| neighbour (hub) | 1 | 0.167 |
Sum: . So . Notice that the high-degree neighbour got the smallest weight (0.167 vs 0.333) purely because it is a hub — the degree normalisation did that automatically, before any learning. The bank’s own state (3.333) still dominates, but its two neighbours pulled the new value down toward theirs.
GCN is transductive — new nodes are a problem
The fixed normalisation is computed from the whole graph’s degree structure, and classic GCN training assumes the entire graph is present at train time. Add a brand-new bank tomorrow and you have changed the degrees, the normalisation, and arguably the whole adjacency matrix. There is no clean way to embed a node the model never saw without recomputing over the augmented graph. In finance, where new entities appear constantly, this transductive assumption is a genuine ceiling.
When to use it
Reach for GCN when the graph is fixed and fully known at training time, reasonably homogeneous, and you want a strong, cheap, well-understood baseline — node classification on a static interbank network snapshot, say, where every institution is already in the graph. It is the linear-regression-equivalent of GNNs: the thing you should beat before you complicate your life. If nodes will keep arriving, GCN’s transductive nature is a sign to move down the lineage.
Fill in what makes GCN's aggregation fixed.
Pick the right option for each blank, then check.
GCN weights each neighbour by , a normalisation read directly off the graph rather than learned.
GraphSAGE — sample, aggregate, generalise
Before you read — take a guess
GraphSAGE was designed to fix GCN's biggest practical limitation. Which one?
Analogy. A new analyst joins a firm with 50,000 client relationships. They cannot read every file, so they learn a reusable habit: “sample a dozen relationships, summarise them, staple that summary to what I already know about the client.” That habit works on client #50,001 — whom they’ve never met — because they learned the procedure, not a memorised answer for each existing client. That is GraphSAGE: SAmple and aggreGatE.
Definition. A GraphSAGE layer (1) samples a fixed-size set of neighbours from , (2) aggregates their previous vectors with a learnable aggregator (mean, pooling, or even an LSTM), and (3) concatenates the result with the node’s own previous vector before projecting through and a nonlinearity:
where is the sampled subset of neighbours. The two design moves that matter: concatenate (self and neighbours are kept as distinct halves, not blended into one average as in GCN), and sample (a fixed fan-out keeps cost bounded even for a hub with a million edges). Because the layer learns a function rather than a per-node embedding, the same trained weights embed nodes that did not exist at training time. This is the property called inductive learning.
Worked example (mean aggregator). Node has feature and four neighbours with values . We sample two of them — say we draw . The mean aggregate is . Concatenate with self: the layer input is the pair . With a tiny projection (so it averages the two halves) and identity :
Now suppose the next training step samples a different pair, : the aggregate is , and . Same node, same weights, different answer — because the sample changed.
Sampling is approximation — mind the variance
That two-value swing (6.25 vs 5.75) from re-sampling is the catch. Neighbour sampling makes GraphSAGE scalable, but it injects variance: a node’s embedding now depends on which neighbours happened to be drawn. Too small a fan-out and the estimate of the “true” full-neighbourhood aggregate is noisy; too large and you lose the scalability that motivated sampling. It is the classic bias–variance knob, wearing a graph hat — and in low-signal finance (recall the small-sample discipline from Deep Learning for Market Data), extra variance is never free.
When to use it
GraphSAGE is the realistic finance default, because financial graphs grow: new banks charter, new wallets appear, new suppliers enter the network every day, and you need to score them without retraining the world. Use it when the node set is open-ended, when hubs are too large to aggregate fully, or when you train on one time period and must deploy on later, larger graphs. If your graph is genuinely fixed and small, GCN’s exactness may beat SAGE’s sampling noise — but that is the exception in finance, not the rule.
Sort each property under the architecture it best describes.
Place each item in the right group.
- Embeds nodes unseen during training (inductive)
- Samples a fixed-size neighbour set
- Concatenates self with the neighbour aggregate
- Self and neighbours blended into one normalised sum
- Fixed degree-normalised averaging
- Needs the whole graph at train time (transductive)
GAT — learn which neighbours matter
Before you read — take a guess
A Graph Attention Network improves on uniform or degree-only weighting by doing what?
Analogy. GCN gives everyone a degree-adjusted but otherwise equal vote. GAT hires a staff that reads the room and decides, per conversation, whose opinion to weight: the counterparty exposing you to $2 billion gets leaned on; the $10,000 nuisance account gets a polite nod. Crucially, the staff learned how to allocate that attention from past data — it wasn’t told “size equals importance,” it figured out what importance looks like.
Definition. A Graph Attention Network layer computes, for each edge , a learned, normalised attention coefficient , then aggregates neighbours as an attention-weighted sum. The coefficients come from a softmax over learned scores :
The raw score is produced by a small learnable function of the two transformed endpoint vectors and (in the original GAT, a single-layer feedforward on their concatenation, with a LeakyReLU). The softmax guarantees the weights over a node’s neighbourhood are non-negative and sum to one. Multi-head attention runs several independent attention mechanisms in parallel and concatenates (or averages) their outputs, which stabilises training the way multiple analysts cross-check each other.
Worked example (softmax over 3 neighbours). Node has three neighbours with raw learned scores and per-neighbour values . Exponentiate: , , . Their sum is . The attention weights are:
| Neighbour | Raw score | Value | Weighted | ||
|---|---|---|---|---|---|
| 1 | 2.0 | 7.389 | 10 | 6.65 | |
| 2 | 1.0 | 2.718 | 4 | 0.98 | |
| 3 | 0.0 | 1.000 | 1 | 0.09 |
The weights sum to , as a softmax must. The attention-weighted aggregate (taking , identity) is — dominated by neighbour 1, whose higher learned score earned it two-thirds of the attention. Contrast a plain mean, : GAT’s learned weighting pulled the result sharply toward the neighbour the model decided was important.
Attention is the same idea you have met along the temporal axis — assigning weights to others and summing accordingly. The heatmap below shows attention distributed over time; a GAT does the exact same trick over a node’s neighbours: a learned weight per relationship, softmaxed to sum to one, with the high-weight links dominating the aggregate.
A softmax turns learned scores into weights that sum to one. Read each query row as a node, each key column as one of its neighbours: the bright cells are the relationships the model leans on. Sharper attention concentrates on a few; diffuse attention spreads it out, like a degree-only average.
Attention is not free interpretability
It is tempting to read the weights as an explanation — “the model paid 66% attention to its biggest creditor, so that’s why.” Resist. High attention is correlation with the model’s objective, not a causal account, and different attention patterns can yield near-identical predictions. GAT also carries more parameters than GCN or SAGE and is correspondingly data-hungry — exactly the wrong appetite in a low-signal, small-effective-sample financial regime. The discipline from Deep Learning for Market Data applies in full: prove the extra capacity earns its keep on a held-out, purged test before believing the attention map.
When to use it
Use GAT when neighbours are genuinely unequal in importance and that importance is learnable — credit-risk graphs where a single dominant counterparty drives contagion, heterogeneous transaction networks, fraud rings where a few edges carry the signal. It shines when degree-normalisation (GCN) or uniform sampling (SAGE) wrongly treat a critical edge like any other. Skip it when your effective sample size is tiny, the graph is nearly homogeneous, or a cheaper model already clears the bar — the extra parameters are a tax you pay in data you may not have.
Why does GAT use a softmax over the neighbours instead of just using the raw scores as weights?
Answer. The softmax does two jobs at once. First, it forces the weights to be non-negative and sum to one within each neighbourhood, so the aggregate is a proper weighted average that does not blow up for high-degree nodes — a node with 500 neighbours and one with 3 are both summarised on the same scale. Second, it makes the scoring relative: what matters is how a neighbour’s score compares to its siblings’, not its absolute value, so the model can express “this neighbour is the important one here” independently of the overall magnitude. Raw, unnormalised scores would let one busy node dominate the loss landscape and would not give comparable, bounded weights across differently-sized neighbourhoods.
Temporal / dynamic GNNs — when the graph moves
Before you read — take a guess
GCN, GraphSAGE, and GAT all assume a single graph. Why is that assumption dangerous for a real financial network?
Analogy. A static GNN on a financial network is a single long-exposure photo of a busy intersection: every car that ever passed is smeared into one ghostly blur, and you cannot tell rush hour from 3 a.m. A temporal GNN is a video — a sequence of crisp frames — so you can see the lending network tighten before a crisis and slacken after, instead of averaging the panic and the calm into one meaningless grey.
Definition. Temporal (dynamic) GNNs model a graph that changes over time. There are two broad families:
- Snapshot-based (discrete-time). Slice time into windows, build one graph per window, embed each with a GNN, then run a sequence model across the snapshots — a GRU, LSTM, or temporal attention. Schematically, a per-slice embedding feeds a recurrence:
- Continuous-time (event-based). Skip the snapshots and ingest timestamped events directly — each new edge (a loan at 14:32, a transfer at 14:33) updates the embeddings of the nodes it touches as it arrives. This preserves exact timing and irregular spacing that fixed snapshots throw away.
This is the deliberate marriage of two axes you have been building all along: the relational axis (a GNN, summarising who is connected to whom) and the temporal axis (an RNN or attention, summarising how things evolve), the same temporal machinery from Deep Learning for Market Data, now stacked on top of message passing.
Illustrative example — a 5-day lending sequence. Track one bank’s interbank borrowing neighbours over a week. Each day is a snapshot ; we embed it (say with GraphSAGE) into a per-day vector , then a GRU carries state forward:
| Day | Active lending edges | Snapshot embedding (toy) | What the GRU should notice |
|---|---|---|---|
| Mon | 12 | 0.20 | calm baseline |
| Tue | 11 | 0.22 | unchanged |
| Wed | 7 | 0.41 | edges dropping — funding tightening |
| Thu | 4 | 0.68 | sharp contraction |
| Fri | 3 | 0.79 | stress building |
A static GNN on the time-averaged graph would report something like ”≈ 7.4 average edges, embedding ≈ 0.46” — a single number that completely hides the Monday-to-Friday collapse from 12 edges to 3. The temporal model sees the trajectory (0.20 → 0.22 → 0.41 → 0.68 → 0.79) and can flag the accelerating withdrawal of funding as a trend, which is precisely the signal a risk desk cares about.
Time-averaging silently mixes regimes (and leaks)
Squashing a dynamic network into one static or time-averaged graph does not just lose the trend — it can fabricate edges that never coexisted (a counterparty from January and one from June, joined in a graph as if simultaneous) and it quietly blends incompatible regimes. Worse, if you build that averaged graph using future snapshots to embed a past node, you have leaked the future into the past. Keeping time explicit — snapshots in order, no peeking ahead — is the same look-ahead-bias discipline the next lesson on temporal leakage makes its whole subject.
When to use it
Use a temporal GNN whenever the network’s topology itself evolves and that evolution carries signal — funding-stress propagation, supply-chain disruption spreading link by link, fraud rings that assemble and dissolve, correlation graphs that regime-shift. Choose snapshot + sequence model when events naturally bucket into periods (daily positions, weekly exposures) and you want simplicity; choose continuous-time when exact timing and irregular event spacing matter (high-frequency settlement flows, intraday transfers). If the graph genuinely does not change over your horizon, a static GNN is simpler and fine — but in finance, “the graph doesn’t change” is a hypothesis to test, not assume.
Fill in the two-axis idea behind temporal GNNs.
Pick the right option for each blank, then check.
A snapshot-based temporal GNN combines the axis, handled by a GNN per time slice, with the temporal axis, handled by a sequence model such as a GRU across slices.
The whole lineage on one table
The four architectures laid side by side — the comparison to keep when you choose:
| Architecture | Aggregation rule | Inductive? | Learns neighbour weights? | Best finance use | Main weakness |
|---|---|---|---|---|---|
| GCN | Fixed degree-normalised average of self + neighbours, weight | No (transductive) | No — weights are structural | Static, fully-known network as a strong cheap baseline | Can’t embed unseen nodes; needs the whole fixed graph |
| GraphSAGE | Sample a fixed fan-out, learn AGG (mean/pool/LSTM), CONCAT self with neighbour aggregate | Yes | Partly — learns the aggregator, not per-edge weights | Growing graphs: new banks/wallets scored without retraining | Sampling variance; embedding depends on the draw |
| GAT | Attention-weighted sum; from a softmax over learned scores; multi-head | Yes | Yes — explicit learned per-neighbour weights | Unequal neighbours: dominant creditors, fraud-ring edges | Data-hungry (more params); attention is not interpretability |
| Temporal GNN | A GNN per snapshot + a sequence model across snapshots (or timestamped events) | Depends on the base GNN | Depends on the base GNN | Non-stationary topology: contagion, evolving supply links | More moving parts; needs careful no-look-ahead time handling |
Pick a term, then click its definition.
Recap
You walked the lineage from a fixed recipe to a moving target. GCN averages neighbours with a degree-normalised rule nobody learned and the whole graph must be present — clean, cheap, transductive. GraphSAGE samples a handful of neighbours, learns the aggregator, concatenates self with neighbours, and earns the property that matters most in a growing financial network: it is inductive, embedding banks and wallets it never saw in training. GAT lets each node learn, via a softmax over scores, which neighbours deserve its attention — powerful where a dominant creditor truly matters, but parameter-hungry and not the free explanation it looks like. And temporal GNNs admit the graph itself moves, marrying the relational axis to the temporal one so a funding collapse reads as a trajectory, not a smeared average.
Big picture
GCN, GraphSAGE, GAT and Temporal GNNs
- GNN architecture lineage
- Design axis
- AGGREGATE neighbours
- COMBINE with self
- K layers = K hops
- GCN
- Fixed degree-norm average
- Weight 1/sqrt(deg v · deg u)
- Transductive — needs whole graph
- GraphSAGE
- Sample fixed fan-out
- Learn aggregator, CONCAT self
- Inductive — embeds unseen nodes
- Sampling variance
- GAT
- Learned attention alpha (softmax)
- Important neighbours weigh more
- Multi-head; data-hungry
- Temporal GNN
- Snapshot + GRU/attention
- Continuous-time events
- Topology is non-stationary
- No look-ahead across time
- Design axis
Mixed check: did the lineage stick?
A GCN aggregates a small bank v (deg 3) with neighbours a (deg 3) and b (deg 12), plus a self-loop. Why does neighbour b get less weight than a?
Check your answer to continue.