Majid Al-RaimiPooling and what CNN filters learn

COE 592Lecture 02Part 04

Pooling and what CNN filters learn

Parameter-free downsampling with max and average pooling, the feature hierarchy a CNN learns, and two interactive demos.

Concepts
4
Slides
21-26
Reading
24 min
Understood
0/4 concepts

Why this part matters

Pooling is the cheapest layer you will ever deploy: zero parameters, four times fewer activations, and it is therefore the first tool for fitting a CNN into microcontroller SRAM. The feature hierarchy that follows it explains why pruning, quantization and transfer learning treat early and late layers differently.

The two skills this part drills are pure counting: the output shape of a pooling layer and the parameter count of a convolution layer. That same counting is the first step of every embedded model budget, because parameters set flash and activation shapes set SRAM. The two browser demos at the end give you the numbers layer by layer so you can check yourself.

By the end you can

  1. Compute the output shape of any pooling layer from W1, H1, C, F and S, and state why its parameter count is zero.
  2. Evaluate max and average pooling by hand on a small slice and explain the small translation invariance max pooling brings.
  3. Describe the edges, parts, objects feature hierarchy and tie it to receptive-field growth through CONV-RELU-POOL blocks.
  4. Count the parameters of a conv layer from its filter shape, including biases, as in the ConvNetJS first layer.
  5. Chain shapes through a real small network (CNN Explainer) and separate the layers that cost parameters from those that cost only activations.

A VGG-style block hands the next layer a volume of 224 x 224 x 64, which is 3,211,264 activations. A 2 x 2 pool with stride 2 returns 112 x 112 x 64, which is 802,816. Nothing was learned, nothing was mixed across channels, and every one of the 64 maps was simply shrunk on its own. That is the whole job of a Pooling layer.

The rule behind the example: a pooling layer applies a fixed summary over a small window of each activation map, one map at a time. Two summaries are common. Max pooling keeps the largest value in the window, and Average pooling keeps the mean. Because the summary is computed inside one Channel and never across channels, the depth of the volume is preserved while the spatial size falls. Pooling is therefore the second Downsampling tool of this lecture, next to Stride, and its output is a smaller Feature map per channel.

A 2x2 window sweeps one map of the 224x224x64 volume; the pooled volume is a quarter of the area with the same 64-deep edge

Slide 21 pinned as shapes

Input
224 x 224 x 64
Spatial extent F, stride S
2, 2
Output
112 x 112 x 64
Channels
Unchanged, 64 in and 64 out
Activations
3,211,264 to 802,816 (75% discarded)
Learned parameters
0

Why max pooling is the default, and why that is a heuristic

Pooling of any kind brings an approximate translation invariance, and max pooling shows it most sharply, which is why slide 21 attaches "Introduces spatial invariance" to max pooling. Goodfellow, Bengio and Courville describe pooling in all its forms as making the representation "approximately invariant to small translations of the input": if the input shifts by a pixel, the values of most pooled outputs do not change, because the maximum is still inside its window. Their example is face detection, where the network need not know the location of the eyes with pixel-perfect accuracy, only that there is an eye on each side. They also point out that pooling regions spaced k pixels apart give the next layer roughly k times fewer inputs to process, which is the memory saving your microcontroller will feel.

Max poolingAverage pooling
What it returnsThe largest value in the windowThe mean of all values in the window
What it is sensitive toOne strong activation anywhere in the windowEvery value equally, so a strong spike is diluted
Effect of a one-cell shiftUsually none, if the maximum stays inside the windowSmall change, the average moves slightly
Gradient in the backward passRouted to the argmax cell onlySpread equally, 1/F² to every cell
Typical place in a networkInside the trunk after a conv blockGlobal average pooling as the classifier head
Max pooling against average pooling

Slide 21 goes further and says max pooling "performs a lot better" because it discards noisy activations. Treat that as the slide's heuristic, not a law. Boureau, Ponce and LeCun analysed the two in 2010 and found that which one wins depends on how sparse the features are and how large the pool is; they note that earlier comparisons had been "purely empirical". CS231n states more cautiously that max pooling "has been shown to work better in practice". And the field has partly moved on: Springenberg et al. showed in 2014 that max pooling "can simply be replaced by a convolutional layer with increased stride without loss in accuracy", and Lin, Chen and Yan's Network in Network replaced the fully connected head with global average pooling, which they found "less prone to overfitting". ResNet and MobileNet families follow that pattern: strided convolutions inside, a single global average pool at the end.

