ResNet: Deep Residual Learning

ResNet (Deep Residual Network) is a convolutional neural network architecture introduced by He et al. in 2015 that uses shortcut connections to learn residual mappings rather than direct input-output transformations, enabling stable training of networks with hundreds or thousands of layers. It matters because it solved the degradation problem — the counterintuitive observation that adding more layers to a network made it worse even on training data, not just test data — and it sparked the modern era of ultra-deep architectures. The counterintuitive fact: a 1000-layer ResNet can be trained stably, yet a plain 20-layer network outperforms a plain 56-layer network on the same task.

The core insight

Instead of asking each layer to learn a complete mapping from input to output, ResNet asks each layer to learn only what needs to change — the residual. If the optimal transformation is close to the identity, it is far easier to push the residual toward zero than to fit an identity mapping through a stack of nonlinear layers. The shortcut connection carries the original input forward and adds it back after the transformation, so the gradient can flow directly backward through these identity paths without vanishing. This single structural change unlocked networks of depth 50, 101, 152, and beyond, transforming computer vision permanently.

How It Works

The Degradation Problem

In a vanilla deep network (no shortcuts), stacking more layers should never hurt: at worst, the extra layers could learn the identity function and match the shallower network's performance. In practice, optimizers fail to learn this — training loss increases with depth. This is not overfitting; it is an optimization problem.

The Residual Formulation

Let x\mathbf{x} be the input to a residual block and F(x,{Wi})\mathcal{F}(\mathbf{x}, \{W_i\}) be the mapping learned by the stacked layers. The block's output is:

1
y=F(x, {Wi})+x\quad \mathbf{y} = \mathcal{F}(\mathbf{x},\, \{W_i\}) + \mathbf{x}

Explanation: The block's output is the learned residual correction plus the original input, so the layers only need to model what changes rather than the full transformation. Here x\mathbf{x} is the skip-connected input, F\mathcal{F} represents two or three convolutional layers with batch normalization and ReLU, and y\mathbf{y} is passed through a final ReLU before becoming the next block's input.

Gradient Flow Through Shortcuts

Consider the loss L\mathcal{L} and a deep network with LL layers. With shortcut connections the activations at any shallow layer ll can be expressed in terms of any deeper layer LL:

2
xL=xl+∑i=lL−1F ⁣(xi, {Wi})\quad \mathbf{x}_L = \mathbf{x}_l + \sum_{i=l}^{L-1} \mathcal{F}\!\left(\mathbf{x}_i,\, \{W_i\}\right)

Explanation: The deep activation equals the shallow activation plus a sum of residuals, meaning information from any depth is directly accessible at any other depth. The gradient at layer ll follows directly:

3
∂L∂xl=∂L∂xL⋅(1+∂∂xl∑i=lL−1F(xi,{Wi}))\quad \frac{\partial \mathcal{L}}{\partial \mathbf{x}_l} = \frac{\partial \mathcal{L}}{\partial \mathbf{x}_L} \cdot \left(1 + \frac{\partial}{\partial \mathbf{x}_l}\sum_{i=l}^{L-1}\mathcal{F}(\mathbf{x}_i,\{W_i\})\right)

Explanation: The gradient at any shallow layer receives a direct copy of the deep gradient (the "1" term), preventing it from vanishing even through hundreds of layers. The term ∂L∂xL\frac{\partial \mathcal{L}}{\partial \mathbf{x}_L} is the gradient from the loss, and the "1" in the parenthesis is the contribution of the identity shortcut — it guarantees the gradient can never fully vanish as long as the loss gradient itself is nonzero.

Dimension Matching with Projection Shortcuts

When the input and output dimensions differ (e.g., when stride=2 halves spatial resolution or channel depth doubles), a projection shortcut is used:

4
y=F(x, {Wi})+Ws x\quad \mathbf{y} = \mathcal{F}(\mathbf{x},\, \{W_i\}) + W_s\,\mathbf{x}

Explanation: The learnable projection matrix WsW_s (implemented as a 1×1 convolution) reshapes the shortcut signal to match the residual branch's output dimensions before addition. WsW_s is a 1×11\times1 convolution with stride matching the residual branch, with no activation applied to the shortcut path itself.

BasicBlock vs. Bottleneck

For ResNet-18/34, each block uses two 3×33\times3 convolutions (BasicBlock). For ResNet-50/101/152, a Bottleneck design reduces computation:

5
FLOPsbottleneck=2⋅(1×1⋅C/4)+(3×3⋅C/4)+2⋅(1×1⋅C/4)  ≈  98 C2\quad \text{FLOPs}_{\text{bottleneck}} = 2\cdot(1{\times}1\cdot C/4) + (3{\times}3\cdot C/4) + 2\cdot(1{\times}1\cdot C/4) \;\approx\; \tfrac{9}{8}\,C^2

