Segmentation Mask Inspector
A diagnostic for the gap between "the loss went down" and "the masks actually look right".
When to use
- Right after a training run when mIoU looks fine but visual inspection says otherwise.
- Before deployment: checking the class balance of predictions against ground truth.
- When per-class IoU is high for large objects but low for small ones.
- Debugging boundary artefacts that do not show up in IoU because they are small in pixel count.
Inputs
preds: (N, H, W) tensor of predicted class IDs.targets: (N, H, W) tensor of ground-truth class IDs.num_classes: integer.- Optional
class_names: list of C strings.
Steps
Class pixel histograms. Compute the percentage of pixels per class for
predsandtargets. Flag any class where|pred% - gt%| / max(gt%, 1e-6) > 0.30(relative deviation above 30%). For classes absent from ground truth (gt% == 0), flag any predicted share above0.3directly.IoU per class and boundary F1 per class. Boundary F1 is computed by dilating each mask by 3 pixels, intersecting, and scoring. Classes with IoU > 0.7 but boundary F1 < 0.5 are blurring edges.
Small-object recall. Separate every ground-truth connected component into size buckets (tiny < 100 px, small < 1000 px, medium < 10000 px, large >= 10000 px). Report recall per bucket per class. Small-object recall below 0.3 while large-object recall is above 0.9 indicates a resolution / receptive-field problem.
Confusion pairs. For each class, find the class it most often confuses with (most common wrong predicted class within its ground-truth mask). Report the top 3 pairs.
Saturation check (requires
probsorlogits, not justpreds). If the caller passes the raw per-pixel probability distributionprobs: (N, C, H, W), compute the fraction of pixels whereprobs.max(dim=1) > 0.99per class. High saturation (>0.9 of a class's pixels) suggests overconfidence — candidate for label smoothing or calibration. When only argmaxedpredsare available, skip this step and note it in the report.
Report format
[mask-inspector]
classes: C
[class distribution]
name gt % pred % delta
...
[metrics]
class IoU bF1 recall_tiny recall_small recall_medium recall_large
...
[confusion pairs]
class A confused with class B: <N> pixels (most common)
class B confused with class A: <N> pixels
...
[verdict]
most impactful issue: <one sentence>Rules
- Sort class rows by descending gt pixel share so the most frequent classes come first.
- Flag classes with IoU < 0.4 or boundary F1 < 0.3 as
critical. - When small-object recall is the dominant failure, recommend: higher-resolution training, smaller stride at the last encoder stage, or a feature-pyramid decoder.
- When boundary F1 is the dominant failure, recommend: boundary-aware loss (Lovasz or BoundaryLoss), TTA with horizontal flip, and stride-less decoder.
- Never output class indices as the only identifier; if
class_namesis provided, use it in every row.