What Happens When the Conv2d Output Size Is Zero or Negative?
The Short Answer
PyTorch does not return an empty tensor. It stops with a RuntimeError before the forward pass completes. The check runs on the padded input, so the message reports the padded size and the kernel size it compared.
Measured Error Text
PyTorch 2.8.0, CPU build. A Conv2d layer with kernel 9 on an 8×8 input:
conv = nn.Conv2d(3, 16, 9)
conv(torch.zeros(1, 3, 8, 8))
RuntimeError: Calculated padded input size per channel: (8 x 8).
Kernel size: (9 x 9). Kernel size can't be greater than actual input size
The formula gives floor((8 + 0 - 1 × (9 - 1) - 1) / 1) + 1 = 0. A size of 0 is not a valid output, so the layer refuses the input. A negative result fails the same check.
The Dilation Trap
Dilation multiplies the reach of the kernel. The effective kernel is dilation × (kernel_size - 1) + 1. A kernel of 5 with dilation 2 reaches 9 positions, not 5. With a 4×4 input the error message reports the effective size:
conv = nn.Conv2d(3, 16, 5, dilation=2)
conv(torch.zeros(1, 3, 4, 4))
RuntimeError: Calculated padded input size per channel: (4 x 4).
Kernel size: (9 x 9). Kernel size can't be greater than actual input size
Read the second line of the message. The kernel size there is the effective size, so a layer you configured with kernel_size=5 can report 9.
Check Before the Forward Pass
The output size for one spatial dimension is:
out = floor((in + 2 * padding - dilation * (kernel - 1) - 1) / stride) + 1
The layer is valid only when out >= 1 for height and width. Run the number for each dimension before you train, not after the error. The Conv2d output size calculator shows the result and the formula for each dimension.
Four Fixes
- Reduce
kernel_sizeuntil the computed size is at least 1. - Add
padding. Each unit of padding adds 2 to the padded input size. - Reduce
strideto 1 if the layer has no reason to downsample that much. - Change the earlier layers. A stack of pooling layers can shrink a feature map past the reach of the next kernel, and the fix belongs in that stack.
Do not fix this error with output_padding. That argument belongs to ConvTranspose2d. Conv2d does not accept it.