Des jeux de données représentatifs de la réalité
Audite un jeu de données réel pour repérer les lacunes de couverture avant d’ajouter des annotations, puis transforme ces lacunes en plan de collecte incluant des exemples difficiles négatifs.
La plupart des modèles de vision décevants ne sont pas de mauvais modèles : ce sont de bons modèles entraînés sur un jeu de données qui ne ressemble pas à l’environnement de déploiement. Le détecteur COCO de la leçon précédente n’a détecté aucun bateau depuis un drone, car les bateaux de COCO sont photographiés de côté. Un audit de cinq minutes révèle ces lacunes avant que tu dépenses de l’argent en annotations.
Pratique
Les modèles apprennent le jeu de données, pas le monde#
Un modèle interpole entre les exemples qu’il a vus. Entraîne-le sur des rues ensoleillées de jour et déploie-le dans un garage brumeux la nuit : il échouera — non pas parce que les voitures ont changé d’apparence, mais parce qu’il n’a jamais vu de voiture dans ces conditions. Ce décalage s’appelle le décalage de domaine, et la validation ne peut pas t’en avertir si ses images proviennent du même échantillon biaisé :
La solution est structurelle, pas algorithmique : échantillonne délibérément l’environnement de déploiement avant l’annotation. Le guide sur la collecte et l’annotation des données explique comment procéder.
Auditer un jeu de données réel#