Recall

A 224x224x64 volume passes through max pooling with F = 2 and S = 2. What are the output shape and the number of learned parameters?

112 x 112 x 64, from (224 - 2)/2 + 1 = 112 in each spatial dimension with the depth unchanged. Parameters: 0, because max is a fixed function with nothing to fit.

Quick check

A 56x56x128 volume passes through max pooling with a 2x2 window and stride 2. What does it output?

Take the single depth slice from slide 22, a 4 x 4 grid, and pool it with a 2 x 2 window and Stride 2. The window lands in four places and never overlaps itself, so the four coloured quadrants of the slide are the four windows. Each quadrant becomes one output cell.

WindowValuesMaxMean
Top left (pink on the slide){1, 1, 5, 6}613 / 4 = 3.25
Top right (green){2, 4, 7, 8}821 / 4 = 5.25
Bottom left (yellow){3, 2, 1, 2}38 / 4 = 2
Bottom right (blue){1, 0, 3, 4}48 / 4 = 2
Slide 22 window by window

Read the two results as grids. Max pooling gives [[6, 8], [3, 4]] and Average pooling gives [[3.25, 5.25], [2, 2]]. Notice what each one threw away. Max kept only the argmax cell of each window (the 6, the 8, the 3, the 4) and forgot the other three values entirely. Mean kept a trace of all four but flattened the 8 down to 5.25.

Each window's largest cell lights and sends its value to the max grid; a second sweep writes the means

The general rule

Let the input be W1 x H1 x C. A Pooling layer needs exactly two hyperparameters, the spatial extent F of the window and the stride S, and it produces W2 x H2 x C.

W2=W1FS+1,H2=H1FS+1,C2=C1W_2 = \frac{W_1 - F}{S} + 1, \qquad H_2 = \frac{H_1 - F}{S} + 1, \qquad C_2 = C_1
Same shape rule as a convolution with no padding, applied to every channel
parameters=0\text{parameters} = 0
Max and mean are fixed functions; there is nothing to fit

The shape formula is the convolution formula from part 03 with p = 0 and the kernel size renamed to F. PyTorch writes the same rule in its general form, H_out = floor((H_in + 2p - d(F - 1) - 1)/S + 1), with the stride defaulting to the kernel size, so MaxPool2d(2) means F = 2, S = 2 (PyTorch docs). The floor matters when the division is not exact, and the second worked example shows why.

The zero comes from what pooling does in the backward pass. CS231n notes that a pooling layer "introduces zero parameters since it computes a fixed function of the input". Implementations keep the index of the maximum, the "switch", so the gradient is routed to exactly one cell per window in max pooling; in average pooling it is spread as 1/F² to each cell. Either way the layer has no Weight and no Bias, so it adds nothing to the Parameter count.

Worked example

224 to 112, the slide 21 numbers

  1. Substitute into the width formula

    W2 = (224 - 2)/2 + 1 = 111 + 1 = 112. The height is identical.
  2. Carry the depth across

    C2 = C1 = 64, because the window only ever looks inside one channel.
  3. Count the activations

    Before: 224 x 224 x 64 = 3,211,264. After: 112 x 112 x 64 = 802,816. Exactly one quarter survives; CS231n phrases it as "discards exactly 75% of the activations in an input volume".
  4. Result

    Output 112 x 112 x 64, 0 parameters, 75% of runtime memory for that tensor gone.

Worked example

Why F = 3, S = 2 needs care

  1. Overlapping pool on 224

    (224 - 3)/2 + 1 = 111.5. Not an integer: the last window would hang off the edge. PyTorch floors to 111 by default and rounds up to 112 only with ceil_mode=True.
  2. The AlexNet case that does divide

    AlexNet pools 55 x 55 maps with F = 3, S = 2: (55 - 3)/2 + 1 = 27, a clean integer, which is why that configuration is famous.
  3. Rule of thumb

    Check that (W1 - F) divides by S. If it does not, state the floor explicitly.

