Aller au contenu principal

Module 5 — Métriques de détection : IoU et précision moyenne

Une détection ne se juge pas comme une classification. Deux boîtes qui prédisent la bonne classe peuvent différer radicalement par leur position ; le nombre de vrais objets varie d'une image à l'autre ; certaines images n'en contiennent aucun. La métrique standard, la mean Average Precision sur le format COCO, agrège tout cela en un chiffre. Ce module explique ce qui se cache derrière et comment le lire.

L'IoU, ligne par ligne

L'Intersection over Union mesure le chevauchement de deux rectangles. C'est la brique élémentaire de toute la suite.

IoU(A,B)=ABAB\mathrm{IoU}(A, B) = \frac{|A \cap B|}{|A \cup B|}

Sur un exemple concret, prenons deux boîtes en pixels :

  • Vérité : A=(100,100,200,200)A = (100, 100, 200, 200), aire =100×100=10000= 100 \times 100 = 10\,000.
  • Prédiction : B=(120,130,220,210)B = (120, 130, 220, 210), aire =100×80=8000= 100 \times 80 = 8\,000.

L'intersection va de max(100,120)=120\max(100, 120) = 120 à min(200,220)=200\min(200, 220) = 200 en xx, et de max(100,130)=130\max(100, 130) = 130 à min(200,210)=200\min(200, 210) = 200 en yy. Elle mesure 80×70=560080 \times 70 = 5\,600. L'union vaut 10000+80005600=1240010\,000 + 8\,000 - 5\,600 = 12\,400. L'IoU vaut 5600/124000,455\,600 / 12\,400 \approx 0{,}45, sous le seuil courant de 0,5.

def iou_pas_a_pas(a, b):
x1 = max(a[0], b[0])
y1 = max(a[1], b[1])
x2 = min(a[2], b[2])
y2 = min(a[3], b[3])
inter = max(0, x2 - x1) * max(0, y2 - y1)
aire_a = (a[2] - a[0]) * (a[3] - a[1])
aire_b = (b[2] - b[0]) * (b[3] - b[1])
union = aire_a + aire_b - inter
return inter / union if union > 0 else 0.0

print(round(iou_pas_a_pas((100, 100, 200, 200), (120, 130, 220, 210)), 3))
# 0.452

L'IoU est symétrique en AA et BB, comprise entre 0 et 1. Il ne fait pas la différence entre une petite boîte incluse dans une grande et deux boîtes de tailles voisines qui se chevauchent modérément, ce qui a motivé la GIoU et la CIoU pour l'entraînement — mais pour l'évaluation, l'IoU brute reste la référence.

Apparier prédictions et vérités

Pour chaque image et chaque classe, on trie les prédictions par score décroissant. On les parcourt et, pour chacune, on cherche la vérité qui donne le meilleur IoU au-dessus du seuil.

  • Si une telle vérité existe et n'a pas déjà été appariée, c'est un vrai positif (VP), et la vérité est retirée du pool.
  • Sinon, c'est un faux positif (FP).
  • Les vérités restées non appariées à la fin sont des faux négatifs (FN).

L'appariement se fait par ordre décroissant de score, ce qui empêche une prédiction faible de « voler » un objet à une prédiction forte.

De la courbe précision-rappel à l'AP

En balayant le seuil de confiance de 1 à 0, chaque prédiction est progressivement acceptée. À chaque étape on recalcule :

preˊcision(s)=VP(s)VP(s)+FP(s),rappel(s)=VP(s)VP(s)+FN(s)\text{précision}(s) = \frac{\text{VP}(s)}{\text{VP}(s) + \text{FP}(s)}, \quad \text{rappel}(s) = \frac{\text{VP}(s)}{\text{VP}(s) + \text{FN}(s)}

Le rappel monte de façon monotone, la précision fluctue. L'AP (Average Precision) est l'aire sous la courbe précision-rappel, souvent interpolée aux valeurs monotones décroissantes de la précision pour éviter que le bruit local pénalise un bon modèle.

AP=01p(r)dri(ri+1ri)p(ri+1)\mathrm{AP} = \int_0^1 p(r)\, \mathrm{d}r \approx \sum_{i} (r_{i+1} - r_i) \cdot p(r_{i+1})

Une AP à 1 signifie que le modèle a placé toutes les vérités devant toutes les fausses détections. Une AP à 0,7 est déjà un bon score sur COCO.

De l'AP à la mAP

L'AP se calcule par classe. La mean Average Precision (mAP) est leur moyenne arithmétique. Sur COCO à 80 classes, la mAP est la moyenne des 80 AP.

