CNN building blocks
Pooling, 1×1 convs, depthwise, dilated and transposed convolutions
Real networks are assembled from a small vocabulary of blocks: convolution + normalization + activation, pooling or strided downsampling, 1×1 channel mixers, and (for dense prediction) upsampling layers. Knowing the cost and purpose of each block lets you read ResNet, MobileNet or U-Net tables at a glance (5.3 Architectures: LeNet → AlexNet → VGG → Inception → ResNet → EfficientNet → ConvNeXt, 5.6 Segmentation), design networks that fit a latency budget, and recognize the same ideas inside transformers, where the feed-forward layer is a 1×1 convolution in disguise (7.4 Inside the block: residuals, LayerNorm, FFN and embeddings).
You'll be able to
- Describe the stem–stages–head anatomy of a CNN and how resolution and channels trade off
- Explain max/average/global pooling and when strided convolution replaces pooling
- Compute the cost of standard, 1×1, depthwise-separable and dilated convolutions, and the separable savings ratio
- Explain transposed convolutions, their output-size formula and checkerboard artifacts
- Count the parameters and FLOPs of a complete small CNN
Key ideas
- CNN anatomy: a stem that downsamples fast, stages that halve resolution while doubling channels (keeping compute roughly constant), and a GAP + linear head.
- Max pooling adds invariance and quarters downstream compute for free; strided convolutions learn their own downsampling and have replaced pooling in many designs.
- A 1×1 convolution is a per-pixel fully connected layer (C_in·C_out parameters) used for bottlenecks and cheap nonlinearity; the transformer FFN is the same operation on tokens.
Show 4 more key ideas
- Depthwise-separable cost ratio = 1/C_out + 1/k² ≈ 1/9 for 3×3 kernels — MobileNet, Xception and ConvNeXt's large depthwise kernels rest on this.
- Dilation grows receptive fields exponentially without downsampling: effective size k + (k−1)(d−1).
- Transposed convolution upsamples with output (n−1)s − 2p + k; kernel/stride mismatch causes checkerboard artifacts, so upsample+conv is often preferred.
- Parameters concentrate in FC layers, compute in conv layers — count both before trusting an architecture table.
Suggested path through this lesson
The anatomy of a CNN
Almost every CNN has three parts. A stem quickly reduces resolution (e.g., a stride-2 conv plus a stride-2 pool: ). A sequence of stages each halve the spatial size while roughly doubling the channels (56→28→14→7, channels 64→128→256→512), keeping the compute per stage roughly constant since cost scales with . A head collapses the final map with global average pooling into a -vector and applies a linear classifier. Total downsampling of (the output stride) is the classification default; dense-prediction tasks reduce it (5.6 Segmentation).
Pooling
Max pooling with a window and stride 2 keeps the strongest response in each window and halves both spatial dimensions (output size follows the usual formula with , ). It has no parameters, adds a little translation invariance (a feature shifted by one pixel still wins its window) and quarters the compute of everything downstream. Average pooling blurs instead of selecting. Global average pooling (GAP) averages each channel over all positions, turning a map into 2,048 numbers; introduced by Network-in-Network and used by GoogLeNet and ResNet, it removed the giant fully connected layers that held 90% of AlexNet's and VGG's parameters. Many modern nets drop pooling entirely and downsample with stride-2 convolutions, which learn how to downsample ("all convolutional" networks, ResNet stages).
1×1 convolutions
A convolution applies the same linear map to the channel vector at every pixel:
It mixes channels but not positions — a per-pixel fully connected layer with parameters. Uses: shrinking channels before an expensive (the bottleneck of ResNet-50, Inception), expanding them after, and adding nonlinearity cheaply. A transformer's position-wise feed-forward network is exactly this idea applied to tokens (7.4 Inside the block: residuals, LayerNorm, FFN and embeddings).
Depthwise-separable convolutions
A standard conv costs multiply-adds because every filter mixes all channels and all positions at once. Factor it into two steps: a depthwise conv (one filter per input channel, no mixing across channels) costing , then a pointwise conv mixing channels at . The ratio of separable to standard cost is
For and : , about cheaper, with a similar saving in parameters. This is the engine of MobileNet and Xception (5.3 Architectures: LeNet → AlexNet → VGG → Inception → ResNet → EfficientNet → ConvNeXt) and of the large-kernel () depthwise layers in ConvNeXt — once mixing is cheap, big spatial kernels become affordable.
Dilated (atrous) convolutions
Insert zeros between kernel taps. A kernel with dilation covers pixels while still using weights. Stacking dilations 1, 2, 4, 8 grows the receptive field exponentially without any downsampling — WaveNet uses this in 1-D (6.8 Project: character-level language model) and DeepLab in 2-D for segmentation, where you want context and full resolution (5.6 Segmentation).
Transposed convolutions: learning to upsample
Segmentation, autoencoders (4.10 Autoencoders, embeddings and representation learning) and GAN generators (8.8 Generative models I: VAEs and GANs) must go from a small map back to a large one. A transposed convolution (sometimes misnamed "deconvolution") is the adjoint of a strided convolution: each input value is multiplied by the kernel and scattered into an output region, with overlaps summed. Its output size inverts the conv formula:
For : . When is not divisible by the overlaps are uneven, producing checkerboard artifacts; the standard fix is nearest/bilinear upsampling followed by an ordinary conv, or pixel shuffle. Recall from 5.1 Convolution: the operation and its math that the gradient of a convolution with respect to its input is a transposed convolution — the two operations are a matched pair.
Normalization and activation placement
The canonical block is conv → BatchNorm → ReLU (4.6 Initialization and normalization, 4.2 Activation functions). At inference BatchNorm folds into the preceding conv's weights and bias, so it is free. Modern blocks (ConvNeXt) use LayerNorm and GELU, following transformers, and place a single activation per block rather than one after every conv.
Worked example: counting a LeNet-style network
Input (MNIST). Layers: conv , 6 filters, padding 2 → ReLU → maxpool 2 → conv , 16 filters → ReLU → maxpool 2 → flatten → FC 120 → FC 84 → FC 10.
| layer | output shape | parameters | multiply-adds |
|---|---|---|---|
| conv1 (1→6, 5×5, p=2) | 6×28×28 | 6·(25+1) = 156 | 28·28·6·25 = 117,600 |
| pool 2×2 | 6×14×14 | 0 | — |
| conv2 (6→16, 5×5) | 16×10×10 | 16·(150+1) = 2,416 | 10·10·16·150 = 240,000 |
| pool 2×2 | 16×5×5 | 0 | — |
| fc1 (400→120) | 120 | 400·120+120 = 48,120 | 48,000 |
| fc2 (120→84) | 84 | 10,164 | 10,080 |
| fc3 (84→10) | 10 | 850 | 840 |
| total | 61,706 | ≈ 0.42 M |
Two lessons jump out: the fully connected layers hold 96% of the parameters but only 14% of the compute, while the convolutions are the reverse. This is why GAP replaced FC layers (parameters) and why architecture work focuses on the conv stages (compute). Use the same accounting on any network table — 4.12 Compute, hardware and scale basics extends it to memory and transformers.
Where this shows up later
- Bottlenecks, GAP, depthwise convs and large kernels in the architecture timeline — 5.3 Architectures: LeNet → AlexNet → VGG → Inception → ResNet → EfficientNet → ConvNeXt.
- Upsampling and skip connections in U-Net and Mask R-CNN — 5.6 Segmentation; feature pyramids in detection — 5.5 Object detection.
- The transformer FFN as a 1×1 convolution over tokens — 7.4 Inside the block: residuals, LayerNorm, FFN and embeddings; dilated causal convs in WaveNet — 6.8 Project: character-level language model; transposed convs in GAN generators — 8.8 Generative models I: VAEs and GANs.
Common pitfalls (4)
- Calling a transposed convolution a 'deconvolution' and expecting it to invert a convolution — it only inverts the shape, not the values.
- Forgetting that pooling changes the output-size arithmetic for every layer after it; recompute shapes layer by layer (or print them).
- Assuming fewer FLOPs means faster: depthwise convolutions are memory-bound and can be slower per FLOP on GPUs than dense 3×3 convs.
- Leaving BatchNorm in training mode at inference (batch statistics instead of running stats) — use model.eval().
Recap: all 7 key points
- CNN anatomy: a stem that downsamples fast, stages that halve resolution while doubling channels (keeping compute roughly constant), and a GAP + linear head.
- Max pooling adds invariance and quarters downstream compute for free; strided convolutions learn their own downsampling and have replaced pooling in many designs.
- A 1×1 convolution is a per-pixel fully connected layer (C_in·C_out parameters) used for bottlenecks and cheap nonlinearity; the transformer FFN is the same operation on tokens.
- Depthwise-separable cost ratio = 1/C_out + 1/k² ≈ 1/9 for 3×3 kernels — MobileNet, Xception and ConvNeXt's large depthwise kernels rest on this.
- Dilation grows receptive fields exponentially without downsampling: effective size k + (k−1)(d−1).
- Transposed convolution upsamples with output (n−1)s − 2p + k; kernel/stride mismatch causes checkerboard artifacts, so upsample+conv is often preferred.
- Parameters concentrate in FC layers, compute in conv layers — count both before trusting an architecture table.
Watch
Second half: pooling, the full layer pattern and the parameter arithmetic that this lesson's worked example mirrors.
Read
Try it live
Interactive demo
runs in your browserExercises
- Count a ResNet-18 by hand
Using the ResNet paper's table (18-layer column), compute the output shape, parameters and multiply-adds of every stage for a input. Expected totals: about 11.7 M parameters and 1.8 G multiply-adds. Check with
torchinfo.summary. - Separable vs standard
Implement a conv from 128 to 256 channels on a map both as
nn.Conv2dand as depthwise (groups=128) + pointwise. Verify the parameter ratio is close to . Time both on CPU and (if available) GPU — note that FLOP savings and wall-clock savings differ. - Transposed convolution shapes
Predict the output size of
nn.ConvTranspose2d(16, 8, kernel_size=4, stride=2, padding=1)on a input, then on a input, before running it. Then feed a constant image through a kernel-3/stride-2 transposed conv and look at the checkerboard pattern in the output.
Quiz
Flashcards
These cards are now in your spaced-repetition queue. Review all due cards →