Définir la spécification du jeu de données
Planifie les scénarios, les quotas, les variations, les cas limites et les images d’arrière-plan avant la collecte, puis dimensionne le plan selon les objectifs de volume d’Ultralytics.
Les équipes qui n’ont pas de spécification se retrouvent avec 5 000 photos bien éclairées, prises de jour avec une seule caméra, et un modèle qui échoue à la tombée du jour dès son premier jour en production. Une spécification de jeu de données est une liste de courses d’images : elle répertorie chaque scénario que le modèle doit gérer, le nombre d’images nécessaires pour chacun et les cas rares à suréchantillonner. Sa rédaction prend une heure et détermine où investir les efforts de collecte.
Pratique
Où se situe la spécification#
La spécification fait le lien entre l’objectif et la caméra. Elle guide la collecte et constitue la référence à consulter lorsque le premier modèle n’atteint pas son objectif :
Le cycle revient à la spécification, pas aux paramètres d’entraînement : un objectif manqué signale généralement un scénario omis par la spécification. Le guide sur les étapes d’un projet de vision par ordinateur décrit le même cycle de vie.
Présente les scénarios en lignes#
Un scénario correspond à une combinaison de conditions de capture que le modèle doit gérer. Des lignes assorties de quotas rendent les lacunes visibles avant que quiconque ne prenne une caméra :
| Scénario | Caméras | Emplacements | Moment de la journée | Condition | Quota | Remarques |
|---|---|---|---|---|---|---|
| quai-jour | cam-1 à cam-4 | quais A–C | 08:00–17:00 | n’importe lequel | 1,200 | heures de pointe |
| quai-nuit | cam-1 à cam-4 | quais A–C | 22:00–04:00 | n’importe lequel | 400 | éclairage au sodium, moins de personnes |
| chargement-pluie | cam-2, cam-3 | quai B | n’importe lequel | pluie uniquement | 200 | rare, mais critique |
| empilé | n’importe lequel | n’importe lequel | n’importe lequel | palettes à plus de 2 niveaux de hauteur | 150 | cache les personnes derrière elles |
| arrière-plan | n’importe lequel | n’importe lequel | n’importe lequel | quai vide | 150 | aucun objet, aucune étiquette |
Un scénario que tu ne peux pas décrire par écrit est un scénario que le modèle ne verra pas pendant l’entraînement, et c’est celui qui échouera en production.
Dimensionne la spécification en fonction des objectifs de volume#
Les conseils d’Ultralytics pour obtenir les meilleurs résultats d’entraînement donnent des règles empiriques pour la production :
| Objectif | Recommandation |
|---|---|
| Images par classe | ≥ 1,500 |
| Instances annotées par classe | ≥ 10,000 |
| Images d’arrière-plan (sans étiquette) | 0–10 % du jeu de données ; COCO en contient environ 1 % |
| Variété | Différents moments, saisons, conditions météorologiques, éclairages, angles, sources et caméras |
Ce sont les seuils à viser pour un modèle de production. Quelques centaines d’objets annotés par classe suffisent pour commencer à expérimenter, et ce premier modèle est le moyen le plus rapide de repérer les scénarios qui nécessitent davantage de données. Pour savoir à quelle distance un jeu de données se trouve de ces seuils, compte-le. Ce script s’exécute sur COCO128, un échantillon de COCO de 128 images téléchargé automatiquement :
from collections import Counter
from pathlib import Path
from ultralytics.data.utils import IMG_FORMATS, check_det_dataset, img2label_paths
IMAGES_PER_CLASS, INSTANCES_PER_CLASS = 1500, 10_000 # Ultralytics production targets
data = check_det_dataset("coco128.yaml") # downloads COCO128 (~7 MB) on first run; swap in your data YAML
images = [p for p in Path(data["train"]).rglob("*.*") if p.suffix[1:].lower() in IMG_FORMATS]
image_count, instance_count, background = Counter(), Counter(), 0
for label in map(Path, img2label_paths([str(p) for p in images])):
classes = [int(r.split()[0]) for r in label.read_text().splitlines() if r.strip()] if label.exists() else []
instance_count.update(classes)
image_count.update(set(classes))
background += not classes
print(f"{len(images)} images, {background} background ({background / len(images):.0%}, target 0-10%)")
print(f"{'class':>12} {'images':>7} {'instances':>10} {'of target':>10}")
ranked = instance_count.most_common()
for cls, n in ranked[:3] + ranked[-3:]: # best and worst covered classes
coverage = min(image_count[cls] / IMAGES_PER_CLASS, n / INSTANCES_PER_CLASS)
print(f"{data['names'][cls]:>12} {image_count[cls]:>7} {n:>10} {coverage:>10.1%}")
never_labeled = [name for i, name in data["names"].items() if i not in instance_count]
print(f"{len(never_labeled)} classes in names with zero labels: {never_labeled[:4]} ...")128 images, 2 background (2%, target 0-10%)
class images instances of target
person 61 254 2.5%
car 12 46 0.5%
cup 10 36 0.4%
bear 1 1 0.0%
banana 1 1 0.0%
skis 1 1 0.0%
9 classes in names with zero labels: ['fire hydrant', 'parking meter', 'sheep', 'cow'] ...Comment interpréter le résultat :
- La couverture correspond à la plus faible des proportions d’images et d’instances, car une classe a besoin des deux. Même
person, la classe la mieux couverte, n’atteint que 2,5 % du seuil de production. - Les classes avec une seule instance (
bear,banana,skis) ne peuvent être ni apprises ni évaluées. Pour ton jeu de données, collecte des exemples ou retire ces classes de la v1. - Les classes sans aucune étiquette figurent dans le fichier YAML, mais ne sont jamais représentées. Le modèle consacre tout de même une partie de sa capacité à les prédire. Supprime-les de
namesou collecte des exemples avant l’entraînement.
Couvre les dimensions de variation#

