Lensa ML

Pooling & Downsampling

Step 1 of 6: Why Pool?

Reducing spatial dimensions

Feature Map Size8
Input: 8×82×2 poolPooled: 4×4
Original cells
64
Pooled cells
16
Reduction
75%

A 8×8 map has 64 cells. After 2×2 pooling it shrinks to 16, a 75% cut in the cells later layers must process.

Drag Feature Map Size from 4 to 16. A 2×2 pool with stride 2 keeps one value per window, so each pooling layer cuts the cell count by about 75%. This demo rounds odd sizes up, so 7×7 becomes 4×4. Frameworks usually round down by default (ceil_mode=False in PyTorch), giving 3×3. Pooling has no weights and costs little itself; the savings come in the layers after it, whose cost scales with the map's area. VGG-16 uses five 2×2 max-pooling layers to take a 224×224 input down to 7×7.

Step 2 of 6: Max Pooling

Keep the strongest signal

Pool Size
Window Position0
Input 8×81187139459324639225094477065301471551596854556513095627302614520Max Pool Output9869769785693967
Pool Size
2×2
Window Max
9
Output Size
4×4

The 2×2 window picks the maximum value (9) from each region. This preserves the strongest activation and discards weaker ones.

Click 2×2 or 3×3, then drag Window Position to move the highlighted window across the 8×8 map. In backpropagation, the gradient of a max-pool output flows only to the cell that held the maximum, and every other cell in the window gets zero. Frameworks store the position of each maximum during the forward pass for this reason. With 3×3 windows and stride 3, only 6 of the 8 rows and columns fit, so the last two are dropped. AlexNet used overlapping max pooling instead: 3×3 windows with stride 2.

Step 3 of 6: Average Pooling

Smooth aggregation

Pool Size
Window Position0
Input1187139459324639225094477065301471551596854556513095627302614520Max Pool9869769785693967Avg Pool453.56.32.84445.34.84.35.31.35.34.33
Max Value
9
Avg Value
4
Difference
5.0

Max pooling picks the peak (9) while average pooling smooths to 4. Max is better for detecting sharp features; average preserves overall intensity.

Click 2×2 or 3×3 and drag Window Position, comparing the Max Value and Avg Value cards. Average pooling sends an equal share of the gradient, 1/k² of it, to every cell in a k×k window, so all inputs keep learning. LeNet-5 (1998) used a trainable form of average pooling that it called subsampling. Max pooling replaced it in most CNNs because it worked better at signaling whether a feature is present anywhere in the window. Average pooling survives in global form and where a smooth, low-aliasing downsample matters.

Step 4 of 6: Stride & Overlap

Controlling output size

Stride2
Window Position0
Input 8×8 — stride 21187139459324639225094477065301471551596854556513095627302614520Output 4×49869769785693967
Stride
2
Output Size
4×4
Overlap?
No

Stride 2 with a 2×2 pool gives non-overlapping windows, the most common setting. Each cell is read exactly once, and the size halves.

Drag Stride from 1 to 4, and drag Window Position to step through the windows. The output width is ⌊(W − k)/s⌋ + 1 for input width W, window size k and stride s. With W = 8 and k = 2, that gives 7, 4, 3 and 2 for strides 1 to 4. Padding adds p cells on each side, so the formula becomes ⌊(W + 2p − k)/s⌋ + 1. The same formula gives the output size of a convolutional layer.

Step 5 of 6: Global Average Pooling

Collapse to a vector

Number of Channels4
4 feature maps (4×4) → 4 scalars via GAP0.60.40.30.10.50.00.30.71.00.30.90.30.20.70.50.70.470.70.90.80.71.00.30.20.90.50.40.10.90.50.90.90.10.610.10.60.70.00.60.40.30.40.80.20.60.10.60.10.50.10.370.70.90.30.70.40.20.10.00.10.80.30.20.80.70.30.90.47FC → Classes
Channels
4
Input values
64
After GAP
4
Reduction
16×

Each of the 4 feature maps is averaged into a single number, producing a 4-d vector. The spatial dimensions disappear, so the next dense layer stays small.

