Module 1 — Les trois familles de tâches sur l'image
Le cours 10 a montré comment un réseau convolutif transforme une image en un vecteur de caractéristiques. Reste à décider ce qu'on veut prédire. Toute la vision par ordinateur moderne se ramène à trois grandes familles, et le choix conditionne l'architecture, la métrique et surtout le coût d'annotation. Confondre les familles au démarrage d'un projet, c'est se tromper d'ordre de grandeur sur le budget et sur le calendrier.
Le fil rouge : compter au carrefour
Le cours travaille sur un système de comptage installé au-dessus d'un carrefour. Une caméra fournit des images à 25 images par seconde. Selon la question posée, la même image se traite très différemment.
- « Y a-t-il quelqu'un sur la scène ? » demande une classification — un scalaire par image.
- « Combien de voitures et où sont-elles ? » demande une détection — une liste de rectangles étiquetés.
- « Quelles zones de pixels sont la chaussée, le trottoir, la voiture, le piéton ? » demande une segmentation — une carte de la même taille que l'image.
Les trois questions se répondent à partir des mêmes pixels, mais le modèle, la sortie, la perte et surtout la manière d'annoter changent.
Classification : un scalaire par image
La classification produit un vecteur de probabilités de la taille du
nombre de classes, éventuellement suivi d'un argmax. La sortie n'a aucune
information spatiale : le modèle répond « il y a un chat » sans dire où.
import torch
from torchvision.models import resnet50, ResNet50_Weights
modele = resnet50(weights=ResNet50_Weights.DEFAULT).eval()
image = torch.randn(1, 3, 224, 224) # un lot d'une image
logits = modele(image) # forme (1, 1000)
classe = logits.argmax(dim=1).item() # entier entre 0 et 999
L'annotation est la moins chère de toutes : un annotateur regarde l'image et coche une case. Une image bien cadrée s'étiquette en une seconde ou deux, ce qui rend possibles des jeux à un million d'exemples comme ImageNet. Le prix de cette économie est la perte de toute information spatiale : la classification seule ne compte rien et ne localise rien.
Détection : une liste de rectangles
La détection ajoute la position. La sortie est une liste variable de
boîtes englobantes (bounding boxes), chacune accompagnée d'une classe et
d'un score de confiance. Une image de carrefour vide donne zéro boîte, une
image encombrée en donne des dizaines. Cette longueur variable est ce qui
rend la détection plus difficile qu'une classification par grille : le
modèle doit produire une structure, pas juste un tenseur de taille fixe.
Une boîte se code souvent par les coordonnées de deux coins opposés
(x1, y1, x2, y2), ou par un centre et une taille (cx, cy, w, h). La
seconde forme est plus stable pour la régression, car chaque paramètre a un
rôle homogène.
L'annotation coûte de dix à trente secondes par objet. Un carrefour aux heures de pointe contient facilement quinze véhicules et dix piétons : à vingt secondes par objet, une image demande huit minutes d'annotation sérieuse. C'est la première fois où l'ordre de grandeur du coût explose et oblige à réfléchir à un jeu de taille raisonnable, cinq à dix mille images plutôt que le million des jeux de classification.
Segmentation : trois nuances qui changent tout
La segmentation attribue une classe à chaque pixel de l'image. La sortie a la même hauteur et la même largeur que l'entrée, avec un canal par classe. Trois variantes cohabitent, et elles ne se confondent pas.
| Variante | Ce qu'elle distingue | Sortie |
|---|---|---|
| Sémantique | classes uniquement | carte de classes |
| D'instances | objets d'une classe, un par un | boîte + masque par instance |
| Panoptique | classes de fond et objets individuels | union des deux |
Sur le carrefour, la segmentation sémantique répond « ce pixel appartient à une voiture », sans distinguer deux voitures collées. La segmentation d'instances répond « ce pixel appartient à la voiture n° 3 », ce qui permet enfin de compter. La panoptique ajoute que le pixel voisin appartient à la classe fond « route », qui n'est pas un objet dénombrable.
L'annotation d'une carte de segmentation coûte de trente minutes à deux heures par image en polygone soigné. Sur les jeux publics comme Cityscapes, chaque image représente quatre-vingt-dix minutes d'annotation en moyenne. C'est trois ordres de grandeur au-dessus de la classification.
La segmentation panoptique n'est pas « sémantique + instances mises côte à côte ». Elle exige que chaque pixel appartienne à une et une seule entité, ce qui interdit les chevauchements produits par une sortie d'instances brute. Un post-traitement de fusion est indispensable, et il tranche les conflits par priorité de score. Sans lui, deux masques superposés donnent des étiquettes contradictoires sur les pixels partagés.
Formats d'annotation : trois écritures pour la même chose
La même boîte englobante peut s'écrire de trois façons selon le format, et mélanger les formats est la source la plus banale d'erreurs silencieuses.
COCO stocke tout dans un unique fichier JSON par split. Une image y est
un objet avec un identifiant, une largeur et une hauteur. Chaque annotation
référence une image et donne sa boîte au format [x, y, w, h] en pixels,
avec l'origine en haut à gauche. Les masques de segmentation cohabitent dans
la même annotation, sous forme de polygone ou d'encodage RLE.
Pascal VOC utilise un fichier XML par image, dans le sous-dossier
Annotations. La boîte y est donnée en pixels par ses deux coins
(xmin, ymin, xmax, ymax). Les classes sont écrites en toutes lettres, ce
qui rend le format lisible mais un peu verbeux.
YOLO utilise un fichier texte par image, une ligne par objet, au format
classe cx cy w h, avec toutes les coordonnées normalisées entre 0 et 1
par rapport à la taille de l'image. C'est le format que consomme
Ultralytics.
# COCO -> YOLO : la conversion la plus frequente
def coco_vers_yolo(x, y, w, h, largeur_image, hauteur_image):
cx = (x + w / 2) / largeur_image
cy = (y + h / 2) / hauteur_image
return cx, cy, w / largeur_image, h / hauteur_image
Choisir la bonne famille pour la bonne question
La règle est simple mais souvent violée : choisir la famille la moins riche qui répond à la question métier. Une classification suffit à savoir si le carrefour est occupé, une détection suffit à compter, la segmentation n'est nécessaire que pour délimiter des zones libres pour le passage piéton. Chaque niveau supplémentaire multiplie le coût d'annotation par cinq à cinquante, et augmente aussi la puissance de calcul et la complexité du suivi. Livrer une segmentation d'instances quand une détection suffit, c'est promettre un projet à six mois là où trois auraient suffi.
Multipliez le nombre d'images cible par le temps d'annotation par image de
la famille choisie, puis par un facteur 1,5 pour le contrôle qualité. Pour
5 000 images de détection à 5 minutes chacune, comptez 625 heures
d'annotation, soit quatre annotateurs pendant un mois. C'est ce chiffre
qu'il faut poser sur la table avant le premier git commit, pas après.
En résumé
- La vision moderne se ramène à trois familles : classification (un scalaire), détection (une liste de rectangles) et segmentation (une carte de pixels), chacune avec sa perte et son coût d'annotation.
- Le coût d'annotation varie de trois ordres de grandeur entre classification (secondes) et segmentation soignée (heures), et il détermine la faisabilité du projet avant l'architecture.
- Les formats COCO, Pascal VOC et YOLO codent la même boîte de trois manières différentes : origine, coins ou centre, en pixels ou en fraction. Mélanger deux formats produit des boîtes muettement décalées.
- La panoptique exige un pixel = une entité et n'est pas un simple empilement de sémantique et d'instances : elle demande une fusion explicite pour résoudre les chevauchements.
Module suivant : la première grande famille de détecteurs, R-CNN, qui pose la question « où regarder ? » avant « qu'est-ce que je vois ? ».