Skip to content
ml-recall

Topic notes

Convolutional Neural Networks

Convolutional layers for images; locality and weight sharing, output-size arithmetic with padding and stride, channels and parameter counts, pooling, receptive fields and cheaper convolution variants.

4-min read AI-checked

Practise 66 questions Take a test

Key ideas

Formulas

Output size per dimension (input nn, kernel kk, padding pp per side, stride ss, dilation dd)3,6:

nout=⌊n+2p−d(k−1)−1s⌋+1(d=1: ⌊(n+2p−k)/s⌋+1)n_{\text{out}} = \left\lfloor \frac{n + 2p - d(k - 1) - 1}{s} \right\rfloor + 1 \qquad (d = 1:\ \lfloor (n + 2p - k)/s \rfloor + 1) #params=co ci khkw+co,multiply-adds=co houtwout⋅ci khkw\#\text{params} = c_o\,c_i\,k_h k_w + c_o,\qquad \text{multiply-adds} = c_o\,h_{\text{out}} w_{\text{out}} \cdot c_i\,k_h k_w

Receptive field, layer by layer for kernel kk and stride ss: r←r+(k−1) jr \leftarrow r + (k - 1)\,j and j←j⋅sj \leftarrow j \cdot s, starting from r=j=1r = j = 1 (jj is the distance in input pixels between neighbouring units).

Worked example

Input 3×64×643 \times 64 \times 64:

  1. Conv2d(3, 16, 5, padding=2): (64+4−5)+1=64(64 + 4 - 5) + 1 = 64, so 16×64×6416 \times 64 \times 64; parameters 16⋅3⋅25+16=121616 \cdot 3 \cdot 25 + 16 = 1216.
  2. MaxPool2d(2): 16×32×3216 \times 32 \times 32, no parameters.
  3. Conv2d(16, 32, 3, stride=2, padding=1): ⌊(32+2−3)/2⌋+1=16\lfloor (32 + 2 - 3)/2 \rfloor + 1 = 16, so 32×16×1632 \times 16 \times 16; parameters 32⋅16⋅9+32=464032 \cdot 16 \cdot 9 + 32 = 4640; multiply-adds 32⋅16⋅16⋅16⋅9=1,179,64832 \cdot 16 \cdot 16 \cdot 16 \cdot 9 = 1{,}179{,}648.
  4. Flatten: 32⋅16⋅16=819232 \cdot 16 \cdot 16 = 8192 features; Linear(8192, 10) has 81,93081{,}930 parameters, far more than both convolutions together.

In code

import torch
from torch import nn
net = nn.Sequential(
    nn.Conv2d(3, 16, kernel_size=5, padding=2), nn.ReLU(), nn.MaxPool2d(2),
    nn.Conv2d(16, 32, kernel_size=3, stride=2, padding=1), nn.ReLU(),
    nn.Flatten(), nn.Linear(32 * 16 * 16, 10))
x, shapes = torch.zeros(8, 3, 64, 64), []
for layer in net:
    x = layer(x)
    if not isinstance(layer, nn.ReLU):   # (shape without batch, parameters)
        shapes.append((tuple(x.shape[1:]), sum(p.numel() for p in layer.parameters())))
print(shapes)  # [((16, 64, 64), 1216), ((16, 32, 32), 0), ((32, 16, 16), 4640), ((8192,), 0), ((10,), 81930)]

Common pitfalls

References

  1. Dive into Deep Learning — Sec. 7.1 From Fully Connected Layers to Convolutions (introduction, 7.1.2.1 Translation Invariance, 7.1.2.2 Locality)
  2. Dive into Deep Learning — Sec. 7.2 Convolutions for Images (7.2.3 Object Edge Detection in Images, 7.2.4 Learning a Kernel, 7.2.5 Cross-Correlation and Convolution, 7.2.6 Feature Map and Receptive Field)
  3. Dive into Deep Learning — Sec. 7.3 Padding and Stride (7.3.1 Padding, 7.3.2 Stride)
  4. Dive into Deep Learning — Sec. 7.4 Multiple Input and Multiple Output Channels (7.4.2 Multiple Output Channels, 7.4.3 1×1 Convolutional Layer, 7.4.4 Discussion)
  5. Dive into Deep Learning — Sec. 7.5 Pooling (7.5.1 Maximum Pooling and Average Pooling, 7.5.2 Padding and Stride, 7.5.3 Multiple Channels)
  6. PyTorch documentation: torch.nn.Conv2d — Conv2d (groups parameter; Shape; Variables weight and bias)
  7. Wikipedia: Convolutional neural network — Architecture (Convolutional layers, Pooling layers, Receptive field); Translation equivariance and aliasing; Regularization methods, Artificial data
  8. Howard et al. (2017): MobileNets: Efficient Convolutional Neural Networks for Mobile Vision Applications — Abstract; Sec. 3.1 Depthwise Separable Convolution