Explanation: The bottleneck block uses 1×1 convolutions to compress channels by 4× before and expand after the expensive 3×3 convolution, cutting FLOPs by roughly 8× compared to two 3×3s at full width. Here CC is the full channel width, the factor C/4C/4 is the bottleneck dimension, and the three stages are: compress → spatial-mix → expand.

PyTorch Implementation

```python import torch import torch.nn as nn class BasicBlock(nn.Module): expansion = 1 def __init__(self, in_channels: int, out_channels: int, stride: int = 1): super().__init__()

# Main residual branch self.conv1 = nn.Conv2d(in_channels, out_channels, 3, stride=stride, padding=1, bias=False) self.bn1 = nn.BatchNorm2d(out_channels) self.relu = nn.ReLU(inplace=True) self.conv2 = nn.Conv2d(out_channels, out_channels, 3, stride=1, padding=1, bias=False) self.bn2 = nn.BatchNorm2d(out_channels)

# Projection shortcut (only when dimensions change) self.shortcut = nn.Sequential() if stride != 1 or in_channels != out_channels: self.shortcut = nn.Sequential( nn.Conv2d(in_channels, out_channels, 1, stride=stride, bias=False), nn.BatchNorm2d(out_channels) ) def forward(self, x: torch.Tensor) -> torch.Tensor: identity = self.shortcut(x) # ← shortcut path out = self.relu(self.bn1(self.conv1(x))) out = self.bn2(self.conv2(out)) out = self.relu(out + identity) # ← residual addition return out

class Bottleneck(nn.Module): expansion = 4 # output channels = base_width × 4 def __init__(self, in_channels: int, base_width: int, stride: int = 1): super().__init__() out_channels = base_width * self.expansion self.conv1 = nn.Conv2d(in_channels, base_width, 1, bias=False) self.bn1 = nn.BatchNorm2d(base_width) self.conv2 = nn.Conv2d(base_width, base_width, 3, stride=stride, padding=1, bias=False) self.bn2 = nn.BatchNorm2d(base_width) self.conv3 = nn.Conv2d(base_width, out_channels, 1, bias=False) self.bn3 = nn.BatchNorm2d(out_channels) self.relu = nn.ReLU(inplace=True) self.shortcut = nn.Sequential() if stride != 1 or in_channels != out_channels: self.shortcut = nn.Sequential( nn.Conv2d(in_channels, out_channels, 1, stride=stride, bias=False), nn.BatchNorm2d(out_channels) ) def forward(self, x: torch.Tensor) -> torch.Tensor: identity = self.shortcut(x) out = self.relu(self.bn1(self.conv1(x))) # compress out = self.relu(self.bn2(self.conv2(out))) # spatial mix out = self.bn3(self.conv3(out)) # expand return self.relu(out + identity) ```

researcher · Kaiming He | b. 1990 | Inventor of ResNet and He Initialization

Kaiming He completed his PhD at The Chinese University of Hong Kong and later joined Microsoft Research Asia, where he led the team that produced ResNet. His 2015 paper "Deep Residual Learning for Image Recognition" won Best Paper at CVPR 2016 and became one of the most cited papers in all of science. Remarkably, He also invented the Kaiming (He) weight initialization scheme in the same year, which is specifically designed for ReLU networks and is the default initializer in PyTorch's `nn.Conv2d` today.

researcher · Jian Sun | b. 1979 | Senior Author and Research Lead for ResNet

Jian Sun was a principal researcher at Microsoft Research Asia and the senior author on the ResNet paper, leading the broader research program that produced a series of breakthroughs in deep feature learning. He guided the experimental strategy that validated residual networks across ImageNet classification, COCO detection, and PASCAL segmentation simultaneously — an unusually broad validation for a single architecture paper. Sun later moved to industry, joining Megvii (Face++) as VP of Research, where residual architectures formed the backbone of their commercial vision systems.

Figure
ResNet Residual Block — Data Flow
Residual Block — Forward Pass Input x Conv 3×3 BN + ReLU W₁ Conv 3×3 BN W₂ + Identity shortcut (x) Output y = F(x)+x then ReLU Residual branch F(x, {Wᵢ}) ∂L/∂x receives gradient directly via shortcut → no vanishing
Figure
ResNet-50 Macro Architecture
ResNet-50 — Macro Architecture 224×224 RGB Input 7×7, 64 stride 2 Conv1 112×112 3×3 pool +3 blocks 256-ch Conv2_x 56×56 4 blocks stride 2 512-ch Conv3_x 28×28 6 blocks stride 2 1024-ch Conv4_x 14×14 3 blocks stride 2 2048-ch Conv5_x 7×7 Global Avg Pool 2048-d FC 1000 Softmax Output Total: 50 weighted layers | 25.6M parameters | Bottleneck blocks in Conv2–5

