Ismail Ben Alla

YOLO Object Detector

YOLOv1 depuis l’article, en PyTorch

Vision par ordinateur · sept. 2023 · Terminé

Donnez-lui une image et il trace une boîte autour de chaque objet qu’il connaît, avec sa classe, en une seule passe.

Construit avecPyTorchtorchvisionpytestMatplotlibNumPyKaggleGoogle Colab

YOLO Object Detector — vue d’ensemble

Présentation

YOLOv1 transforme la détection d’objets en une seule régression : l’image est découpée en une grille 7 × 7, et la cellule qui contient le centre d’un objet prédit sa classe et deux boîtes candidates avec une confiance. Le réseau voit toute l’image d’un coup, donc la détection tient en une seule passe avant. J’en ai écrit chaque partie en PyTorch depuis l’article : le réseau à 24 couches, la perte en somme des carrés des erreurs, l’encodage des cibles, le décodage, la suppression des non-maxima et le mAP, sans bibliothèque de détection ni poids pré-entraînés.

Le projet a commencé en 2023 sous forme de deux notebooks entraînés sur les panneaux routiers Mapillary. En le réécrivant comme package testé, j’ai découvert que les CSV de test et de validation étaient des sous-ensembles du CSV d’entraînement, donc que chaque mAP avait été mesuré sur des images d’entraînement ; que les classes au-delà de 20 n’étaient jamais comptées ; que les boîtes étaient tracées depuis leur centre comme s’il s’agissait d’un coin ; et que la deuxième boîte de chaque cellule n’était jamais utilisée au test. Le dossier legacy conserve les notebooks et la liste complète des corrections.

Pour montrer que le pipeline apprend sans pré-entraînement ImageNet, j’ai ajouté deux jeux de données qui tournent sur CPU : des formes synthétiques et des chiffres MNIST dispersés sur un canevas. Un petit réseau de 8,3M de paramètres atteint un mAP@0.5 de validation de 0,952 sur les formes et 0,921 sur les chiffres en environ 25 minutes chacun. PASCAL VOC et tout dossier au format YOLO sont pris en charge par la même commande et un notebook Kaggle / Colab, mais ces runs GPU ne sont pas rapportés.

La question

Un détecteur à passe unique écrit sans bibliothèque de détection ni poids pré-entraînés peut-il apprendre à trouver et classer des objets, et comment prouver que le code de la perte, du décodage et du mAP est juste ?

Fonctionnalités clés

Comment ça marche

  1. Encoder les cibles

    Chaque boîte de vérité terrain va dans la cellule de la grille qui contient son centre, sous forme d’un décalage dans la cellule, d’une taille relative à l’image et d’une classe one-hot, ce qui donne un tenseur S × S × (C + 5B).

  2. Une seule passe avant

    Des blocs conv, batch-norm et leaky-ReLU avec quatre max-pools réduisent l’image à une carte 7 × 7 ; deux couches entièrement connectées produisent d’un coup chaque boîte, confiance et probabilité de classe.

  3. Perte en somme des carrés des erreurs

    Pour chaque objet, la boîte de plus haut IoU est responsable et est tirée vers les coordonnées cibles et vers une confiance de 1 ; tout autre prédicteur est poussé vers une confiance de 0, pondéré par λ_noobj ; les probabilités de classe sont régressées dans les cellules contenant un objet.

  4. Décoder et supprimer

    Chaque boîte reçoit le score confiance × meilleure probabilité de classe ; les boîtes sous le seuil sont écartées et les boîtes de même classe qui chevauchent une boîte retenue au-delà de l’IoU de NMS sont supprimées.

  5. Mesurer le mAP

    Par classe, les détections sont triées par score, appariées à une vérité terrain non encore appariée à IoU ≥ 0,5, et l’AP est l’aire sous l’enveloppe de précision ; le mAP moyenne les classes qui ont une vérité terrain.

Exemples

Images de validation des formes : vérité terrain en haut, prédictions après 20 époques en bas. Le petit réseau atteint un mAP@0.5 de validation de 0,952 (cercle 0,94, carré 0,97, triangle 0,94).
Images de validation des formes : vérité terrain en haut, prédictions après 20 époques en bas. Le petit réseau atteint un mAP@0.5 de validation de 0,952 (cercle 0,94, carré 0,97, triangle 0,94).
Chiffres MNIST dispersés sur un canevas : vérité terrain en haut, boîtes prédites avec classe et score en bas (seuil d’affichage 0,3). Le mAP@0.5 de validation est de 0,921 ; les classes les plus faibles sont le chiffre 1 à 0,75 et le chiffre 8 à 0,88.
Chiffres MNIST dispersés sur un canevas : vérité terrain en haut, boîtes prédites avec classe et score en bas (seuil d’affichage 0,3). Le mAP@0.5 de validation est de 0,921 ; les classes les plus faibles sont le chiffre 1 à 0,75 et le chiffre 8 à 0,88.
Le run MNIST sur 12 époques : perte d’entraînement et de validation, mAP@0.5 de validation montant à 0,92, et les quatre composantes de la perte (coordonnées, confiance objet, confiance non-objet, classe).
Le run MNIST sur 12 époques : perte d’entraînement et de validation, mAP@0.5 de validation montant à 0,92, et les quatre composantes de la perte (coordonnées, confiance objet, confiance non-objet, classe).

Entrée

yolov1-train --dataset mnist --root data --image-size 112 --arch small --hidden 512 --dropout 0.3 --no-augment --train-size 10000 --val-size 500 --epochs 12 --batch-size 32 --lr 1e-3 --output-dir checkpoints/mnist

Sortie

checkpoints/mnist/: best.pt (highest validation mAP), last.pt, history.json, history.png, predictions.png, best_metrics.json — validation mAP@0.5 0.921 after 12 epochs, about 26 minutes on an 8-core CPU.

La recette MNIST du README. Avec seulement 3 000 images d’entraînement, le même réseau surapprend (perte d’entraînement 0,3, validation 1,6, mAP 0,55), c’est pourquoi le run en utilise 10 000.

Stack technique

Ce que j’ai appris

Limites

Mots-clés

YOLO · YOLOv1 · détection d’objets · You Only Look Once · PyTorch · suppression des non-maxima · NMS · précision moyenne (mAP) · mAP · PASCAL VOC · MNIST · panneaux routiers Mapillary · vision par ordinateur · apprentissage profond