Suppose you wire a 224×224 RGB image straight into a fully-connected layer. Flattened, the input is 150,528 numbers; connecting it to even a modest 1,000-unit layer needs 150,528×1,000≈150 million weights, for one layer, and it throws away the single most important fact about an image: that nearby pixels are related and that a pattern is the same pattern wherever it appears. Convolution fixes both problems at once. It is the operation that made deep learning practical for vision, and it does so by replacing that ocean of weights with a tiny filter that slides across the image.
From dense layers to convolution: the parameter problem
A dense layer treats every input pixel as independent and gives every connection its own weight. That is catastrophic for images in two ways: the parameter count explodes with image size, and the layer has no notion that pixel sits next to . Shift the whole image one pixel to the right and a dense layer sees an entirely different input vector.
Ask the tutor
Ask about this lesson, or about anything in AI. Answers cite the lessons they draw on.
Finished this lesson?
Mark it complete to earn XP, keep your streak, and schedule a review.
(10,10)
(10,11)
Convolution makes two structural bets instead:
Local connectivity, each output looks at only a small neighborhood of the input, because visual features (edges, corners, textures) are local.
Weight sharing, the same small set of weights is reused at every position, because a useful feature detector is useful everywhere in the image.
The convolution operation: kernel, stride, padding
A kernel (or filter) is a small weight grid, typically 3×3 or 5×5, spanning all input channels. You slide it across the image; at each position you multiply the kernel elementwise with the patch beneath it and sum the products into a single output number. Sweep over every position and the outputs form a feature map, a new grid that lights up where the kernel's pattern is present.
Three hyperparameters control the sweep:
Kernel size K, the side length of the patch each output sees.
Stride S, how many pixels the kernel jumps between positions. Stride 2 skips every other position, halving the output resolution.
Padding P, rings of (usually zero) pixels added around the border, so the kernel can be centered on edge pixels and the output does not shrink.
The output side length follows directly:
O=⌊SW−K+2P⌋+1
Two cases worth memorizing, both starting from W=224:
K=3,P=1,S=1: ⌊(224−3+2)/1⌋+1=224. A 3×3 kernel with padding 1 and stride 1 preserves the resolution, the ubiquitous "same" convolution.
K=3,P=0,S=2: ⌊(224−3)/2⌋+. Stride 2 with no padding roughly halves the resolution, downsampling as it goes.
Weight sharing and local connectivity
The payoff shows up in the parameter count. A convolutional layer stores one small weight tensor per output channel, of shape K×K×Cin, plus one bias, regardless of image size. For 64 filters of size 3×3 over 3 input channels:
(3×3×3+1)×64=28×64=1,792 parameters
That 1,792-parameter layer produces a 224×224×64 feature map, a far richer output than the dense layer's, at roughly one hundred-thousandth of the weights. And because the same kernel is applied everywhere, the layer is translation-equivariant: shift the input and the feature map shifts with it, instead of becoming unrecognizable.
Intuition
For a curious beginner
A detector for a vertical edge is useful whether the edge is in the top-left
corner or the bottom-right. So rather than learn a separate detector for every
location, the network learns one small filter and slides it across the whole
image. One reusable pattern, checked everywhere.
Engineering
How it is actually used
A conv layer holds one K×K×Cin weight tensor per
output channel, not one weight per pixel, so its size is independent of image
resolution. The same weights convolve every position; in practice this is
implemented as an im2col unfolding of patches followed by a single matrix
multiply, which maps cleanly onto GPU kernels.
Mathematical
The underlying mechanism
Sharing weights constrains the layer's weight matrix to be a single local
stencil repeated at every location, a banded, Toeplitz-like structure. This
encodes the prior that image statistics are stationary (the same features
matter everywhere) and makes the operator translation-equivariant: convolving
a shifted input yields a shifted output. The constraint collapses the
hypothesis space and is exactly why CNNs generalize from far less data than a
dense network would need.
For a curious beginner
A detector for a vertical edge is useful whether the edge is in the top-left
corner or the bottom-right. So rather than learn a separate detector for every
location, the network learns one small filter and slides it across the whole
image. One reusable pattern, checked everywhere.
How it is actually used
A conv layer holds one K×K×Cin weight tensor per
output channel, not one weight per pixel, so its size is independent of image
resolution. The same weights convolve every position; in practice this is
implemented as an im2col unfolding of patches followed by a single matrix
multiply, which maps cleanly onto GPU kernels.
The underlying mechanism
Sharing weights constrains the layer's weight matrix to be a single local
stencil repeated at every location, a banded, Toeplitz-like structure. This
encodes the prior that image statistics are stationary (the same features
matter everywhere) and makes the operator translation-equivariant: convolving
a shifted input yields a shifted output. The constraint collapses the
hypothesis space and is exactly why CNNs generalize from far less data than a
dense network would need.
Pooling and the receptive field
Stacked convolutions alone keep the resolution high and expensive. Pooling downsamples a feature map by summarizing each small window into one value, max pooling takes the largest activation in each 2×2 window (keeping the strongest evidence of a feature), average pooling takes the mean. A 2×2 pool with stride 2 halves both spatial dimensions, so 224×224→112×112, cutting the activation count by 4x and granting a little tolerance to small shifts.
The receptive field is the region of the original image that influences one output value. A single 3×3 conv has a 3×3 receptive field; stack a second and it grows to 5×5; a third reaches 7×7. Pooling and strided convolution expand it much faster. This is the engine behind the classic hierarchy: early layers, with tiny receptive fields, detect edges and colors; deeper layers, seeing large swaths of the image, respond to textures, then object parts, then whole objects.
Stacked 3×3 convs (stride 1)
Receptive field
1
3×3
2
5×5
3
7×7
This is also why two stacked 3×3 convolutions are preferred over one 5×5: they cover the same receptive field with fewer parameters and an extra nonlinearity in between.
A typical conv–pool stack
Classic CNNs (LeNet, AlexNet, VGG) repeat a simple motif: a few convolutions with ReLU nonlinearities, then a pool that halves resolution, with the channel count growing as the spatial size shrinks, trading spatial detail for feature richness.
1Conv block 1Two 3x3 convolutions (padding 1, stride 1) with ReLU keep resolution at 224 and lift channels to 64, learning edges and simple color patterns.
2Pool 1A 2x2 max pool with stride 2 halves resolution to 112, discarding precise position while keeping the strongest activations.
3Conv block 2More 3x3 convolutions raise channels to 128 at 112 resolution, combining edges into textures and corners over a larger receptive field.
4Pool and deepenRepeat: each stage halves the spatial size and doubles the channels, so the receptive field widens and features grow from parts toward whole objects.
5HeadGlobal pooling or a flatten feeds a small fully-connected classifier that maps the final feature vector to class scores.
Why the channel count grows as resolution shrinks
Downsampling loses spatial precision but frees a compute and memory budget.
CNNs spend it on more channels, more distinct feature detectors, so a deep
layer might be only 7x7 in space yet 512 channels deep. The network trades
knowing exactly where something is for knowing what it is, which is the
right trade for recognition.
Common mistakes
Comparing a conv layer to a dense layer on parameter count alone and
forgetting the real win is the built-in translation-equivariance prior, not
just fewer weights. - Getting the output-size formula wrong by mishandling the
floor, so a stride that does not evenly divide the input silently drops a
border row or column. - Assuming padding preserves resolution regardless of
stride, "same" padding only preserves size at stride 1. - Believing a 3×3 kernel can only ever see 3×3 pixels; depth and pooling grow
the receptive field to cover the whole image. - Treating max pooling as free,
it discards position information, which hurts tasks like precise localization
and segmentation. - Stacking convolutions without any nonlinearity between
them; two linear convolutions collapse into one, so ReLUs are what give depth
its power.