🤖 YOLOv3 – Le Guide Ultime
Deep Dive : Darknet-53 (ResNet), FPN (Multi-scale), BCE Loss, Darknet (Framework) & OpenCV (Plugin).
1. C'est quoi YOLOv3 ?
3ème version (2018). "Better, Not Faster". Objectif : Précision (SOTA) en temps réel.
YOLOv3 Joseph Redmon2. Impact & Chiffres
A battu RetinaNet/SSD. SOTA (State-of-the-Art) de 2018. mAP 57.9% (COCO).
mAP COCO3. 📈 Archi: Darknet-53
Le "Backbone" (plugin). Un ResNet-like. 53 couches Conv (avec Skip Connections).
Darknet-53 Backbone4. 📈 Archi: Neck (FPN)
Le "plugin" FPN (Feature Pyramid Network). Combine les "features" (upsampling).
FPN Neck5. 🚀 Innovation: Multi-Scale
Prédit à 3 échelles (grids) différentes. La clé pour les *petits* objets (vs v2).
Multi-Scale Small Objects6. Innovation: Head & Loss
9 Anchor Boxes (k-means). BCE Loss (Binary Cross-Entropy) (vs Softmax).
7. Framework: Darknet (C)
Le framework "originel" (en C). .cfg (Archi), .weights (Poids), .data, .names.
8. Inférence (CLI Darknet)
./darknet detect cfg .... L'utilisation "classique" (C, temps-réel).
9. Inférence (Python / OpenCV)
Le "plugin" OpenCV DNN. cv2.dnn.readNetFromDarknet(). (Pas de PyTorch).
10. 🧠 Entraînement (Training)
Format (obj.data, train.txt, .txt labels). ./darknet detector train ...
11. L'Héritage (v4, v5)
v4 (2020) : "Bag of Freebies". v5 (2020) : La ré-écriture PyTorch (Ultralytics).
YOLOv4 YOLOv512. Projets & Liens
Projets (Caméras, Jetson). Liens (PJ Redmon, OpenCV).
Projects LinksYOLOv3 (2018) est la 3ème version majeure de l'architecture YOLO, créée par Joseph Redmon.
Contrairement à YOLOv2 (qui visait à être "Better, Faster, Stronger"), l'objectif de YOLOv3 était "Better, Not Faster" (Meilleur, Pas Plus Rapide). Le but était de sacrifier un peu de vitesse (FPS) pour gagner *massivement* en précision (mAP).
Le Contexte (2018)
En 2018, YOLO (v2) était *rapide*, mais il n'était pas le plus *précis*. D'autres modèles (RetinaNet, SSD) le battaient en précision (mAP), surtout sur les *petits* objets.
YOLOv3 a été la réponse de Redmon. Il a intégré les "plugins" SOTA (State-of-the-Art) de l'époque (ResNet, FPN) pour devenir le premier modèle à être *à la fois* SOTA en précision *et* temps-réel.
Le Papier (Tech Report)
Fidèle à son style, Redmon a publié YOLOv3 non pas dans une conférence, mais comme un "Tech Report" (arXiv) intitulé : "YOLOv3: An Incremental Improvement" (Une Amélioration Incrémentale). C'est le fameux papier qui commence par "I don't have to read your paper" (Je n'ai pas à lire votre papier).
L'impact de YOLOv3 a été *immédiat*. Il est devenu l'architecture de détection *de facto* pour la plupart des projets (industriels et académiques) de 2018 à 2020.
Les Chiffres (COCO mAP vs Vitesse)
Le mAP (mean Average Precision) est le score de précision. Le FPS (Frames Per Second) est la vitesse.
| Modèle (2018) | mAP (COCO) | Vitesse (FPS sur V100) | Philosophie |
|---|---|---|---|
| SSD300 (Ref. 2017) | 41.2 | ~46 FPS | Rapide, précision moyenne. |
| RetinaNet-101 (Ref. 2017) | 57.5 | ~5 FPS | Très précis (SOTA), mais lent (Two-Stage). |
| YOLOv2 (Ref. 2017) | 44.0 | ~67 FPS | Très rapide, précision moyenne. |
| YOLOv3-416 | 55.3 | ~35 FPS | Précis (SOTA) ET Temps-réel. |
Conclusion : YOLOv3 était (à l'époque) *aussi précis* que les modèles "lourds" (RetinaNet) tout en étant *7x plus rapide*. Il a rendu la détection SOTA accessible.
YOLOv3 a abandonné le "Backbone" (extracteur de features) léger de YOLOv2 (Darknet-19).
Pour rivaliser avec ResNet, Redmon a créé Darknet-53 : un backbone "plugin" de 53 couches convolutives.
La Clé : Les "Residual (Skip) Connections"
Darknet-53 est un *hybride* entre Darknet-19 et ResNet (voir 1.3, ResNet). Il utilise les "skip connections" de ResNet (F(x) + x) pour permettre un réseau très profond (53 couches) sans le "problème de dégradation" (Vanishing Gradient).
Diagramme (Bloc Résiduel de Darknet-53)
(Input: x)
|
+-----> (Identité / "Skip") ------------------+
| |
▼ |
[ Conv 1x1 (Bottleneck, ex: 256 -> 128 filtres) ] |
| |
▼ |
[ Conv 3x3 (ex: 128 -> 256 filtres) ] |
| |
▼ |
( F(x) ) |
| |
+--------------------[ ADDITION ] <------------+
|
▼
(Sortie: H(x))
Résultat : Un backbone beaucoup plus "profond" et "riche" sémantiquement que Darknet-19, capable d'extraire des features bien plus complexes.
C'est la *deuxième* innovation majeure de v3. C'est le "plugin" (l'architecture) qui a résolu le problème des *petits objets*.
Le Problème (YOLOv2)
YOLOv2 ne prédisait que sur *une seule* grille (13x13), en utilisant les "features" les plus profondes (sémantiques). C'était bon pour les gros objets, mais *mauvais* pour les petits (les "détails" étaient perdus).
La Solution (YOLOv3) : FPN (Feature Pyramid Network)
Le "Neck" (Cou) de YOLOv3 est un FPN. Il "remonte" (upsample) les features profondes (sémantiques) et les *fusionne* (concatène) avec les features plus basses (détails).
Diagramme (Concept du FPN)
(Input) -> [BACKBONE (Darknet-53)]
|
+-> [Feat 1 (52x52)] --+ (Détails)
| |
+-> [Feat 2 (26x26)] --|--+
| | |
+-> [Feat 3 (13x13)] --|--|--+ (Sémantique)
| | |
| | +-> [ TÊTE 1 (Gros objets) ]
| |
| +-> (Upsample) -> [ CONCAT ] -> [ TÊTE 2 (Moyens) ]
|
+-> (Upsample) -> [ CONCAT ] -> [ TÊTE 3 (Petits) ]
C'est la *conséquence* du FPN (voir 1.4). Au lieu d'une seule "tête" de détection, YOLOv3 en a trois.
Chaque "tête" (Head) est spécialisée dans une taille d'objet, en lisant une "feature map" différente du FPN.
Les 3 Échelles (Pour une image 416x416)
| Échelle | Taille Grille | Champ Réceptif | Cible (Objets) |
|---|---|---|---|
| Scale 1 (Tête 1) | 13x13 (divisé par 32) | Large | Grands objets (ex: "bus", "personne proche"). |
| Scale 2 (Tête 2) | 26x26 (divisé par 16) | Moyen | Moyens objets (ex: "chien", "chaise"). |
| Scale 3 (Tête 3) | 52x52 (divisé par 8) | Petit | Petits objets (ex: "feu de stop", "oiseau lointain"). |
C'est ce "plugin" multi-échelle qui a permis à YOLOv3 de battre les autres modèles sur les *petits objets*, ce qui était sa plus grande faiblesse en v2.
1. Anchor Boxes (via k-means)
YOLOv3 (comme v2) n'est *pas* "anchor-free" (contrairement à v8). Il utilise des "boîtes d'ancrage" (Anchor Boxes), qui sont des ratios de boîtes pré-calculés (un "plugin" de configuration).
Il y a 9 "anchors" au total (découverts par k-means clustering sur le dataset COCO) :
- 3 anchors pour la grille 13x13 (les 3 plus grands).
- 3 anchors pour la grille 26x26 (les 3 moyens).
- 3 anchors pour la grille 52x52 (les 3 plus petits).
2. BCE Loss (Binary Cross-Entropy)
C'est la 2e innovation "non-visible" de v3.
Problème (YOLOv2) : v2 utilisait une Softmax pour la classification. Si l'objet est "chien", il ne peut *pas* être "animal". (Exclusivité mutuelle).
Solution (YOLOv3) : v3 remplace le Softmax par plusieurs Sigmoïde (Logistic Classifiers) (un par classe), et utilise la BCE Loss.
Résultat : Permet la classification multi-label. Un objet peut être prédit comme "Femme" ET "Personne" en même temps.
Contrairement à VGG/ResNet (PyTorch/TF), YOLOv3 a été développé (par Joseph Redmon) dans son propre framework "plugin" : Darknet.
Darknet est un framework de Deep Learning écrit en C et CUDA. Il est *extrêmement* léger, rapide, et n'a (presque) aucune dépendance.
Les 4 Fichiers de Darknet
Un modèle Darknet est défini par 4 types de fichiers :
| Fichier | Description |
|---|---|
darknet | L'exécutable (compilé depuis le C). C'est l'outil CLI. |
.cfg (ex: yolov3.cfg) | Le fichier de Configuration. Il *définit l'architecture* (couches, filtres, anchors). C'est le "plugin" d'architecture. |
.weights (ex: yolov3.weights) | Les Poids (Paramètres) entraînés. C'est le "gros" fichier (>200MB). |
.names (ex: coco.names) | Fichier texte (\n) qui liste les noms des classes (ex: "person", "dog"). |
Exemple (yolov3.cfg)
Le .cfg est un "plugin" qui décrit le réseau (comme le code PyTorch de ResNet).
[convolutional] batch_normalize=1 filters=64 size=3 stride=1 pad=1 activation=leaky # (Utilise LeakyReLU, pas ReLU) [residual] # (Le "skip connection" de Darknet-53) from=-3 activation=linear ... [yolo] # (La "tête" de détection) mask = 0,1,2 anchors = 10,13, 16,30, 33,23 classes=80 ...
L'utilisation "classique" de YOLOv3 se fait via l'exécutable darknet.
Détection (Image)
# 1. Télécharger les poids pré-entraînés $ wget https://pjreddie.com/media/files/yolov3.weights # 2. Lancer la détection # (darknet detect [config] [poids] [image]) $ ./darknet detect cfg/yolov3.cfg yolov3.weights data/dog.jpg # Sortie (texte): # dog: 99% # truck: 93% # bicycle: 99% # (Sauvegarde 'predictions.jpg' avec les BBox)
Détection (Vidéo / Webcam)
# 1. Vidéo (affiche le 'live' OpenCV) $ ./darknet detector demo cfg/coco.data cfg/yolov3.cfg yolov3.weights video.mp4 # 2. Webcam (source 0) $ ./darknet detector demo cfg/coco.data cfg/yolov3.cfg yolov3.weights -c 0 # 3. Seuil de confiance (Threshold) # (N'affiche que les détections > 50%) $ ./darknet detector demo ... -thresh 0.5
YOLOv3 (Darknet) est en C. Comment l'utiliser en Python (ex: dans un backend FastAPI) ?
La solution "plugin" la plus populaire est d'utiliser le module cv2.dnn (Deep Neural Network) d'OpenCV. Ce module sait lire les .cfg et .weights de Darknet.
Exemple (Python + OpenCV)
import cv2
import numpy as np
# 1. Charger le réseau (le "plugin" dnn)
net = cv2.dnn.readNetFromDarknet("yolov3.cfg", "yolov3.weights")
# 2. Charger les noms des classes
with open("coco.names", "r") as f:
classes = [line.strip() for line in f.readlines()]
# 3. Charger l'image
img = cv2.imread("dog.jpg")
height, width, _ = img.shape
# 4. Préparer le "Blob" (image formatée pour YOLO)
blob = cv2.dnn.blobFromImage(img, 1/255.0, (416, 416), swapRB=True, crop=False)
net.setInput(blob)
# 5. Lancer l'Inférence (Forward Pass)
# (Obtenir les noms des 3 couches de sortie (FPN))
layer_names = net.getLayerNames()
output_layers = [layer_names[i - 1] for i in net.getUnconnectedOutLayers()]
# (Lance la détection)
outputs = net.forward(output_layers)
# 6. Parser les "outputs" (très complexe !)
# (YOLOv8 simplifie *massivement* cette étape)
for output in outputs:
for detection in output:
scores = detection[5:]
class_id = np.argmax(scores)
confidence = scores[class_id]
if confidence > 0.5:
# (Calculer x, y, w, h...)
# (Appliquer NMS - Non-Maximum Suppression)
# (Dessiner les boîtes...)
pass
L'entraînement (Transfer Learning) avec Darknet (v3/v4) est un processus *très* manuel comparé à YOLOv8.
1. Le Fichier obj.data (Le "Manifeste")
# (Fichier de config de l'entraînement) classes = 2 # (ex: chat, chien) train = data/train.txt valid = data/valid.txt names = data/obj.names backup = backup/ # (Où sauver les .weights)
2. Le Fichier train.txt (Liste des images)
data/obj/img1.jpg data/obj/img2.jpg data/obj/img3.jpg ...
3. Les Fichiers .txt (Labels)
(Identique à YOLOv8, voir 2.3 YOLOv8). Format [class_id] [x_c] [y_c] [w] [h].
4. Le .cfg (Le "Plugin" d'Archi)
Vous devez *copier* yolov3.cfg et le *modifier* manuellement (c'est l'étape la plus complexe) :
- Changer batch=64, subdivisions=16.
- Changer classes=80 en classes=2 (dans les 3 couches [yolo]).
- Changer filters=255 (juste avant [yolo]) en filters=(classes + 5) * 3 (ex: (2 + 5) * 3 = 21).
5. Lancement (CLI)
# 1. Obtenir les poids pré-entraînés (le "backbone" seul) $ wget https://pjreddie.com/media/files/darknet53.conv.74 # 2. Lancer l'entraînement (Transfer Learning) $ ./darknet detector train data/obj.data yolov3-custom.cfg darknet53.conv.74
YOLOv3 (Joseph Redmon, 2018) a été le SOTA, mais Redmon a quitté la recherche en IA (2020). L'héritage a été repris par deux successeurs majeurs en 2020.
| Modèle | Auteur(s) | Date | Innovation (Le "Plugin") |
|---|---|---|---|
| YOLOv4 | Alexey Bochkovskiy (AB) | Avril 2020 | "Bag of Freebies/Specials". (A gardé le C/Darknet). A pris v3 et a "pluggué" *tous* les meilleurs "hacks" de 2019 : - Backbone: CSPDarknet53 - Neck: PANet (mieux que FPN) - Addons: Mish (activation), SAM (attention) |
| YOLOv5 | Ultralytics (Glenn Jocher) | Juin 2020 | La Révolution (Framework). A *totalement abandonné* le C/Darknet. Ré-écriture 100% en PyTorch. Similaire à v4 (CSPDarknet, PANet), mais *infiniment* plus facile à utiliser, installer ( pip), et entraîner. |
| YOLOv8 | Ultralytics | Jan 2023 | (Voir Guide YOLOv8). |
Conclusion : YOLOv5 (et son framework PyTorch/Ultralytics) est devenu le nouveau "standard" en 2020, rendant l'écosystème C/Darknet de YOLOv3/v4 obsolète pour la plupart des nouveaux projets.
Exemples de Projets (Typiques 2018-2020)
YOLOv3 a été le "cheval de bataille" pour des milliers de projets "edge" (souvent en C++).
- Caméras de Sécurité : Comptage de personnes, détection d'intrusion (sur des "edge devices" comme NVIDIA Jetson).
- Trafic Routier (ANPR) : Détection de
voiture,camion,plaque. - Industrie (Contrôle Qualité) : Détection de défauts (entraîné sur un dataset custom).
Pourquoi l'utiliser aujourd'hui ?
Pour un *nouveau* projet, utilisez YOLOv8 (Ultralytics). C'est plus facile, plus rapide, et plus précis.
Vous ne devriez utiliser YOLOv3 que si :
1. Vous devez maintenir un projet "legacy" (historique) qui est basé sur le framework C/Darknet.
2. Vous avez une contrainte matérielle (ex: un vieux Jetson) qui est optimisée *spécifiquement* pour l'ancien .cfg/.weights de Darknet.
- PJ Redmon (Site Originel) Le site (et le papier "YOLOv3: An Incremental Improvement") de l'auteur originel.
- Darknet (Repo Originel) Le dépôt C/CUDA de Joseph Redmon (non-maintenu).
- Darknet (Fork de AlexeyAB) Le "fork" (addon) qui a continué le développement (et a créé YOLOv4).
- OpenCV DNN Module (Docs) La documentation du "plugin" OpenCV pour lire les modèles Darknet.