Le jeu de données medical-pills ci-dessus — des gros plans de plaquettes où chaque comprimé est encadré — se prête bien à un audit. Ultralytics Platform affiche les principaux décomptes sur la page du jeu de données ; le script ci-dessous calcule les nombres qui révèlent sa couverture, à partir de la copie fournie avec ultralytics :
from collections import Counter
from pathlib import Path
from PIL import Image, ImageStat
from ultralytics.data.utils import check_det_dataset
data = check_det_dataset("medical-pills.yaml") # downloads the dataset on first use
for split in ("train", "val"):
images = sorted(Path(data[split]).glob("*.jpg"))
labels = [Path(str(p).replace("/images/", "/labels/")).with_suffix(".txt") for p in images]
rows = [line.split() for f in labels if f.exists() for line in f.read_text().splitlines()]
classes = Counter(data["names"][int(r[0])] for r in rows)
backgrounds = sum(not f.exists() or not f.read_text().strip() for f in labels)
areas = sorted(float(r[3]) * float(r[4]) for r in rows) # box area as a share of the image
sizes = Counter(Image.open(p).size for p in images)
brightness = [ImageStat.Stat(Image.open(p).convert("L")).mean[0] for p in images]
print(f"{split}: {len(images)} images, {backgrounds} backgrounds, {dict(classes)}, sizes {dict(sizes)}")
print(f" boxes: median {areas[len(areas) // 2]:.1%} of the image, {sum(a < 0.01 for a in areas)} of {len(areas)} under 1%")
print(f" brightness: {min(brightness):.0f} to {max(brightness):.0f} (0 = black, 255 = white)")train: 92 images, 0 backgrounds, {'pill': 1623}, sizes {(1920, 1080): 92}
boxes: median 1.4% of the image, 320 of 1623 under 1%
brightness: 171 to 198 (0 = black, 255 = white)
val: 23 images, 0 backgrounds, {'pill': 399}, sizes {(1920, 1080): 23}
boxes: median 1.4% of the image, 79 of 399 under 1%
brightness: 171 to 198 (0 = black, 255 = white)Lis-le comme un rapport de couverture, avec un constat par ligne :
| Constat | Signification | Décision |
|---|---|---|
| Une seule résolution, 1920×1080 | Une seule caméra, une seule configuration | Collecte des images avec chaque modèle de caméra que tu utiliseras en déploiement |
| Luminosité limitée à 171–198 | Éclairage de studio clair et uniforme, rien de sombre | Collecte des images sombres, en contre-jour et en éclairage mixte avant le déploiement sur un comptoir de pharmacie |
| 0 image d’arrière-plan | Le modèle ne voit jamais de scène sans comprimés | Ajoute des plaquettes vides, d’autres comprimés et des comptoirs nus comme exemples difficiles négatifs |
| La boîte médiane représente 1,4 % de l’image ; une boîte sur cinq fait moins de 1 % | Objets de petite taille | Garde imgsz suffisamment élevé et inclue délibérément des images prises de loin |
Une classe, pill | Aucune catégorie de comprimés | Cela convient au comptage ; ajoute des classes uniquement si une décision le nécessite |
Aucun de ces problèmes n’apparaît dans le score de validation, car l’ensemble de validation présente les mêmes lacunes.
Les quatre axes de couverture#
| Axe | Éléments à collecter | Défaillance typique en cas d’absence |
|---|---|---|
| Éclairage | Aube, midi, crépuscule, nuit, éblouissement, contre-jour, éclairage fluorescent vacillant | Le rappel s’effondre lors des changements d’équipe ou en plein soleil |
| Météo et atmosphère | Pluie, brouillard, neige, poussière, condensation sur l’objectif | Faux positifs sur les gouttelettes, détections manquées dans la brume |
| Occultation et encombrement | Cibles partiellement cachées, scènes encombrées, objets coupés par le bord de l’image | Détections manquées dès que la cible n’est pas entièrement visible |
| Caméra et point de vue | Objectif, hauteur et angle de montage, résolution, compression, flou de mouvement | Fonctionne avec la caméra pilote, mais échoue sur le site suivant |
Le point de vue est l’axe qui manquait dans l’exemple de la marina : la même classe vue sous un nouvel angle, et le rappel est tombé à zéro.
Exemples difficiles négatifs et images d’arrière-plan#
Un détecteur doit aussi apprendre ce qui n’est pas la cible. Les exemples difficiles négatifs présentent une ressemblance superficielle avec celle-ci : pour un détecteur de chariots élévateurs, un transpalette, une nacelle à ciseaux, le reflet d’un chariot élévateur sur un sol poli, une affiche de sécurité représentant un chariot élévateur.
Au format YOLO, une image d’arrière-plan est simplement une image sans fichier d’annotation — rien à dessiner. Les conseils d’entraînement d’Ultralytics recommandent environ 0–10 % d’images d’arrière-plan pour réduire les faux positifs ; COCO en contient environ 1 %. Remplis cette proportion avec des exemples difficiles négatifs issus de ton propre environnement plutôt qu’avec des images vides choisies au hasard. L’augmentation des données peut faire varier la luminosité et l’angle, mais elle ne peut pas inventer un transpalette que le modèle n’a jamais vu.
Pièges#
Symptôme : 10 000 images étiquetées, toutes prises de jour et avec la caméra pilote. Solution : enregistre des images avec les caméras de déploiement, dans toute la diversité des conditions, pendant quelques semaines, vérifie la couverture, puis paie pour les étiquettes. Les données synthétiques peuvent combler une lacune connue, mais ne remplacent pas les captures réelles.
Symptôme : un mAP de validation élevé, mais de mauvais résultats sur le premier nouveau site. Solution : n’oublie pas que la validation partage les angles morts du jeu de données. Prends dix images d’entraînement aléatoires et dix images de production, puis demande à un collègue de les distinguer ; s’il y arrive, tu as un écart de domaine.
Pour un plan d’échantillonnage avec des nombres cibles par condition, poursuis avec Collecter des données représentatives de haute qualité dans Créer des jeux de données YOLO hautes performances.
Afficher la solution
Pour medical-pills, déployé sur un comptoir de pharmacie sous un éclairage mixte, remplis la grille à partir de l’audit (luminosité de 171 à 198, une source 1920×1080, aucun arrière-plan) et d’un rapide défilement des images, qui montre les mêmes boîtes sur la même surface claire, sans mains :
| Classe | Éclairage vif de studio | Éclairage tamisé ou chaud de magasin | Contre-jour / éblouissement | Partiellement masqué par une main | Caméra de téléphone |
|---|---|---|---|---|---|
pill | 2,022 | 0 | 0 | 0 | 0 |
| arrière-plan | 0 | 0 | 0 | — | 0 |
Plan de collecte par ordre de priorité :
- Éclairage tamisé ou chaud de magasin — condition habituelle du comptoir, actuellement représentée par zéro image.
- Partiellement masqué par une main — cela se produit lors de presque chaque interaction réelle.
- Caméra de téléphone — un deuxième capteur et une autre résolution.
- Contre-jour / éblouissement — les emballages en aluminium reflètent les fenêtres et les plafonniers.
Faux positifs difficiles : blisters vides (même aluminium, sans comprimés) et autres objets ronds sur le comptoir — pièces de monnaie, boutons, bonbons. Ajoute-les comme images d’arrière-plan, à hauteur d’environ 5 à 10 % du jeu de données.