Segmentation Metrics - CNNs & Computer Vision
Implement Segmentation Metrics in Python with NumPy. medium exercise with examples, hints, and instant feedback. No setup or signup required.
Segmentation Metrics
What you'll build
Three standard scores for a binary segmentation mask: IoU (Jaccard index), pixel accuracy and the Dice coefficient.
Background
Segmentation models (U-Net, DeepLab, Mask R-CNN's mask head) predict a label for every pixel. Pixel accuracy is easy to read but misleading when the object is small: predicting "background everywhere" on an image that is 95% background scores 0.95. IoU and Dice only look at the foreground, so they are the metrics reported in papers and medical-imaging challenges. Dice also exists as a training loss (1 - soft Dice).
Formula
Treat each mask as the set of pixels equal to 1. With TP = |P ∩ T| (both 1), |P| = number of predicted foreground pixels, |T| = number of target foreground pixels:
IoU = |P ∩ T| / |P ∪ T| = TP / (|P| + |T| - TP)
Dice = 2 |P ∩ T| / (|P| + |T|) = 2 TP / (2 TP + FP + FN)
Pixel accuracy = (number of pixels where prediction == target) / (total pixels)
Dice is the F1 score over pixels, and the two overlap scores are linked by Dice = 2 IoU / (1 + IoU), so Dice >= IoU.
Inputs
prediction,target: 2D arrays of the same shape(H, W)containing only0and1(any integer or float dtype).
Expected return format
A dictionary with exactly these keys, each a Python float rounded to 4 decimal places:
'iou': foreground intersection over union'pixel_accuracy': fraction of pixels that agree (foreground and background)'dice': Dice coefficient
Edge cases and conventions
- If both masks are empty (no foreground at all), the IoU and Dice denominators are 0: return
0.0for'iou'and'dice'here. Pixel accuracy is then1.0. (Some libraries return 1.0 for an empty-vs-empty match; be explicit about which you use.) - Disjoint masks give IoU and Dice of
0.0.
Constraints
NumPy only, vectorised (no loops over pixels).
Follow-up
- How do you extend these to
Kclasses (per-class IoU, then mean IoU)? - Write a differentiable soft Dice loss on predicted probabilities.
Examples
Input: prediction = [[1, 1], [0, 0]], target = [[1, 0], [0, 1]]
Output: {'iou': 0.3333, 'pixel_accuracy': 0.5, 'dice': 0.5}TP = 1, |P| = |T| = 2: IoU = 1 / (2 + 2 - 1) = 1/3; 2 of 4 pixels agree; Dice = 2 * 1 / 4 = 0.5.
Input: prediction = [[1, 1, 0], [1, 1, 0], [0, 0, 0]], target = [[1, 1, 1], [1, 0, 0], [0, 0, 0]]
Output: {'iou': 0.6, 'pixel_accuracy': 0.7778, 'dice': 0.75}TP = 3, |P| = |T| = 4: IoU = 3/5, Dice = 6/8, and 7 of 9 pixels agree.
Practice in Python
import numpy as np
def segmentation_metrics(prediction, target):
"""
Binary segmentation metrics.
Args:
prediction: Predicted mask, shape (H, W), values 0 or 1
target: Ground-truth mask, shape (H, W), values 0 or 1
Returns:
dict with Python floats rounded to 4 decimals:
'iou': foreground IoU (0.0 if both masks are empty)
'pixel_accuracy': fraction of matching pixels
'dice': Dice coefficient (0.0 if both masks are empty)
"""
# Your code here
pass
The interactive editor loads with Python and NumPy. Run your implementation against 6 tests, or use the progressive hints.