PyTorch Receptive Fields
A receptive field is the patch of the original input that one output cell can see. Stacked convolutions grow that patch layer by layer.
One layer
Start from a field of one cell. A 3 by 3 kernel adds one cell on each side.
field = 1
field += 3 - 1
print(field)Two layers
A second 3 by 3 conv adds one more cell on each side. The running total reaches 5.
field = 1
for _ in range(2):
field += 3 - 1
print(field)Three layers
A third conv grows the field to 7. The closing program measures these sizes with gradients, and the counts match.
field = 1
for _ in range(3):
field += 3 - 1
print(field)Example
import torch
from torch import nn
torch.manual_seed(0)
def field_size(depth):
layers = []
for _ in range(depth):
conv = nn.Conv2d(1, 1, kernel_size=3, padding=1, bias=False)
with torch.no_grad():
conv.weight.fill_(1.0)
layers.append(conv)
model = nn.Sequential(*layers)
image = torch.rand(1, 1, 16, 16, requires_grad=True)
out = model(image)
centre = out[0, 0, 8, 8]
centre.backward()
mask = image.grad[0, 0] != 0
height = int(mask.any(dim=1).sum())
width = int(mask.any(dim=0).sum())
return height, width
for depth in (1, 2, 3):
height, width = field_size(depth)
print(f"{depth} stacked conv: receptive field {height} x {width}")Key points
- Receptive field: the input patch that can change one output cell
- One 3 by 3 conv gives each output cell a 3 by 3 field
- Each extra 3 by 3 conv adds one cell to each side of the field
- Use stacked small kernels to see a wide patch with few weights
- A deeper stack lets each cell judge a larger part of the image
In this example, field_size builds a stack of 3 by 3 convs with every weight set to one. Padding 1 keeps the map at 16 by 16, so the centre cell is easy to pick. The program takes the centre output cell and calls backward on it. The input gradient is non-zero only inside the patch that cell can see. Counting its non-zero rows and columns gives the field size. Depths 1, 2, and 3 print fields of 3, 5, and 7.
Note
Stride and pooling grow the field faster than stride-1 convs
Try it Yourself
Edit the code, then press Run.
Running is simulated ยท Python Playground
Exercise
How large is the receptive field after two stacked 3 by 3 convs with stride 1?