17 · Padding + pooling: controlling spatial dimensions
Padding preserves spatial size after convolution; max pooling deliberately shrinks it — together they give precise control over feature map dimensions.
Padding preserves input size after convolution; pooling deliberately reduces it to extract dominant features.
Without this:
Without padding, each conv shrinks the image; without pooling, you can't build deep CNNs that downsample to a final feature vector.
Every convolution with a kernel larger than 1×1 shrinks the spatial dimensions of the feature map. Apply 10 consecutive 3×3 convolutions to a 32×32 image and you end up with a 12×12 feature map — fine for some architectures, but impractical when you need to stack many layers without collapsing the spatial dimensions prematurely.
Padding solves this by adding a border of zeros around the input before the convolution. The most common choice is "same" padding (also called padding=1 for a 3×3 kernel), which adds exactly enough zeros so the output matches the input spatial size.
With same padding, a 3×3 kernel at stride 1 always produces output of the same height and width as the input. This lets you stack as many conv layers as you want without worrying about spatial shrinkage — a prerequisite for deep networks like VGG (19 layers) and ResNet (152 layers).
Pooling then provides the intentional spatial downsampling. Max pooling divides the feature map into non-overlapping windows (typically 2×2) and takes the maximum value in each window. This:
- Halves the spatial dimensions (2×2 → 1×1 per window).
- Retains the strongest activation in each neighbourhood — the most prominent feature detected.
- Adds partial translation invariance: if a feature shifts by 1 pixel within a pooling window, the output is unchanged.
Average pooling takes the mean instead of the max — smoother, but often less effective for tasks where detecting the presence of a feature matters more than its average strength.
Python (in browser)
Python runs entirely in your browser via Pyodide (~6 MB on first Run, cached after).
Python (in browser)
Python runs entirely in your browser via Pyodide (~6 MB on first Run, cached after).
Python (in browser)
Python runs entirely in your browser via Pyodide (~6 MB on first Run, cached after).
Full output-shape formula including padding, and same-padding rule
PyTorch read-along: Conv2d with padding, MaxPool2d, AdaptiveAvgPool2d
What is the main purpose of max pooling in a CNN?
- Same padding (pad=1 for k=3) preserves spatial size through convolutions — enabling arbitrarily deep stacking without spatial collapse.
- Full shape formula: out = (in + 2*pad - k) / stride + 1. Same padding: pad = (k-1)/2.
- Max pooling: keeps strongest activation per 2×2 window, halves spatial dims, adds partial translation invariance, zero extra parameters.
- Global Average Pooling (AdaptiveAvgPool2d(1)) collapses spatial dims entirely, producing a fixed-size vector — used in ResNet and EfficientNet as the classifier bridge.
Every CNN block pattern is Conv → BatchNorm → ReLU → (occasional MaxPool). The pooling layers steadily reduce spatial dims while convolutions extract features.
If you remove it: Without padding, deep stacking collapses spatial dims to zero. Without pooling, you have no principled way to reduce the feature map to a fixed-size vector for the classifier head.