CNNs: one small detector, slid everywhere
A dense layer (chapter 42's x @ w + b) connects everything to
everything — fine for tabular rows, wasteful for images and
signals, where the meaningful patterns are local (an edge, a
spike) and can appear anywhere. Convolutional networks encode
exactly those two facts.
Run the one-dimensional version
The kernel [-1, 1] is a two-weight pattern detector meaning
"next value minus this value." Sliding it along the signal
produces a response: +5 exactly at the upward jump, −5 at the
downward one, 0 on flat stretches. You just ran a convolution.
Two properties fell out, and they are the whole idea:
- Locality — each output looked at a small window, not the whole input.
- Weight sharing — the same two weights scanned every position. One detector, reused everywhere, means far fewer parameters than a dense layer — and a pattern learned at one position is automatically recognized at every other (translation robustness).
From demo to CNN
A real convolutional layer is this demo, generalized: 2-D windows
sliding over images, dozens of kernels per layer (each learns its
own detector — edges and blobs early), and layers stacked so
later ones see combinations of earlier detections — edges into
textures into parts into objects. The kernels' weights are
learned by the same loop you already know — chapter 43's four
beats; autograd differentiates through the sliding window like
anything else. Pooling layers downsample between stages, trading
resolution for context. In torch: nn.Conv2d(in_channels, out_channels, kernel_size) on chapter 42's (batch, channels, height, width) tensors.
Where they're the right call: images and spatially-structured data, audio spectrograms, and any signal where "local pattern, any position" describes the truth. That inductive bias is a head start when data is limited — the architecture already knows locality matters, so the model doesn't spend data learning it.
Where AI specifically gets this wrong
- Channel mismatches across layers. Each conv's output
channels must feed the next conv's input channels — generated
stacks that were never shape-checked crash on the first forward
pass.
print(x.shape)between layers, chapter 42's habit. - Spatial dims that quietly vanish. Sizes shrink with each valid convolution and each pool; a stack that pools to 1×1 too early runs fine and detects nothing. Same habit, subtler payoff.
- CNNs pattern-matched onto tabular data. Column order in a spreadsheet isn't spatial structure; a conv over arbitrary column neighbors detects nothing meaningful.
- Forgetting the demo. When a generated explanation of CNNs
goes mystical, come back to
[-1, 1]sliding along a list.