Drag Number of Channels from 1 to 6. Each 4×4 map becomes its mean, so C channels become a C-dimensional vector. Global average pooling was introduced in Network in Network (Lin et al., 2013) as a replacement for fully connected layers. ResNet-50 ends with a 7×7×2048 feature map: flattening it would feed 100,352 values to the classifier, while GAP feeds 2,048. Because GAP ignores spatial size, the network accepts different image resolutions. The classifier weights on each map also give class activation maps (CAM).

Step 6 of 6: Pooling vs Strided Conv

Fixed vs learned downsampling

Compare
Input 6×6266666643096686021643411871394593246Max Pool2×2, s=2Output6698629390 paramsKernel 3×30.40.80.60.50.9-0.3-0.50.70.1Conv3×3, s=2Output18717191111910149 params
Pool Params
0
Conv Params
9
Learnable?
No
Output Size
3×3

Max pooling is a fixed operation that takes the maximum in each 2×2 window. It has zero parameters and is fast, but it cannot learn what information to keep.

Click Max Pool or Strided Conv to compare the two paths on the same 6×6 input. Both give a 3×3 output. The 3×3 kernel here has 9 weights for its single input channel. Across 16 input channels it would have 144 weights per output channel, and a real layer has many output channels: 64 of them need 9,216 weights before biases. Springenberg et al. (2014) found that replacing max pooling with strided convolutions lost no accuracy on several benchmarks. ResNet downsamples with stride-2 convolutions inside its blocks, and Vision Transformers split the image into patches instead of pooling.

What is pooling in a CNN?

Pooling is a CNN operation that shrinks a feature map by summarizing each small window of values with one number, usually the maximum (max pooling) or the mean (average pooling). It has no learned weights. A 2×2 pool with stride 2 halves the width and height of every channel and keeps 25% of the values.

Pooling layers appear in classic image classifiers such as LeNet, AlexNet and VGG, where they cut computation and make the network tolerant of small shifts in the input. Modern architectures still use global average pooling to turn the final feature maps into a vector for the classifier, and many have replaced the intermediate pooling layers with strided convolutions.

Key ideas

  • Pooling summarizes each window of a feature map with a single number and has no learned weights.
  • Max pooling keeps the strongest activation in each window, and average pooling keeps the mean.
  • A 2×2 pool with stride 2 halves height and width and keeps 25% of the values.
  • The output width is ⌊(W − k)/s⌋ + 1 for input width W, window size k and stride s.
  • Global average pooling turns each channel into one number, giving a fixed-length vector for the classifier.
  • Strided convolutions can replace pooling with downsampling the network learns.

Common questions

Does pooling make CNNs translation invariant?

Only partly. A feature that moves within one pooling window gives the same max, so small shifts are absorbed, but a shift across a window boundary can change the output. Zhang (2019) showed that standard CNNs are not shift invariant and added a blur before downsampling (anti-aliased pooling) to fix much of the problem.

Does a pooling layer have trainable parameters?

No. Max and average pooling are fixed functions of their input, so they add no weights to the model. Gradients still pass through them during backpropagation, which is why pooling layers sit between trainable convolutional layers without blocking learning.

What is adaptive pooling?

Adaptive pooling takes a target output size instead of a window size and picks the windows to fit. PyTorch's AdaptiveAvgPool2d((1, 1)) is global average pooling for any input size, and AdaptiveAvgPool2d((7, 7)) lets a classifier head accept images of different resolutions.

What is RoI pooling in object detection?

RoI (region of interest) pooling, from Fast R-CNN, crops the feature map to each proposed box and max-pools it into a fixed grid such as 7×7. Every box, whatever its size, then produces a feature vector of the same length for the classification and box-regression heads. Mask R-CNN replaced it with RoIAlign, which avoids rounding the box coordinates.

Related explainers

References

  1. Lin, Chen & Yan (2013), "Network In Network"
  2. Springenberg et al. (2014), "Striving for Simplicity: The All Convolutional Net"
  3. Zhou et al. (2016), "Learning Deep Features for Discriminative Localization", CVPR
  4. Zhang (2019), "Making Convolutional Networks Shift-Invariant Again", ICML
  5. Stanford CS231n, "Convolutional Neural Networks for Visual Recognition" course notes

Last updated