← Explainer Library

Interactive Explainer

Residual Connections, Why They Work

The single line $y = x + F(x)$ unlocked networks 100× deeper. Watch the failure mode of plain deep nets as a 64-layer activation map collapses to noise, then add the skip and watch the same network train cleanly. Three live experiments and one loss-surface tour.

Prelude

The depth degradation problem

Before December 2015, conventional wisdom said deeper networks should generalise better — until you tried to train a plain 50-layer CNN and watched it do worse than the 20-layer version on the training set, never mind the test set. That's not overfitting; it's a failure of the optimiser. He et al. called it the degradation problem.

The fix was a single line of code: change every block from $y = F(x)$ to $y = F(x) + x$. The output is now whatever the block computes plus a copy of the input the block could ignore. That tiny change made it possible to train ResNet-152, ImageNet-class accuracy at 3× the depth of every prior architecture, and started the modern deep-learning rocket.

The slogan. A residual block doesn't have to learn the right output. It only has to learn the residual — the small correction on top of the input. If a layer has nothing to add it can output zeros, and the input passes through untouched.
Step 1

Watch activations die without skips

Below: a tiny feed-forward stack at depth $L$. Each layer is $h_{l+1} = \tanh(W_l h_l + b_l)$, randomly initialised. The plain version is just that recursion. The residual version replaces it with $h_{l+1} = h_l + \tanh(W_l h_l + b_l)$. Slide $L$ and watch the activation magnitude at each depth.

Activation L₂-norm per layer. Solid teal: residual stack. Dashed orange: plain stack. The plain trace decays to zero (or blows up); the residual stack stays bounded.
Step 2

Gradient flow — the same story, backwards

Backpropagation computes $\frac{\partial \mathcal{L}}{\partial h_l}$ as a chain of matrix products. In a plain net every link in the chain is some Jacobian close to a non-identity matrix; their product collapses fast. In a residual net the Jacobian is $I + \frac{\partial F}{\partial h_l}$ — identity plus something small. Identity preserves; "plus something small" adds gradient signal layer by layer instead of multiplying it away.

Below: gradient norm at each depth, traced from the loss back to layer 0. The residual line is roughly flat. The plain line falls off geometrically.

‖∂ℒ/∂h_l‖ vs depth l, on a log scale.
Step 3

Train both, side by side

Same dataset, same depth, same optimiser. Press Start training below; one canvas trains the plain net, the other trains the residual net. The plain version visibly stalls at $L \ge 16$; the residual version trains cleanly to much greater depth.

step 0 plain loss residual loss
Training loss for the two architectures, same data, same lr. Crank L up to 64 and watch the gap blow open.
Step 4

The loss surface, visualised

Li et al. (2018) showed that residual connections smooth the loss landscape. We render a 2-D slice: pick two random directions in parameter space, evaluate the loss on a grid, and contour. The plain landscape is ridged and full of bad minima; the residual landscape is a single shallow bowl.

Plain net (L = 24)
Residual net (L = 24)

Lighter regions are lower loss. Notice the plain surface has multiple basins separated by ridges; the residual surface has a single broad basin around the origin. Same model class, one line of code different.

Step 5

Iterative refinement — what each block does

A useful mental model (Greff et al., Jastrzębski et al., Veit et al.): each residual block makes a small correction to a running representation. The "residual stream" carries the input forward unchanged; blocks are read-write peripherals that nudge it.

That's also exactly the picture of a Transformer's residual stream — attention and MLP blocks read the stream, add their contributions, and pass it on. Mechanistic interpretability work (Elhage et al., 2021) treats the stream as a literal communication channel between layers.

What the model can do that a plain stack cannot. A residual stack can choose its own depth: any unnecessary block just outputs $\approx 0$ and the input passes through. A plain stack has to use every layer fully — and the optimiser has to learn an identity subnetwork from scratch to do so.
Step 6

The variants and their lessons

Final takeaway. One line of code — "and add the input back" — was the deep-learning equivalent of the printing press. Without residuals, no ResNet-152, no BERT, no GPT-anything. Every time you stack more than ~10 layers and it just works, you're using this trick.
Step 7

Why the residual stream view unlocks Transformers

Modern transformers are best understood as residual streams (Elhage et al., 2021, Anthropic interpretability). Each layer reads from a high-dimensional residual stream, computes a delta, and writes it back. Layer $\ell$'s output is

Three consequences of this view:

Step 8

Where residuals can hurt

Three failure modes to know:

Step 9

Reading list