Key ideas
- Tasks1: semantic segmentation gives every pixel a class but does not separate objects of the same class (three sheep form one "sheep" region); instance segmentation detects and masks each object separately; panoptic segmentation gives every pixel a class and an instance id. Countable things (people, cars) get one segment per object, amorphous stuff (sky, road, grass) one segment per class1.
- Encoder–decoder: the encoder (a classification backbone) extracts features at decreasing resolution; the decoder upsamples them to the input's height and width with one channel of class scores per class, and the predicted class of a pixel is the argmax over the channels3.
- Loss: per-pixel cross-entropy averaged over the pixels (binary cross-entropy for a two-class mask)3,7. When the foreground is tiny, background pixels dominate this loss and the network may learn to miss the object; V-Net instead maximizes a soft Dice coefficient, which relates the overlap to the sizes of the predicted and true foreground and needs no class re-weighting8.
- Transposed convolution broadcasts each input value through the kernel and sums the overlapping results, so the output is larger than the input2. Its stride spaces those results apart and its padding removes output rows and columns2. It multiplies by the transpose of the convolution's sparse weight matrix, which is why it undoes the shape change of a convolution (not its values)2. When the kernel size is not divisible by the stride, output pixels receive unequal numbers of contributions (kernel 3, stride 2: 1, 1, 2, 1, 2, …), so even a constant input comes out as a checkerboard-like grid.
- FCN3,7: a pretrained classification CNN without its global pooling and fully connected head (the original FCN turned the FC layers into convolutions), a conv to the number of classes, and a transposed conv that scales by the backbone's total stride, initialized as bilinear upsampling. Kernel , stride , padding scale height and width by exactly (64, 32, 16 for )3. FCN-32s upsamples its stride-32 scores in one step and is coarse; FCN-16s adds class scores predicted from pool4 (stride 16) to the 2× upsampled scores, and FCN-8s repeats this with pool37.
- U-Net4: a contracting path that gathers context and a mirror-image expanding path that recovers precise locations. At every level the decoder concatenates the cropped encoder feature map of the same resolution with its up-convolved map and applies two convolutions4. Unpadded convs shrink the maps, hence the cropping; a weight map boosts the thin background borders between touching cells4.
- Dilated (atrous) convolution with rate inserts zeros between kernel taps: a kernel covers pixels per side with the same weights and no extra computation6. It enlarges the field of view without downsampling. ASPP runs parallel atrous convolutions with different rates on one feature map and fuses them to capture several scales6.
- Mask R-CNN adds a small FCN mask branch to Faster R-CNN, so it does instance segmentation5. It predicts one binary mask per class with a per-pixel sigmoid and trains only the mask of the ground-truth class, so classes do not compete5. RoIAlign samples features at exact (unrounded) positions with bilinear interpolation instead of RoIPool's rounding, which matters for pixel-accurate masks5.
- Label maps hold class indices, not intensities. Geometric transforms (flip, crop, resize) must be applied identically to image and label map, with nearest-neighbour resizing for the labels; colour jitter changes the image only. Do not convert masks with
ToTensor: it dividesuint8values by 255 (see the code).
Formulas
With = pixels of true class predicted as and , as in the FCN paper7:
is V-Net's Dice for predicted probabilities and labels 8. PQ is computed per class and averaged; it matches a predicted and a ground-truth segment only if their IoU is strictly above 0.5, which makes the matching unique because panoptic segments do not overlap1. Transposed convolution output size (dilation 1): , plus PyTorch's output_padding, which follows from the stride spacing and the removed padding2.
Worked example
Binary segmentation of 100 pixels; rows are the true class, columns the prediction:
| true \ pred | background | object |
|---|---|---|
| background | 70 | 10 |
| object | 5 | 15 |
- Pixel accuracy .
- Background IoU ; object IoU ; mIoU .
- Object Dice .
- Mean per-class accuracy . Pixel accuracy hides the weak object class; mIoU and Dice expose it.
In code
import numpy as np
import torch
from torch import nn
from torchvision.transforms import ToTensor
up = nn.ConvTranspose2d(21, 21, kernel_size=64, stride=32, padding=16)
print(up(torch.zeros(1, 21, 15, 20)).shape) # torch.Size([1, 21, 480, 640]) scores back at input size
up2 = nn.ConvTranspose2d(16, 16, kernel_size=3, stride=2, padding=1)
print(up2(torch.zeros(1, 16, 8, 8)).shape) # torch.Size([1, 16, 15, 15]) not 16
up3 = nn.ConvTranspose2d(16, 16, kernel_size=3, stride=2, padding=1, output_padding=1)
print(up3(torch.zeros(1, 16, 8, 8)).shape) # torch.Size([1, 16, 16, 16])
mask = np.full((4, 4, 1), 15, dtype=np.uint8) # label map: class 15 everywhere
print(round(ToTensor()(mask)[0, 0, 0].item(), 4)) # 0.0588 = 15/255, no longer a class index
Common pitfalls
- U-Net is semantic segmentation; Mask R-CNN separates instances. Semantic segmentation never tells two touching dogs apart.
- Padding in a transposed convolution shrinks the output instead of enlarging it.
- Pixel accuracy is misleading under class imbalance: predicting "background" everywhere on 95% background scores 0.95 accuracy, 0.5 mean class accuracy and only 0.475 mIoU.
- Dice is never below IoU for the same masks (equal only at 0 and 1); do not compare a Dice score with an IoU score.
- Averaging IoU per image is not the same as one IoU from pixel counts pooled over the dataset.
- A dilated kernel still has 9 weights; it sees a wider area, it does not downsample.
- Interpolating a label map bilinearly invents classes between neighbouring labels (between 1 and 3 it creates 2).
- U-Net concatenates encoder features; FCN adds class-score maps.
References
- Kirillov et al. (2018), Panoptic Segmentation — Sec. 1 Introduction; 3 Panoptic Segmentation Format; 4.1 Segment Matching; 4.2 PQ Computation
- Dive into Deep Learning — Sec. 14.10.1 Basic Operation; 14.10.2 Padding, Strides, and Multiple Channels; 14.10.3 Connection to Matrix Transposition
- Dive into Deep Learning — Sec. 14.11 (introduction); 14.11.1 The Model; 14.11.2 Initializing Transposed Convolutional Layers; 14.11.4 Training; 14.11.5 Prediction
- Ronneberger et al. (2015), U-Net: Convolutional Networks for Biomedical Image Segmentation — Sec. 2 Network Architecture; 3 Training
- He et al. (2017), Mask R-CNN — Sec. 3 Mask R-CNN (Mask Representation; RoIAlign)
- Chen et al. (2016), DeepLab: Semantic Image Segmentation with Deep Convolutional Nets, Atrous Convolution, and Fully Connected CRFs — Sec. 3.1 Atrous Convolution for Dense Feature Extraction and Field-of-View Enlargement; 3.2 Multiscale Image Representations using Atrous Spatial Pyramid Pooling
- Long et al. (2015), Fully Convolutional Networks for Semantic Segmentation — Sec. 4 Segmentation Architecture (introduction; 4.1 From classifier to dense FCN; 4.2 Combining what and where); 5 Results (Metrics)
- Milletari et al. (2016), V-Net: Fully Convolutional Neural Networks for Volumetric Medical Image Segmentation — Sec. 3 Dice loss layer