Changing F and S on the same 4 x 4 slice shows how strongly the two hyperparameters shape the result. The values below are max pooling; the simulator lets you check the means.

F, SW2OutputValuesWhat happened
F = 2, S = 2(4 - 2)/2 + 1 = 22 x 2[[6, 8], [3, 4]]Windows tile the input, 75% of activations dropped
F = 2, S = 1(4 - 2)/1 + 1 = 33 x 3[[6, 7, 8], [6, 7, 8], [3, 3, 4]]Windows overlap, the row 6, 7, 8 appears twice
F = 3, S = 1(4 - 3)/1 + 1 = 22 x 2[[7, 8], [7, 8]]Nine cells per window, the small values vanish
F = 3, S = 2(4 - 3)/2 + 1 = 1.51 x 1 (floored)[[7]]Not an integer, PyTorch floors and drops the last row and column
Four configurations on the slide 22 slice, max pooling
SimulatorSlide 22, every window at once
W2 = (4 - 2) / 2 + 1 = 2
Input 4×4×1
4 windows of 2×2
Output 2×2×1
This window
hover an output cell
Input W1 × H1 × C
4 × 4 × 1
Output W2 × H2 × C
2 × 2 × 1
Learned parameters
0
Activations in, out
16 to 4 (75% discarded)
Every input cell is editable, negative and decimal values included. Each window keeps one colour in the input and in the output; hovering an output cell brightens the winning cell for max pooling and the whole window for average pooling.

Recall

Compute max and mean pooling with F = 2, S = 2 on [[1,1,2,4],[5,6,7,8],[3,2,1,0],[1,2,3,4]].

Max: [[6, 8], [3, 4]]. Mean: [[3.25, 5.25], [2, 2]]. The output is 2 x 2 because (4 - 2)/2 + 1 = 2.

Quick check

Why does a pooling layer add nothing to a network's parameter count?

From edges to objects: what the filters learn

The grid on slide 23 comes from Lee, Grosse, Ranganath and Ng (ICML 2009), who learned a first layer of edge detectors from natural images once, then trained the second and third layers of a convolutional deep belief network separately on unlabeled Caltech-101 images of faces, cars, elephants and chairs, and visualized what each layer responds to. Their own summary: the first, second and third layers "learn edge detectors, object parts, and objects respectively". Look at the bottom row of the slide. It is the same across all four columns because that first layer was learned once from natural images: small oriented edges like Gabor patches. The middle row diverges into eyes and noses, wheels and bumpers, tusks and ears, chair legs and backs. The top row shows entire faces, cars, elephants and chairs.

Three tiers light up bottom to top: edges, then parts, then whole objects, joined by upward arrows

This ladder is the Feature hierarchy, and it is not designed by hand. Every Convolution layer runs the same operation with a small Kernel (filter). What changes with depth is the Receptive field: a first-layer unit sees only its k x k patch of pixels, so the most it can detect is an edge. A second-layer unit sees a k x k patch of first-layer responses, which covers a larger region of the image (L(k - 1) + 1 pixels after L stride-1 layers, faster with stride or pooling), so it can combine edges into a curve or an eye. Deep units cover most of the image and can match a whole face. Zeiler and Fergus confirmed in 2013 that the same ladder appears inside a supervised ImageNet CNN, using a deconvolutional visualization of intermediate layers.

TierLayersWhat the filters respond toReceptive field, roughly
Low levelFirst convolution layersOriented edges, bars, blobs, colour opponents3 x 3 to 11 x 11 pixels (the first kernel size)
Mid levelMiddle layersCurves, corners, eyes, wheels, tusks, chair legstens of pixels
High levelDeepest layersWhole faces, cars, elephants, chairsmost of the image
The three tiers

The mechanism in action: slide 24

Slide 24 shows a network of the pattern [CONV, RELU, CONV, RELU, POOL] repeated three times and then a fully connected layer, run on a photo of a car. Each column is the activation maps of one layer. Read them left to right and the hierarchy appears live: the first columns look like edge-filtered copies of the car, the middle columns are sparse and blotchy, and the last columns are tiny grids that no longer resemble the photo at all.