Intuition

The Mental Model

Think of climbing a mountain in thick fog, where at each step you have two options: (1) decide exactly where you want to stand on the entire mountain, or (2) decide only how much to move from where you already are. Option 2 is obviously easier — small corrections are simpler to learn than absolute positions. ResNet's residual blocks are option 2: every block asks "how should I adjust what I already have?" rather than "what should the output be from scratch?" A useful secondary analogy: think of a residual block as a surgeon making small corrections to a draft document. The draft (identity shortcut) flows straight through, and the surgeon (residual branch) adds only the minimum necessary edits. If no edits are needed, the surgeon adds nothing (pushes residuals to zero) — the draft is perfect as-is. In contrast, a plain network is like asking each surgeon to rewrite the entire document from scratch at every revision step. The gradient flow interpretation: imagine the backpropagation gradient as water flowing backward through a pipe network. In a plain deep network, every layer is a narrow constriction — the gradient (water pressure) drops at every bend. In ResNet, the shortcut connections are bypass pipes of unlimited width running in parallel. Water can always flow backward through the bypass, so pressure never drops to zero, no matter how many constrictions are in the main pipe.

Historical Development

Origins · 1 minhow this was discovered
History
1998: Yann LeCun's LeNet-5 demonstrates that depth helps in CNNs, but network sizes are limited by compute and the vanishing gradient problem.
2012: AlexNet (Krizhevsky, Sutskever, Hinton) wins ImageNet by a huge margin with 8 layers and ReLU activations, restarting the deep learning era in vision.
2014: VGGNet (Simonyan & Zisserman) pushes to 16–19 layers using uniform 3×3 convolutions, but training very deep networks remains unstable; GoogLeNet (Szegedy et al.) reaches 22 layers using inception modules.
2015 (Feb): Batch Normalization (Ioffe & Szegedy) is published, partially addressing instability in deep networks by normalizing layer inputs — a key enabler for ResNet's later training stability.
2015 (Dec): He et al. publish "Deep Residual Learning for Image Recognition" on arXiv, introducing ResNet-152 that wins ImageNet 2015 with 3.57% top-5 error — surpassing human-level performance (~5%) for the first time.
2016 (Jun): ResNet wins Best Paper at CVPR 2016. The paper becomes one of the most cited in AI history (>200,000 citations by 2024), validating residual learning across classification, detection (COCO), and segmentation tasks simultaneously.
2016: He et al. publish "Identity Mappings in Deep Residual Networks," analyzing pre-activation ResNets (BN→ReLU before convolution) and showing cleaner gradient flow; ResNeXt (Xie et al.) introduces grouped convolutions into residual blocks.
2017–2019: Wide ResNet, DenseNet (shortcut connections to all previous layers), SENet (Squeeze-and-Excitation with channel attention), and EfficientNet all build directly on the residual paradigm.
2020–present: Vision Transformers (ViT) incorporate residual connections as a core architectural feature in every transformer block; hybrid architectures like ConvNeXt re-examine pure-CNN design and adopt transformer-inspired training recipes while retaining residual structure.

Why It Matters

Real-World Impact
ImageNet ClassificationResNet-50 achieves ~76% top-1 accuracy and is the default backbone in virtually every vision framework (torchvision, timm, Keras Applications), making it the "MNIST of backbone benchmarking."
Object Detection — Faster R-CNN / Mask R-CNNFacebook AI Research's Detectron uses ResNet-50/101 as the Feature Pyramid Network (FPN) backbone; virtually every modern object detector (YOLO v4–v8, DETR, Cascade R-CNN) defaults to a ResNet backbone for feature extraction.
Medical ImagingResNet-based models (e.g., CheXNet, a 121-layer DenseNet variant) detect pneumonia from chest X-rays at radiologist-level performance; ResNet-50 is the standard backbone in FDA-cleared diabetic retinopathy screening systems.
Face RecognitionArcFace, CosFace, and most production face recognition systems (Apple FaceID's server-side pipeline, Megvii Face++) use ResNet-50/100 backbones trained with margin-based softmax losses.
Self-Driving PerceptionTesla Autopilot's HydraNet (multi-task vision network) and Waymo's PerceptionNet use ResNet-derived residual backbones to simultaneously segment lanes, detect objects, and estimate depth from camera streams.
Foundation Model BackbonesCLIP (OpenAI) offers a ResNet-50/101/50×4/50×16/50×64 vision encoder variant alongside ViT; DALL·E's VQVAE encoder uses residual blocks; Stable Diffusion's VAE encoder/decoder is