Une seule image mélange déjà des personnes proches et éloignées, des vélos, un chien et des voitures. Une spécification réelle doit prévoir délibérément cette diversité. Pour chaque dimension, indique si la spécification la couvre ou pourquoi elle ne s’applique pas ; les lignes vides correspondent à des scénarios que tu découvriras en production :
| Dimension | Exemples |
|---|---|
| Heure | Jour, nuit, aube, crépuscule |
| Météo | Soleil, ciel couvert, pluie, brouillard, neige |
| Éclairage | Lumineux, faible luminosité, éblouissement, ombres marquées, sources mixtes |
| Caméra | Modèle, objectif, hauteur de montage, champ de vision |
| Géographie | Sites, villes, pays |
| Personnes et opérateurs | Équipes, horaires, uniformes, équipements de protection |
| Variantes de produits | Références SKU, révisions des emballages, couleurs |
| Taille des objets | Proches et grands, à moyenne distance, éloignés et petits |
| Occultation | Dégagés, partiellement occultés, fortement occultés, derrière une vitre |
| État de l’équipement | Objectifs sales ou embués, palettes endommagées, marquages au sol usés |
La diversité compte davantage que le volume : 1 500 images réparties entre ces catégories valent mieux que 5 000 images prises par une seule caméra à midi.
Prévois des images d’arrière-plan et des cas limites#
Les images d’arrière-plan sont des images sans objet annoté, comme celles d’un quai vide. Elles apprennent au modèle qu’il n’y a rien dans la scène et réduisent les faux positifs.
Dans le format Ultralytics YOLO, une image d’arrière-plan est simplement une image dont le fichier d’étiquettes est vide ou absent. L’entraînement les comptabilise toutes les deux dans sa ligne d’analyse (… 1200 images, 90 backgrounds, 0 corrupt). Vérifie que ce nombre respecte ton objectif de 0 à 10 % avant la première époque.
Les cas limites comprennent les fortes occultations, les objets coupés par le bord de l’image, les orientations inhabituelles, les objets empilés et les éléments ressemblants, comme un mât de chariot élévateur près d’un pilier en acier. Prévois une ligne de quota distincte pour chacun.
Si une image sur 200 montre une personne derrière des palettes empilées, un jeu de données recueilli à une fréquence naturelle ne contiendra qu’environ 7 images de ce type sur 1 500, ce qui est bien trop peu pour permettre l’apprentissage. Suréchantillonne volontairement les cas limites : leur quota doit être bien supérieur à leur proportion dans les images réelles.
Tu ne penseras pas à tous les scénarios sur papier. Mets le cahier des charges au point dans ses grandes lignes, entraîne rapidement un premier modèle et laisse ses erreurs révéler les scénarios que tu as manqués.
Afficher la solution
Les quotas sont calculés à partir de l’objectif d’instances, et pas seulement de l’objectif d’images. Supposons qu’un système de comptage sur un parking ait deux classes et que les premières vidéos affichent en moyenne 3 voitures et 0,5 camion par image :
| Classe | Instances par image | Images nécessaires pour 10 000 instances | Images nécessaires pour atteindre le minimum de 1 500 images | Plan |
|---|---|---|---|---|
car | 3.0 | ≈ 3,300 | 1,500 | 3 300 images |
truck | 0.5 | ≈ 20,000 | 1,500 | Collecte ciblée à l’entrée de la zone de chargement, où les camions sont 10 fois plus fréquents |
Les voitures sont couvertes par des vidéos ordinaires. Il faudrait 20 000 images aléatoires pour les camions ; la spécification ajoute donc une ligne de scénario dédiée (entrée de la zone de chargement, en semaine de 06:00 à 10:00) au lieu de collecter six fois plus d’images de chaque type. Ajoute une ligne pour l’arrière-plan d’environ 5 % (parking vide la nuit) et des lignes pour les cas limites liés à la neige au sol et aux camions partiellement hors cadre.