Block 1
full size

Two convs with ReLU, then pool: edges and colour blobs.

pool halves
Block 2
half size

Same pattern on the smaller maps: corners, wheels, parts.

pool halves
Block 3
quarter size

Coarse maps whose units see most of the image.

flatten
FC
class scores

car, truck, airplane, ship, horse; car wins.

CONV-RELU-CONV-RELU-POOL three times, then FC

The ReLU after each conv keeps only positive responses, which is why the columns after it are darker. Each POOL halves the Feature map and, because the next block's k x k window now covers twice as many original pixels, pushes the receptive field outward. Two pools have already halved the maps twice, so the third block works on maps one quarter the width of the input, and the third pool leaves the fully connected layer maps one eighth the width; that is why the last units can see a whole car. The Fully connected layer at the end reads every unit of the final maps at once and produces one score per class. On the slide, car scores highest, well above truck, then airplane, ship and horse.

A pulse runs down the 16-layer chain; chips shrink after each pool, and the FC bars grow with car reaching full width

Why this matters on an embedded device

The hierarchy explains a pattern you will meet throughout this course. Early layers have few parameters (a 5 x 5 x 3 filter is 75 weights) but large activation maps; late layers have many parameters but tiny maps. So SRAM pressure comes from the front of the network and flash pressure from the back, and pruning or quantizing them calls for different budgets. Transfer learning on the edge uses the hierarchy directly: the edge and part detectors are generic, so you freeze the low tiers and retrain only the top.

Recall

Name the three tiers of the feature hierarchy with one example each, and say what property of deep layers makes the top tier possible.

Edges (oriented bars), object parts (eyes, wheels, tusks), whole objects (faces, cars, elephants). The receptive field grows with depth and pooling, so only deep units see enough of the image to match an object.

Quick check

In the feature hierarchy, what do the deepest convolution layers respond to?

Two browser demos as counting practice

Open the ConvNetJS CIFAR-10 demo and read its first conv block. It prints "conv (32x32x16), filter size 5x5x3, stride 1, parameters: 16x5x5x3+16 = 1216". That one line is a complete exam answer, and it is worth rebuilding by hand.

Worked example

The ConvNetJS first conv layer

  1. Weights

    16 filters, each 5 x 5 and 3 deep to match the RGB input: 16 x 5 x 5 x 3 = 1200 weights.
  2. Biases

    One Bias per filter, so 16.
  3. Why the map stays 32 x 32

    The demo's layer definition uses pad 2: (32 + 2·2 - 5)/1 + 1 = 32. With Padding equal to (F - 1)/2, a stride-1 conv keeps its size.
  4. Result

    1200 + 16 = 1216 parameters, output 32 x 32 x 16, which is 16,384 activations for one image.

The ConvNetJS CIFAR-10 demo

Dataset
CIFAR-10: 60,000 colour images of 32 x 32, 10 classes, 50,000 train and 10,000 test (Krizhevsky)
Classes
airplane, automobile, bird, cat, deer, dog, frog, horse, ship, truck
Accuracy quoted on the page
state of the art "about 90%", humans "about 94%" (2014 figures; current models exceed 99%)
Augmentation
random flips and random shifts of up to 2 px
Optimizer
Adadelta, batch size 4, L2 decay 0.0001

The whole demo network is small enough to count in full. Two things to watch: every conv filter is as deep as the channels feeding it, and the three pooling layers contribute nothing to the total while cutting the activations by four each time.

LayerOutputParametersNote
input32 x 32 x 30Raw CIFAR-10 image
conv, 16 filters 5x5x3, pad 232 x 32 x 1616 x 5 x 5 x 3 + 16 = 1216The count printed on slide 25
max pool 2x2, stride 216 x 16 x 160Activations cut by 4x
conv, 20 filters 5x5x16, pad 216 x 16 x 2020 x 5 x 5 x 16 + 20 = 8020Depth of the filter equals the input channels
max pool 2x2, stride 28 x 8 x 200
conv, 20 filters 5x5x20, pad 28 x 8 x 2020 x 5 x 5 x 20 + 20 = 10020
max pool 2x2, stride 24 x 4 x 200
softmax, 10 classes10320 x 10 + 10 = 3210The only layer whose count depends on image size
Total22,466Three pools contribute nothing
Every ConvNetJS layer, output shape and parameters

