Skip to main content
Residual Networks

Residual & Skip Connections

The Depth Problem

In 2015, researchers at Microsoft Research tried training networks with 100+ layers. They expected deeper = better — after all, a 56-layer network has strictly more capacity than a 20-layer one, so it should be able to represent everything the shallower network can, plus more. What actually happened: Deeper networks performed WORSE than shallower ones. The 56-layer network had higher training error than the 20-layer version. This was not overfitting — even training error was higher. The network had the capacity but could not learn to use it. This is the degradation problem, and it puzzled the field until Kaiming He and colleagues proposed a deceptively simple fix. An analogy: Imagine you are giving someone directions, but every instruction passes through a chain of translators. With 5 translators, the message arrives somewhat garbled. With 50, it is unrecognizable. The original intent (gradient signal) degrades with each hop, until the earliest layers receive essentially random noise as their learning signal.
The Degradation Problem: Adding more layers can hurt performance even when the network has more capacity. This happens because gradients vanish or explode through many layers, making it progressively harder for early layers to learn meaningful features. The paradox is that a deeper network should at worst match a shallower one (by learning identity mappings for extra layers), but standard training cannot find this solution.

The Residual Insight

The solution is beautifully simple: skip connections. Instead of learning H(x)H(x), learn the residual F(x)=H(x)xF(x) = H(x) - x: Output=F(x)+x\text{Output} = F(x) + x

Why This Works

The key insight in plain English: instead of asking the network “what should the output be?”, we ask “what small change should we make to the input?” If the best thing to do is nothing (identity), the weights can simply go to zero. Learning “do nothing” is trivially easy; learning “perfectly reconstruct the input through two conv layers” is not. Think of it like editing a document. Without residuals, each layer rewrites the entire document from scratch. With residuals, each layer just suggests tracked changes — additions and deletions. If a layer has nothing useful to contribute, it proposes zero changes, and the document passes through untouched. This is far easier to learn.
  1. Identity is easy: If the optimal transformation is identity, the residual weights just go to zero — F(x)=0F(x) = 0 means output =x= x
  2. Gradient highway: During backpropagation, gradients flow directly through the skip connection (addition is a gradient-friendly operation — the gradient of x+F(x)x + F(x) with respect to xx always includes a term of 1, preventing vanishing)
  3. Ensemble effect: A ResNet with nn blocks can be viewed as an implicit ensemble of 2n2^n paths of different lengths, because each block can either transform or pass through
Training tip: The reason ResNets enabled 152-layer networks (and later 1000+ layers) is fundamentally about gradient flow. Without skip connections, gradients must pass through every weight matrix. With skip connections, they have a “shortcut highway” that preserves signal strength. Monitor gradient norms at early layers — with skip connections, they should remain within 1-2 orders of magnitude of later layers.

ResNet Architecture


DenseNet: Dense Connections

Where ResNet adds the input to the output (and the original information gets blended in), DenseNet takes a more aggressive approach: concatenate all previous features together. Think of it as a group chat where every layer can read every message from every previous layer, not just the most recent one. This maximal information sharing means no feature is ever “forgotten.” Instead of adding, DenseNet concatenates all previous features:

U-Net: Skip Connections for Segmentation

U-Net applies skip connections differently from ResNet: instead of adding within a block, it bridges between the encoder (downsampling path) and decoder (upsampling path). The problem it solves is fundamental to segmentation: the encoder compresses spatial information into rich semantic features (it knows “this is a dog”), but loses precise spatial detail (it forgets exactly where the dog’s ear ends). Skip connections from the encoder pipe high-resolution spatial features directly to the decoder, giving it both the “what” and the “where.” Think of it like an architect designing a building. The high-level plan (encoder output) says “put a window here,” but you need the detailed measurements from the original blueprint (encoder skip features) to cut the window to the right size. U-Net combines encoder-decoder with skip connections for pixel-level predictions:
U-Net Architecture

Comparison

Common pitfall — dimension mismatches: When the residual branch changes spatial dimensions (stride > 1) or channel count, you must add a projection shortcut (1x1 conv + BN) to the skip connection so the shapes match for addition. Forgetting this is one of the most common implementation bugs — your code will crash with a shape mismatch error at the out += identity line. The BottleneckBlock above handles this correctly with self.shortcut.
When to use what: ResNet is the safe default for classification. If you are memory-constrained and want maximum feature reuse, DenseNet with a modest growth rate (k=12-32) is worth trying. U-Net (or its variants like U-Net++ and nnU-Net) is the go-to for any pixel-level prediction task — segmentation, depth estimation, super-resolution, or diffusion model backbones.

Exercises

Compare gradient magnitudes at early layers for a 50-layer network with and without skip connections.
Implement ResNet-50 and ResNet-101 using bottleneck blocks.
Train U-Net on a simple segmentation task (e.g., cell segmentation).

What’s Next

Module 16: Normalization Techniques

Batch norm, layer norm, and other techniques for stabilizing training.