Skip to main content

Convolutional Neural Networks

A convolutional neural network (CNN) alternates learned spatial feature extraction with nonlinearities and controlled resolution changes. A classifier head maps the final representation to one raw logit per class.

Prerequisites​

Complete Convolution and Pooling and Loss Functions and Objectives.

Learning goals​

  • trace (N, C, H, W) through a compact CNN.
  • use adaptive pooling to decouple the classifier head from one fixed spatial size.
  • keep logits, probabilities, labels, and loss shapes consistent.

Worked example​

The network accepts RGB images and produces three logits per image. Adaptive average pooling reduces any remaining height and width to one cell per channel.

import torch
from torch import nn

torch.manual_seed(44)
model = nn.Sequential(
nn.Conv2d(3, 4, kernel_size=3, padding=1),
nn.ReLU(),
nn.MaxPool2d(2),
nn.Conv2d(4, 8, kernel_size=3, padding=1),
nn.ReLU(),
nn.AdaptiveAvgPool2d((1, 1)),
nn.Flatten(),
nn.Linear(8, 3),
)
images = torch.linspace(0, 1, steps=2 * 3 * 8 * 8).reshape(2, 3, 8, 8)
labels = torch.tensor([0, 2], dtype=torch.long)

shapes = []
x = images
for layer in model:
x = layer(x)
shapes.append(tuple(x.shape))
loss = nn.CrossEntropyLoss()(x, labels)

print(f"layer_shapes={shapes}")
print(f"logits={tuple(x.shape)} labels={tuple(labels.shape)} loss={loss.item():.4f}")
print(f"parameters={sum(parameter.numel() for parameter in model.parameters())}")

Output:

layer_shapes=[(2, 4, 8, 8), (2, 4, 8, 8), (2, 4, 4, 4), (2, 8, 4, 4), (2, 8, 4, 4), (2, 8, 1, 1), (2, 8), (2, 3)]
logits=(2, 3) labels=(2,) loss=1.1700
parameters=435

CrossEntropyLoss expects raw logits of shape (N, classes) and integer class indices of shape (N,); do not apply softmax first. The receptive field grows through stacked layers, but padding, stride, and boundary effects mean it is not synonymous with reliable object understanding.

Common mistakes​

  • Hard-coding a flattened size that silently breaks when image dimensions change.
  • Applying softmax before CrossEntropyLoss, weakening numerical stability and changing the intended interface.
  • Assuming more channels always mean more useful information; capacity must be validated against data and cost.
  • Forgetting model.train() during optimization or model.eval() plus torch.inference_mode() during evaluation.

Practice​

Run the same model with a (2, 3, 12, 10) input and identify which intermediate shapes change. Add another pooling layer and discuss the loss of small spatial details.

Next steps​

Continue with Image Augmentation to define training-time transformations without corrupting targets or evaluation.

Primary sources​

Checked 2026-10-16: PyTorch Conv2d, PyTorch AdaptiveAvgPool2d, PyTorch CrossEntropyLoss, and He et al., deep residual learning.