The total is 22,466 parameters. The softmax layer is the only one whose count depends on the image size, because it reads the flattened 4 x 4 x 20 = 320 activations; every conv layer's count depends only on its filter shape, which is Weight sharing at work.

CNN Explainer as retrieval practice

CNN Explainer (Wang et al., IEEE VIS 2020) runs a network the authors call Tiny VGG on ten classes: lifeboat, ladybug, pizza, bell pepper, school bus, koala, espresso, red panda, orange and sport car. Its training code uses 3 x 3 convolutions with 10 filters and no padding ("valid"), and 2 x 2 max pools with stride 2. The input is 64 x 64 x 3. Before you look at the table, chain the shapes yourself: a valid conv subtracts 2, a pool halves.

Recall

Chain the CNN Explainer shapes from 64x64x3 to the second pool.

64 - 3 + 1 = 62, 62 - 3 + 1 = 60, pool 60/2 = 30, 30 - 3 + 1 = 28, 28 - 3 + 1 = 26, pool 26/2 = 13. All with 10 channels. Flatten: 13 x 13 x 10 = 1690.
LayerShape formulaOutputParameters
input64 x 64 x 30
conv_1_1, 10 filters 3x3, valid64 - 3 + 162 x 62 x 1010 x 3 x 3 x 3 + 10 = 280
conv_1_2, 10 filters 3x3, valid62 - 3 + 160 x 60 x 1010 x 3 x 3 x 10 + 10 = 910
max_pool_1, 2x2, stride 2(60 - 2)/2 + 130 x 30 x 100
conv_2_1, 10 filters 3x3, valid30 - 3 + 128 x 28 x 10910
conv_2_2, 10 filters 3x3, valid28 - 3 + 126 x 26 x 10910
max_pool_2, 2x2, stride 2(26 - 2)/2 + 113 x 13 x 100
flatten, dense 10, softmax13 x 13 x 10 = 1690101690 x 10 + 10 = 16,910
Total19,920
Tiny VGG, layer by layer

The pattern repeats: 19,920 parameters, of which the two pools contribute 0 while each removes three quarters of the activations. The dense layer holds 16,910 of the total because it multiplies the image-dependent 1690 by the ten classes. Click any activation map in the live page and it animates the window that produced it, which is the pooling and convolution arithmetic of this lecture rendered one cell at a time.

Recall

How many parameters does the ConvNetJS first conv layer hold, and why does the map stay 32x32?

16 x 5 x 5 x 3 + 16 = 1216. The demo pads by 2, so (32 + 4 - 5)/1 + 1 = 32.

Quick check

In the ConvNetJS CIFAR-10 demo the first conv layer has 16 filters of 5x5x3. How many parameters does it hold?

Quick check

In CNN Explainer, conv_1_2 outputs 60x60x10. What does max_pool_1 with a 2x2 window and stride 2 output?

Recap

If you remember nothing else

  • Pooling summarizes a window in each activation map independently: spatial size drops, channel count stays, 224x224x64 becomes 112x112x64.
  • W2 = (W1 - F)/S + 1, H2 = (H1 - F)/S + 1, depth C unchanged, parameters 0.
  • On the slide's 4x4 slice, F = 2 and S = 2 give max [[6,8],[3,4]] and mean [[3.25,5.25],[2,2]].
  • Max pooling adds approximate invariance to small shifts; 'max is always better' is a heuristic, and many modern networks use strided convolutions or global average pooling instead.
  • Filters form a hierarchy: edges in early layers, object parts in the middle, whole objects deep, because receptive fields grow with depth and pooling.
  • CONV-RELU-CONV-RELU-POOL repeated three times then FC turns an image into class scores; car beats truck, airplane, ship, horse.
  • ConvNetJS first layer: 16 x 5 x 5 x 3 + 16 = 1216 parameters; CNN Explainer shapes: 64, 62, 60, 30, 28, 26, 13.

Sources