Receptive Fields
Each unit only ever looks at a small patch directly, but stacking layers lets that patch grow until a deep unit has effectively seen the whole image.
Why Does This Exist?
A single unit from a 3x3 convolution sees exactly nine input pixels, the patch directly under its kernel, nothing more. On its own, a 3x3 kernel could never notice a shape spanning forty pixels or tell a face from one eyebrow, no matter how it is trained. Its whole world is a 3x3 window.
Yet networks built almost entirely from 3x3 kernels reliably recognize things far larger than nine pixels. This page resolves that gap: how does a network built from tiny local pieces end up with any sense of the whole picture.
The answer is depth. A second layer unit does not see raw pixels. It sees first layer outputs, and each of those already summarized its own 3x3 patch. Stack enough layers and one deep unit depends, indirectly, on a much larger patch of the original input. That indirect footprint is the receptive field. Downsampling in pooling layers grows it faster, which is why real nets interleave the two.
Think of It Like This
One person in a bucket brigade
A bucket brigade passes water along a line. The person at the very end never touched the well. They only ever took a bucket from the neighbor one spot back. Trace that bucket back one hand at a time and it came from far up the line.
A deep unit is the last person in the line. It never looked at the raw image. It only read the layer right below it, which only read the layer below that. Follow the chain back and a deep unit depends on a wide stretch of the original pixels, even though no single step ever looked at more than a handful at once.
Each carrier is one layer, each handoff is one convolution, the well is the input image, and the distance the water traveled is the receptive field size.
Where it stops: brigade buckets arrive unchanged, but layer outputs transform what they pass. A deep unit does not receive pixels. It receives summaries, so position near the center of the field matters more than position at the edge.
How It Actually Works
Tracing one unit backward
The diagram traces this by hand on a one dimensional strip of nine input units through three stacked 3x3 convolutions with stride 1 and no padding. Start at the single traced unit in layer three. It was computed from three units below, which is what a width 3 kernel does. Each of those three was computed from three units below, and because the three windows overlap, their union covers five units, not nine. Repeat once more and the union across the input reaches seven of the nine original positions.
Three layers, and the reachable footprint grew 3 to 5 to 7: a jump of two units per layer, matching kernel width minus one. That is the rule, not a coincidence.
The formula, and why it adds
For stacked layers with kernel size and stride 1, the receptive field is:
Plug in the diagram numbers, three layers of size 3, and , exactly the traced span. Growth is additive with depth for stride 1 layers: each extra layer adds a fixed , not a multiple. That rate is slow. It is why early nets needed a dozen or more layers before a unit field covered a typical input image.
Two things that grow the field faster
Pooling and strided convolutions grow the field multiplicatively, not additively. Downsampling shrinks the map, so every kernel afterward reads from a coarser grid where each cell already stands for a larger patch. A stride 2 pool roughly doubles the field of everything after it, which is why architectures interleave downsampling with convolutions rather than stacking stride 1 layers alone. See pooling layers for that half of the design.
Dilation grows the field without adding parameters or depth. A dilated 3x3 kernel with rate spreads three taps across positions, so its effective size is . Swap that into the same additive formula and one dilated layer covers the ground of several ordinary ones, at the cost of skipping positions in between.
Effective against theoretical
The formula gives the theoretical field: every input position a unit connects to. In practice, center positions reached through many overlapping paths matter far more than edge positions reached through one. The effective field is smaller than the theoretical one and, in trained nets, looks roughly Gaussian, strong in the middle and fading outward. The formula marks the outer boundary. It does not say how much each pixel inside counts.
Worked check: 7 against 12
Three stride 1 3x3 layers give . Add a stride 2 pool after the first layer and the code below gives 12. The pool adds only 1 itself but doubles the jump to 2, so each later 3x3 adds instead of 2. The last two layers contribute 8 of the total 12. That doubling is the multiplicative effect, computed step by step.
Code
The point is the check: rebuild the 7 from the diagram and the 12 with downsampling mixed in.
def receptive_field(layers: list[tuple[int, int]]) -> int: """Each layer is (kernel_size, stride). Returns the theoretical RF at the top.""" rf: int = 1 jump: int = 1 # how many input pixels one output step represents for kernel_size, stride in layers: rf += (kernel_size - 1) * jump jump *= stride return rf
three_stride1: list[tuple[int, int]] = [(3, 1), (3, 1), (3, 1)]print(receptive_field(three_stride1)) # -> 7
with_downsampling: list[tuple[int, int]] = [(3, 1), (2, 2), (3, 1), (3, 1)]print(receptive_field(with_downsampling)) # -> 12The printout matches the hand trace: 7 for three plain layers, 12 once a stride 2 stage doubles what every later layer is worth. Change the pool to stride 1 and the total falls back toward the additive path.
Watch Out For
Assuming depth alone sees the whole image
Depth is a number, and the field is a computed number, not a vague property of being deep.
Symptom: a stride 1 stack does well on small crops but fails on full resolution inputs where objects exceed any unit field. A pure 3x3 stride 1 net needs roughly 100 layers to span 200 pixels. Fix: compute the field for the actual architecture, then add downsampling or dilation until the field covers the objects being detected.
Quoting the theoretical field as influence
Reporting a 91 by 91 field says nothing about whether all those pixels steer the output.
Symptom: two units share one theoretical size yet behave differently on long range patterns, because training weighted their centers differently. Fix: check the effective field with an occlusion or gradient sensitivity map before arguing the model should capture a distant pattern. Trust the measured influence, not the outer boundary.
The Quick Version
- A single 3x3 kernel sees nine pixels, and the receptive field is how much input one deep unit depends on after tracing back through every layer.
- For stacked stride 1 layers the field grows additively by the rule RF equals 1 plus L times k minus 1.
- Three stride 1 3x3 layers give 7, traced in the diagram as spans of 3 then 5 then 7.
- Pooling and strided convolutions grow the field multiplicatively because later layers read from an already shrunk map.
- Dilation grows the field without depth or parameters by spreading kernel taps apart.
- The effective field is smaller than the theoretical field and concentrates toward the center.