Cette moyenne masque de grandes disparités. Un détecteur peut avoir 0,55 de mAP moyenne avec 0,80 sur les voitures et 0,25 sur les trottinettes. Sur le carrefour, la classe qui compte peut être précisément celle qui traîne le score. Lire toujours la mAP par classe avant de conclure.

COCO : mAP à 0,5 et 0,5-0,95

Le protocole COCO ne calcule pas une mAP à un seul seuil d'IoU. Il en calcule dix, de 0,50 à 0,95 par pas de 0,05, et moyenne :

  • mAP@0,5 : le seuil historique, permissif — une boîte à peu près bien posée passe. C'est la métrique de Pascal VOC.
  • mAP@0,75 : sévère, exige un chevauchement serré.
  • mAP@0,5:0,95 : la moyenne des dix, retenue comme métrique principale COCO. C'est celle qui apparaît dans les articles.

Un modèle affiché à « 41 mAP » sur COCO fait référence à cette moyenne étendue. Le même modèle sort souvent à 60 mAP@0,5. Confondre les deux fait apparaître un écart artificiel.

Trois autres découpages à connaître

COCO rapporte aussi la mAP par taille d'objet :

TailleAire en pixels²
Petitinférieur à 32²
Moyenentre 32² et 96²
Grandsupérieur à 96²

Un carrefour filmé de loin est dominé par les petites boîtes. Si la mAP globale est à 0,55 mais que la mAP_S est à 0,20, le modèle ne fait quasiment rien sur les piétons lointains, ce qui est un problème métier réel qu'aucun chiffre unique ne signale.

Lire un rapport COCO

Le code de référence est pycocotools. Son rapport, produit par COCOeval, tient sur douze lignes :

Average Precision  (AP) @[ IoU=0.50:0.95 | area=   all | maxDets=100 ] = 0.412
Average Precision (AP) @[ IoU=0.50 | area= all | maxDets=100 ] = 0.618
Average Precision (AP) @[ IoU=0.75 | area= all | maxDets=100 ] = 0.447
Average Precision (AP) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.243
Average Precision (AP) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.458
Average Precision (AP) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.554
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 1 ] = 0.325
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 10 ] = 0.516
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.545
  • Ligne 1 : la métrique principale, mAP@0,5:0,95.
  • Ligne 2 : la mAP@0,5 « historique » Pascal VOC.
  • Lignes 4 à 6 : le découpage par taille — indispensable pour diagnostiquer les échecs sur les petits objets.
  • Lignes 7 à 9 : les rappels moyens avec 1, 10, 100 détections maximum par image. Un écart important entre AR@100 et AR@10 signale que votre modèle a besoin de nombreuses détections pour couvrir tous les objets, souvent parce que le seuil de NMS est trop bas.
from pycocotools.coco import COCO
from pycocotools.cocoeval import COCOeval

verite = COCO("annotations_val.json")
predictions = verite.loadRes("mes_predictions.json")

evaluateur = COCOeval(verite, predictions, iouType="bbox")
evaluateur.evaluate()
evaluateur.accumulate()
evaluateur.summarize()

Les prédictions doivent être un tableau JSON d'objets {image_id, category_id, bbox: [x, y, w, h], score}.

La mAP peut monter sans que le modèle s'améliore

La mAP est agrégée sur toute la plage de scores et sur dix seuils d'IoU. Optimiser un modèle pour la mAP peut réduire son utilité pratique à un seuil d'inférence donné. Reportez toujours précision et rappel au seuil réel d'utilisation, en plus de la mAP, sinon vous mesurez un score de concours et pas un système en production.

Une visualisation vaut mille tables

Sur cinquante images de validation, dessinez en vert les vraies boîtes, en bleu les vrais positifs et en rouge les faux positifs. Une seule inspection révèle ce que dix tables cachent : classes confondues, objets systématiquement manqués sur les bords, détections doubles sur un objet. La mAP montre le résultat, l'inspection visuelle en montre la cause.

En résumé

  • L'IoU est le chevauchement de deux boîtes, entre 0 et 1. Il alimente toute la suite : appariement, calcul de VP/FP/FN, seuils d'évaluation.
  • La courbe précision-rappel se construit en balayant le seuil de confiance de 1 à 0 ; son aire, souvent interpolée, donne l'AP par classe.
  • La mAP@0,5:0,95 est la métrique COCO principale, moyenne de dix seuils d'IoU ; la mAP@0,5 est plus permissive et propre à Pascal VOC — ne pas les confondre en comparant deux modèles.
  • Un rapport COCO découpe aussi la mAP par taille d'objet (S/M/L) et donne les rappels moyens à 1, 10, 100 détections, qui diagnostiquent bien mieux les échecs qu'un chiffre unique.

Module suivant : la segmentation sémantique — U-Net, DeepLab et la question du déséquilibre des classes de pixels.