When One Label Is Not Enough
Detection, segmentation, and the label cost that decides projects
Every model so far answers one question per image: which class is it. Most real vision problems ask something harder, and the difference is not the model but the shape of the output.
| Task | Output | Label cost |
|---|---|---|
| Classification | One label per image | Low |
| Localisation | One box | Medium |
| Detection | Any number of boxes, each labelled | High |
| Segmentation | A label for every pixel | Very high |
| Instance segmentation | Which pixels belong to which individual object | Extreme |
from sklearn.datasets import load_digits
digits = load_digits()
images, y = digits.images / 16.0, digits.target
RAMP = ' .:-=+*#%@'
def show(img):
for row in img:
print(''.join(RAMP[min(9, max(0, int(v * 9.999)))] for v in row))
def make_scene(indices, seed=0):
"""Paste a few digits onto a larger blank canvas at known places,
so we have ground truth boxes without labelling anything by hand."""
rng = np.random.RandomState(seed)
canvas = np.zeros((28, 28))
boxes = []
for i in indices:
for _ in range(40):
r, c = rng.randint(0, 21), rng.randint(0, 21)
if all(abs(r - br) > 9 or abs(c - bc) > 9
for br, bc, _ in boxes):
canvas[r:r + 8, c:c + 8] = np.maximum(
canvas[r:r + 8, c:c + 8], images[i])
boxes.append((r, c, int(y[i])))
break
return canvas, boxes
canvas, boxes = make_scene([0, 1, 2], seed=1)
show(canvas)
print()
for r, c, label in boxes:
print('a %d at row %d, column %d' % (label, r, c))
-%+
%@*@-
.@. *=
:# ==
-= +=
:* #=
.%-*#
-%*
:@#
.@@%
#%- =%=@
*@+ -@*
.@@- =%@
=@@@. +@@-
... (8 more lines)
A classifier cannot describe that picture. There is no single right answer to which digit is this, and the useful output is a list whose length is not known in advance.
The label cost column is the real constraint
Classification labels are a word per image. Detection labels are a drawn box per object, and segmentation labels are a traced outline per object, which is minutes rather than seconds each. A segmentation dataset of any size represents months of work, and two annotators will not draw the same outlines.
Choosing the simplest output shape that answers your actual question is therefore a budget decision as much as a technical one.