Résumé de section
-
Pour réaliser notre objectif d’avoir une intelligence artificielle qui fait de la détection, il nous faut un modèle. Voyez le comme un cerveau rempli de neurones, lesquels vont devoir apprendre pour réaliser la tâche demandée. Créer un cerveau n’est pas une chose aisée à faire donc on utilise ceux fabriqués par des professionnel·les. Il ne nous reste donc qu’à entrainer les neurones. En l’occurrence, nous allons utiliser les modèles YOLO (You Only Look Once) de l’entreprise Ultralytics. Plusieurs versions existent, au fur et à mesure qu’ils les développent, et nous utiliserons la dernière en date à savoir YOLOv26.

Pour commencer, nous avons besoin de ce qu'on appelle environnement virtuel Python, que nous allons expliquer et créer ensemble.
Pour ceux qui ne seraient pas familier avec cette notion, les environnements virtuels dans un ordinateur c’est un petit peu comme plusieurs appartements dans une grande maison. Chaque appartement est indépendant, autonome et totalement fonctionnel individuellement. C’est pour faire en sorte que si un nouveau locataire arrive, il ait son chez lui et qu’il y fasse ce qu’il veux au lieu d’être embêté par les règles de vie des autres.
Nous, c’est pareil, on veut que notre code fonctionne directement, sans avoir de soucis avec l’ordinateur donc on crée un “mini-ordinateur” virtuel à l’intérieur de l’ordinateur physique.
Installation de uv
Pour créer cet environnement virtuel, nous allons utiliser un outil qui s’appelle uv, c’est un peu comme l’architecte et les ouvrier·es de la maison, c’est cet outil qui sait concevoir des environnements et les construire.
On va donc commencer par le télécharger.
Pour Windows :
Pour Linux/macOS :
Mise en place de l'environnement virtuel (appelé venv pour Virtual ENVironnement)
Voila, l’outil pour créer un environnement virtuel est installé (l’architecte et les ouvrier·es sont arrivé·es). Il faut maintenant créer le plan de l’appartement en précisant tout ce dont on a besoin. C'est justement dans ce fichier que nous allons préciser qu'il nous faut Python et la librairie Ultralytics. Ce plan est un fichier .toml que l’on va fabriquer ensemble.
Commencez par ouvrir un éditeur de texte (bloc-notes par exemple pour Windows).
Et dans un fichier vierge, copiez-collez les lignes suivantes :
[project]name = "your_project_name"version = "0.1.0"description = "Add your description here"readme = "README.md"requires-python = ">=3.12"dependencies = [ "ultralytics>=8.4.18", ]Ensuite faites “Enregistrez sous” :
- allez dans votre répertoire de travail (là où vous aviez extrait votre archive .zip de Roboflow)
- dans Type sélectionnez “Tous les fichiers (*.*)”
- dans Nom du fichier écrivez “pyproject.toml” (ce nom doit être exact, il ne peut pas être différent).
- et enfin, enregistrez.

Point important : vérifiez que ".toml" est bien l'extension de votre fichier. Pour cela, vous devez d'abord afficher les extensions des documents (Afficher --> Afficher (tout en bas) --> Extensions de noms de fichiers) puis vérifier que le nom du fichier termine bien par ".toml".
Code python
Maintenant, créez un fichier python toujours dans le même dossier, de la même façon que précédemment :
- ouvrez un outil d’édition de texte
- écrivez les trois lignes ci-dessous (vous pouvez copier-coller)
- “enregistrer sous”
- mettez l’extension .py (même démarche qu’avant mais au lieu du .toml, il faut mettre .py).
Les lignes en question :
from ultralytics import YOLOmodel = YOLO(“yolo26n.pt”)results = model.train(data=”data.yaml”, epochs=100, imgsz=640)Explications
-
-
model = YOLO(“yolo26n.pt”)
-
Cette ligne sert à préciser quel modèle on veut entraîner. Yolo propose 5 tailles de modèle: nano (“n”), small (“s”), medium (“m”), large (“l”), extralarge (“x”). Cela fonctionne intuitivement, les petits sont plus rapides mais moins robustes et les plus grands prennent plus de temps de calcul mais sont plus performants. Ici, le 'n' dans 'yolo26n.pt' correspond à la taille nano.
Ces modèles sont pré-entraînés pour gagner du temps d’entraînement et de la précision.
(Pour les pros de l’IA, Yolo propose aussi de construire son propre réseau de neurones en faisant chaque couche à la main dans un fichier .yaml : voir documentation)
Passons à la ligne suivante :
-
-
results = model.train(data=”data.yaml”, epochs=100, imgsz=640)
-
data : mettez le nom de votre fichier .yaml fourni dans le .zip de Roboflow
epochs : les époques correspondent au nombre de fois que le modèle doit tourner. Pour faire très simple, le modèle regarde toutes les images dans le dossier d’entrainement pour ajuster ses paramètres. Le nombre d’époques correspond au nombre de fois où il passera à travers toutes les images.
imgsz : correspond à la taille de vos images, donc indiquez celle que vous avez mise dans Roboflow. Sachant que 640 est la valeur par défaut donc si vous voulez des images plus grandes (ou plus petites) il faut absolument le préciser sinon elles seront rapetissées (ou agrandies).
Pour vous donner quelques ordres de grandeur des paramètes classiques :
- model : yolo26n.pt (version Nano pour la vitesse) ou yolo26s.pt (Small pour la précision).
- epochs : 100 est la valeur par défaut. Pour de petits jeux de données, vous pouvez monter à 300.
- imgsz : 640 est la valeur par défaut. Utilisez 320 pour plus de rapidité ou 1280 pour détecter de très petits objets.
- batch : -1 pour l'ajustement automatique à votre mémoire VRAM, ou 16 par défaut.
- device : 0 pour utiliser votre premier GPU ou cpu si vous n'en avez pas.
Concernant la taille du modèle, il est recommandé de passer à un modèle plus grand que YOLO26s (comme les versions m, l, ou x) dans les situations suivantes :
- Besoin d'une précision maximale : Si votre modèle actuel souffre d'underfitting (sous-apprentissage) et ne parvient pas à capturer les détails complexes, un modèle plus large offre une plus grande capacité d'apprentissage.
- Complexité du dataset : Pour des jeux de données volumineux (> 50 000 images) avec de nombreuses classes ou des scènes denses, les modèles Medium ou Large sont plus performants.
- Objets difficiles : Si vous travaillez sur des images haute résolution avec de très petits objets (comme l'imagerie aérienne ou médicale), la capacité accrue aide à réduire les erreurs de détection.
- Ressources matérielles suffisantes : Utilisez un modèle plus grand si votre déploiement se fait sur serveur (comme le cluster ISDM MESO) ou sur GPU puissant plutôt que sur mobile ou CPU.
Autres paramètres utiles de la fonction model.train()
Argument Type Défault Description
time float None Permet de définir un temps maximum de calcul. Si il existe, cet argument ignore le nombre d’époques et va jusqu’au temps indiqué. patience int 100 Permet d’indiquer au bout de combien d’époque de stagnation arrêter le code. Par exemple si le code atteint un plateau et y reste pendant 30 époque, on peut dire au code d’arrêter de tourner pour ne pas gaspiller des ressources. device int or str or list None Permet d’indiquer quel outil de calcul à utiliser : un seul GPU (device=0), plusieurs GPUs (device=[0,1]) ou CPU (device=cpu). project str None Si vous voulez donner un nom au dossier où vont être sauvegarder les résultats de vos entrainements. name str None Permet de donner un nom spécifique à un entrainement, donc permet de différencier plusieurs entraînements. exist_ok bool FAUX Si ce paramètre est mis sur True, cela permet de remplacer un dossier projet du même nom. Utile pour tester de manière itérative sans avoir à supprimer manuellement l’entrainement précédent. Ces paramètres sont des paramètres basiques pour personnaliser votre entraînement. Mais pour améliorer l’entrainement, il y a d’autres paramètres que l’on peut ajuster. Nous en parlons plus loin dans la formation sachant que pour commencer, les valeurs par défaut de YOLO permettent d’obtenir des résultats déjà très satisfaisants.
Augmentation
Nous sommes arrivé·es au point des explications sur la désactivation des augmentations par défaut sur YOLO.
Dans le cas où vous avez fait de l’augmentation avec Roboflow et que vous ne voulez pas que l’augmentation de YOLO interfère, ajoutez les lignes en bleu dans ci-dessous. Bien penser à garder vos premiers paramètres donc data, epochs, imgsz, etc ...
model.train(
data="data.yaml",
epochs=100,
imgsz=640,
hsv_h=0.0, # Disable color (Hue)
hsv_s=0.0, # Disable color (Saturation)
hsv_v=0.0, # Disable color (Value)
degrees=0.0, # Disable rotation
translate=0.0, # Disable translation
scale=0.0, # Disable scaling
shear=0.0, # Disable shear
perspective=0.0, # Disable perspective
flipud=0.0, # Disable vertical flip
fliplr=0.0, # Disable horizontal flip
mosaic=0.0, # Disable mosaic
mixup=0.0, # Disable mixup
copy_paste=0.0, # Disable copy-paste
auto_augment=None, # Disable auto-augment policies
erasing=0.0 # Disable random erasing
)
Sinon, si vous êtes dans le cas où vous n’avez pas fait d’augmentation avec Roboflow car le plus simple est de laisser YOLO en faire par défaut, alors n'écrivez rien de ce qui est en bleu au-dessus et les paramètres prendront leur valeur par défaut et YOLO fera ses augmentations.
Point étape final
Votre dossier de travail doit ressembler à ça normalement à la fin :

Note : il peut y avoir des variations avec les fichiers train, val et test en fonction de comment vous avez organisé vos données. Le plus important c’est que le fichier data.yaml soit cohérent avec les chemins respectifs.
Lancer le code
Normalement tout est prêt, donc on va pouvoir lancer le code, pour cela :
- Allez dans votre dossier de travail
- Faites un click droit pour ouvril un terminal dans ce dossier

(Si vous êtes sur macOs, ouvrez un terminal comme vu précédemment puis entrez : cd chemin/absolu/vers/votre/dossier/de/travail )
Dans le terminal, écrivez la commande suivante puis clickez sur entrée :
uv run nom_de_votre_fichier_python.pyLa toute première fois que vous effectuez cette commande, la réponse va prendre beaucoup de temps, car avant de lancer votre fichier python, il va falloir que l’architecte lise le plan (pyproject.toml) et mandate les ouvrier·es de construire ce que requiert ce plan (python, ultralytics, etc...) et qu’ensuite ce soit construit. Mais dans la logique, dès la deuxième fois, l’environnement étant déjà fabriqué, la même commande sera beaucoup plus rapide.
Une fois votre entrainement fini, vous aurez besoin de pouvoir évaluer la qualité de cet entrainement. Dans la prochaine section "Résultats", vous serez amené·e à comprendre tous les éléments que YOLO calcule à la fin de son entrainement, mais si vous avez juste besoin de savoir si votre modèle est bien sans comprendre, vous pouvez vous rendre directement dans la sous-section "Conclusion" de "Résultats".
-
Vous avez fini d'entraîner votre modèle et vous vous demandez maintenant comment vous en servir ou comment l'intégrer à votre code déjà existant.
Si vous êtes dans un environnement Python, vous pouvez garder le modèle tel quel, sinon vous devez l'exporter. L'exportation permet de convertir un modèle YOLO (initialement en PyTorch
.pt) dans un format optimisé pour des matériels spécifiques, améliorant ainsi la vitesse d'inférence (jusqu'à cinq fois plus rapide sur GPU avec TensorRT par exemple) et réduisant la consommation de ressources sur les appareils mobiles ou embarqués. Vous pouvez trouver tous les formats dans lesquels YOLO peut exporter sur cette page dédiée au sujet, ainsi que les arguments d'export expliqués juste au dessus.Si vous restez dans l'environnement Python que vous aviez lors de l'entrainement, pour utiliser votre modèle, il suffit d'utiliser les lignes suivantes :
from ultralytics import YOLOmodel = YOLO("best.pt") # Charger le meilleur modèleresults = model.predict(source="chemin_vers_votre_image/image.jpg", conf=0.25) # N'oubliez pas de spécifier le seuil de confiance optimal iciL'objet results contient l'objet boxes. Et cet objet regroupe les informations suivantes pour chaque détection :
- coordonnées : accessibles via xyxy (coordonnées coin haut gauche et bas droite), xywh (coordonnées du centre/largeur/hauteur), ou leurs versions normalisées xyxyn et xywhn.
- confiance : l'attribut conf donne le score de probabilité (0 à 1) pour chaque boîte.
- classes : l'attribut cls contient l'index de la classe prédite (vous pouvez retrouver à quoi correspondent les indices dans le fichier data.yaml utilisé pour l'entrainement)
- tracking : Si vous utilisez model.track(), l'attribut id contient les identifiants de suivi.
Voyons un exemple de code :
results = model("image.jpg")for r in results: # vous aurez autant de résultats qu'il y a d'objets détectés sur l'imageprint(r.boxes.xyxy) # récupération des coordonnées des coinsprint(r.boxes.xywh) # récupération des coordonnées du centre et de la taille de la boîteprint(r.boxes.conf) # scores de confianceprint(r.boxes.cls) # index qui correspond à la classe de l'objet en questionVous pouvez donc récupérer les informations qui vous intéresse de cette manière et les utiliser pour des calculs ou autre dans la suite de votre code.
-
Yolo propose différents paramètres qui peuvent changer l’issue de l’entraînement, on va voir lesquels mais pour cela, nous allons devoir aborder quelques thématiques propres à l’intelligence artificielle : la fonction de perte (aussi appelée fonction de coût) et l’optimiseur.
Le schéma ci-dessous permet de comprendre comment les différentes composantes s’organisent entre elles. Nous allons voir étape par étape ce qu’il se passe.

Commençons par le modèle vu qu’on travaille avec depuis le début.

Le modèle peut être vu comme un jeu de chute de bille, voir la photo ci-dessous. Le principe de ce jeu est de lâcher une bille en haut d’un plateau vertical rempli de clous et de regarder dans quel bac elle tombe en bas pour marquer des points.

Le fonctionnement du modèle est similaire au plateau de clous, c’est-à-dire que le modèle en lui même est passif, il prend juste une entrée (bille → image), la fait passer dans son algorithme (clous → neurones) puis donne une sortie (bac → classe + boite).
Les clous sont semblables aux neurones du modèle, c’est-à-dire que si on veut que la bille aille bien où nous voulons, il va falloir placer les clous judicieusement. C’est exactement pareil avec notre modèle, il est passif, mais les autres composantes du schéma (fonction de perte et optimiseur) vont venir arranger les clous pour que notre modèle soit capable de faire tomber les billes dans le bon bac.
Propagation avant
La propagation avant est le fait de donner une image (ou plusieurs) au modèle et de regarder ce qu'il se passe quand cette image traverse le modèle. Donc lâcher la bille depuis le haut du plateau et regarder dans quel bac elle arrive.
Pour parler de la propagation avant, ou forward pass, nous allons utiliser une seconde analogie que nous garderons le long de l’explication du modèle.
Un·e professeur·e décide de faire un travail noté. Faire un examen comporte plusieurs étapes similaires à un entrainement :
- préparer le sujet → annoter les données
- le donner à faire aux élèves → propagation avant
- corriger leur travail → fonction de perte
- les évaluer de nouveau plus tard pour s’assurer qu’ils ont appris → répétition des trois pas précédents

L’élève est semblable à un paramètre du modèle, il a des connaissances, puis en fonction de celles ci, il donne des réponses. L’ensemble des élèves constitue le modèle entier.
Fonction de perte
Maintenant, regardons la fonction de perte :

Maintenant que le professeur a récupéré les copies il va les corriger. Donc comparer les réponses aux bonnes réponses attendues. Mais il peut avoir plusieurs critères pour noter une copie :
- exactitude des résultats
- pertinence des explications
- belle écriture/lisibilité
Ainsi, à l’aide de ces trois paramètres, la performance se verra attribuée une note.

De la même façon, pour savoir si le modèle a fait une bonne prédiction, on va prendre des critères et voir à quel point ils sont satisfaits. Ces critères sont rassemblés dans une équation qu’on appelle une fonction de perte. La fonction de perte est en charge d’évaluer l’écart entre une prédiction et la vérité terrain. Le but est de pouvoir quantifier cet écart, pouvoir mettre un nombre dessus pour avoir une idée de la qualité du résultat.
YOLOv26 utilise trois critères :
- choix de la bonne classe (cls) : pour quantifier une “distance” entre deux classes, on peut le voir comme un arbre phylogénétique où chaque chemin pèse de 1 dans la balance. Par exemple, si le modèle prédit “bird” à la place de “snake”, on a une distance de 5. Ce n’est pas ainsi que YOLO fait, mais cela permet de se faire une idée.
- précision dans le positionnement de la boite englobante (box) : pour ce cas, on va regarder à quel point la boite prédite et la boite réelle se chevauchent.
- affinage de la précision des boites pour les objets aux contours flous (dfl) : on ne va pas s’attarder sur cette mesure car elle est un peu complexe.
Pour une prédiction faite, on aura donc trois pertes :
- celle liée à la classe : cls_loss
- celle liée au placement de la boite englobante : box_loss
- celle liée à la précision des bordures de la boite : dfl_loss
On les additionne ensuite pour avoir un score global de la prédiction. Cette addition constitue la base de la fonction de perte.

Ce qui est très important à comprendre, c’est que même si on ne les voit pas, les paramètres sont à “l’intérieur” de chaque perte. Cela est très utile car cela va nous permettre plus tard de nous guider : si la cls_loss est grande c’est parce que le paramètre 158 est pas comme il faut etc...
Sous cette forme, la fonction de perte est incomplète, il y a plusieurs éléments à rajouter.
Pour commencer, on ajoute une pondération, c’est à dire un facteur devant chaque perte pour pouvoir hiérarchiser les pertes dans le résultat total. On peut le voir comme les coefficients des matières au lycée : coefficient 7 en maths donc la note de maths pèse beaucoup dans la moyenne alors qu’on a que coefficient 2 en français donc la note est moins “moins importante” dans le calcul de la moyenne.
Prenons λ1, λ2 et λ3 nos coefficients (appelés “gain” en vision par ordinateur), l’équation devient :

Les trois lambdas ont des valeurs prédéfinies par YOLO (λ1 = 0.5, λ2 = 7.5, λ3 = 1.5) mais vous pouvez toujours les modifier si vous voulez.
Il reste un dernier membre à cette fonction de perte. Ce membre de l’équation ne sert plus à mesurer l’écart entre la prédiction et la vérité terrain mais est un terme qui va servir de pénalisation. Bien sûr, toujours dans l’optique d’améliorer notre modèle. Voyons l’intérêt.
Un phénomène assez courant en apprentissage (même pour les humains) est le surapprentissage, c’est-à-dire quand on apprend par cœur nos données d’entrainement au lieu d’apprendre à généraliser. Exemple : apprendre par cœur une démonstration de mathématiques sans comprendre la méthode.
Comment cela se traduit pour un modèle ? Ses paramètres prennent de très grandes valeurs qui sont adaptées aux données d’entrainement mais une fois confrontés à de nouvelles images, ce sera un échec.
Donc comment faire en sorte que le modèle ne tombe pas dans le surapprentissage ? En intégrant la somme des poids dans la fonction de perte, comme ça, le modèle ne peut s’améliorer qu’en ayant des paramètres de faible valeurs. (Utile de rappeler ici que l’objectif est de faire en sorte que le résultat de la fonction de perte doit être le plus petit possible.)
La forme que prends ce membre de l’équation est la suivante :

Ce terme porte un nom spécifique en anglais : weight decay (le terme français est L2 régularisation, mais nous utiliserons ici le terme anglais donc weight decay).
La forme finale de la fonction de perte est donc :

Pour chaque prédiction faite (donc chaque image), on récupère la valeur issue de la fonction de perte puis on moyenne cette valeur avec toutes les autres images pour avoir une valeur unique. Cette valeur correspond à ce qu’on pourrait appeler le score du modèle et le but va être de minimiser ce score pour rendre l’écart entre la prédiction et la réalité la plus petite possible.
Ce sera la mission de l’optimiseur : modifier les paramètres du modèle pour que l’erreur diminue.
Pour comprendre comment fonctionne l’optimiseur, il est astucieux de visualiser spatialement la fonction de perte. Pour visualiser la fonction de perte en trois dimensions on va imaginer un réseau constitué de 2 paramètres. (Ce qui n’est pas beaucoup car même un escargot a 11 000 neurones 🐌). On obtient une surface qui peut ressembler à celle ci-dessous:

Contrairement à ce que laisse penser le schéma ci-contre, on ne peut pas calculer la fonction de perte dans son entièreté et voir le minimum directement, car ce serait démesuré en terme de calcul (il y a plus de calculs à faire qu’il n’y a d’atomes dans l’univers).
Simulons un entraînement : le modèle vient de finir une propagation avant et donc calcule son erreur grâce à la fonction de perte. Cela nous place à un endroit donné de la courbe : petite chèvre 🐐 des montagne ci-dessous :

L’objectif ici est de descendre jusqu’au point le plus bas, donc l’endroit pointé par la flèche, mais on ne sait pas où il est dans le cas pratique.
Donc la seule chose que l’on peut faire c’est regarder notre environnement très proche pour regarder la “tendance” de la montagne. Imaginez : vous êtes perdu en randonnée et il y a un brouillard très épais. Vous ne voyez pas où vous devez aller, mais vous savez que vous devez descendre pour avoir une chance de manger votre dessert préféré à nouveau 🍰. Vous entreprenez donc avec vos pieds de chercher de quel côté le relief descend le plus, c'est le même principe ici.
Optimiseur
C’est lui qui va se charger de trouver le chemin à prendre pour descendre de la montagne.

L’optimiseur va faire pareil que vous sur la montagne embrumée, il va regarder autour de son point de départ dans quelle direction il doit aller pour descendre.
L’outil mathématique qui permet de trouver la pente la plus raide (steepest slope/descent en anglais) sur une surface est le gradient (car oui, le modèle n’a malheureusement pas de pieds pour tâter le sol...). Le gradient est une dérivée vectorielle, c’est-à-dire qu’il permet de trouver la tangente la plus penchée d’une surface de dimension x. Ce processus qui consiste à prendre le gradient pour trouver la descente s’appelle, de manière très originale, la descente de gradient (gradient descent en anglais).
Une fois que l’on a la direction, il faut décider de la taille du pas qu’on fait. Est-ce qu’on fait une grande enjambée au risque de tomber sur quelques chose qu’on n’avait pas vu, ou un pas tout petit pour avancer de manière plus sûre mais donc prendre plus de temps ?
C’est un des rôles de l’optimiseur, il va décider comment le modèle avance, soit prudemment, soit frénétiquement, soit de manière adaptée au contexte.
La longueur du pas que l’optimiseur va faire prendre au modèle s’appelle le taux d’apprentissage (learning rate en anglais).
Les deux graphiques ci-dessous montrent comment le taux d’apprentissage influence l’entrainement :

Sachant que sortir d’un “trou” n’est pas forcément une mauvaise chose car on peut se retrouver dans un minimum local, c’est-à-dire un minimum par rapport au relief adjacent mais qui ne correspond pas au point le plus bas de la montagne de manière globale.
Sur le dessin ci-dessous par exemple, on ne veut pas rester coincé·es dans le point “1”, on veut retrouver la plaine tout en bas.

Donc il ne faut pas non plus un pas trop petit.
Il existe des techniques pour adapter le pas en fonction de l’entrainement, comme dans l’exemple ci-dessous. Cela permet une approche beaucoup plus sur-mesure de l’entrainement.

Une fois qu’on a la direction et la taille du pas, on va pouvoir avancer dans cette direction. Pour cela, l’optimiseur va modifier les paramètres pour aller à ce point là.
Dans le cas ci-dessous, pour faire descendre vers le point la petite chèvre, il faut baisser la valeur des deux paramètres.

Dans le cas pratique, pour calculer comment chaque paramètre doit être modifié, l’optimiseur utilise les dérivées partielles (dérivée selon chaque paramètre) calculées par l’algorithme de rétroprogation pour ajuster la valeur de chaque poids du modèle.
Une fois tous les paramètres modifiés, le modèle reprend l’entrainement avec d’autre propagation avant pour continuer d’améliorer ses paramètres. Donc le modèle "descend" progressivement de sa montagne au fur et à mesure des entraînements.

L’entrainement s’arrête que le modèle “stagne” dans un minimum. C’est à ce moment que le modèle peut être testé sur de nouvelles données pour vérifier qu’il généralise bien.
Pour reprendre le parallèle avec la classe d’élève :
Le professeur a fini de corriger les copies et il estime qu’une correction devant la classe s’impose. Il va essayer de corriger les erreurs des élèves en leur faisant comprendre le mieux possible d’où elles viennent. Cette partie dépend de la manière de corriger du professeur.
Comme vu précédemment, à partir des résultats de la fonction de perte l’optimiseur va permettre de calculer les changements à apporter au modèle afin qu’il se rapproche du résultat souhaité. Les changements vont dans une direction et représentent la compréhension de l’élève vis à vis des erreurs. On appelle ça la rétropropagation, car on part de la fin du modèle pour mettre à jour l’intégralité de celui ci.

Les changements sont opérés sur chaque paramètre du modèle. Il y a différents optimiseurs qui ont des caractéristiques différentes, cela représente les différentes méthodes que le professeur peut utiliser pour faire comprendre la correction. Le plus classique est la descente de gradient simple.
Récapitulatif

Lien avec vos données
Petit aparté rapide pour faire le lien avec les données que l’on a préparé au tout début. Nous avons vu que nous pouvions donner jusqu’à trois dossiers d’images à YOLO : train, val et test.
Mais comment le modèle s’en sert-il ? Supposons un entraînement en 100 époques.

-
- TRAIN
Le dossier d’images “train” est utilisé pour faire le processus décrit précédemment, à savoir : propagation avant → fonction de perte → optimisation.
Disons qu’il y a 1600 images dans notre dossier train.
Le dossier est divisé en groupe d’images appelés batchs (16 images par batch par défault, mais ce paramètre peut-être changé), et ce qu'il va se passer, c’est que YOLO va formatter ces 16 images comme un volume (il va les concaténer spatialement en quelque sorte). Cela a plusieurs intérêts :
- cela est plus en phase avec le fonctionnement de l’ordinateur car le fait que les images soient organisées comme ça lui permet de les traiter en parallèle plutôt que les unes à la suite des autres, ce qui lui fait gagner du temps
- à la fin de chaque batch, le modèle fait une rétropropagation pour adapter les paramètres, donc on a 100 rétropropagations (batchs de taille 16 dans un dossier de 1600 images) dans une époque, au lieu d'une seule grosse rétropropagation à la fin d’une époque.
-
- VAL
La validation arrive à la fin de chaque époque (à part si vous avez mis manuellement val=False). Il est crucial de noter que le modèle fait des prédictions sur ces images mais aucune phase de rétropropagation ne suivra, donc le modèle n'apprendra pas sur ces images, ce qui fait qu'à chaque phase de validation, le modèle se comporte comme si c'était la première fois qu'il voyait ces images. Cette étape permet surtout de sortir des métriques, notamment la matrice de confusion et tout ce qui en découle. C’est notamment grâce à cette étape que le modèle est capable de choisir quelle itération du modèle est la meilleure pour pouvoir la mettre dans la fichier “best.pt”.
-
- TEST
Enfin, le dossier test permet de tester votre modèle sur d'autres données. Il faut lancer une commande spécifique. Vous pouvez retrouver toutes les infos dans la conclusion de la section "Résultats".
Si on fait une petite frise du fonctionnement d’un entrainement, on a :


À savoir que YOLO modifie la combinaison des images dans les batchs entre chaque époque.
Étude d'un cas pratique
En deep learning l’architecture de modèle classique est le réseau de neurones dense, c’est-à-dire que chaque couche de neurones est complètement connectée à ses voisines.

Chaque cercle correspond à un neurone et chaque flèche à un paramètre. Il dispose d’une couche d’entrée et d’une couche de sortie et entre ces 2 là un certains nombre de couches, dites cachées.
L’entrée contient la donnée sur laquelle on entraîne le modèle et au travers des paramètres et des neurones on récupère une sortie. C’est ce qu’on a précédemment appelé la propagation avant.
Lorsque l’on utilise le résultat de la fonction de perte pour mettre à jour les poids c’est la rétropropagation et l’optimisation, qui arrive à la fin de chaque batch.
Lorsque l’on a traité toutes les données, donc à l’issue de tous les batchs, on a terminé une époque.
Nous allons faire un exemple numérique afin de bien comprendre ce qu’il se passe.
Les neurones de la couche d’entrée contiennent les informations sur la donnée d’entrée.

Un neurone suit une règle de base afin de calculer sa valeur :

Avec ωkj le poids (paramètre) qui part du neurone j pour aller au neurone k, hj la valeur du neurone j et Φ une fonction d’activation.
Prenons l’exemple du calcul de h3 et utilisons la fonction identité qui est linéaire pour faire le calcul, même si de manière générale la fonction doit être non linéaire.

Si on fait la même chose pour tout le réseau on a :

À la fin nous avons la prédiction de notre neurone sur la valeur, qui est assez loin de la vérité.
Nous allons maintenant utiliser une fonction de perte pour estimer cette erreur. Nous utiliserons l’écart au carré :

Nous avons l’erreur à la fin de la propagation avant, il faut maintenant mettre à jour les paramètres afin d’améliorer le modèle à l’aide de la rétropropagation.
Nous allons utiliser une descente de gradient simple avec un taux d’apprentissage noté de 0.1.

Pour mettre à jour par exemple le poids w35 on utilise la formule suivante pour calculer son gradient :

Et ensuite pour mettre à jour sa valeur on utilise la dérivée partielle précédente et le taux d’apprentissage, selon l’optimiseur la formule peut changer :

Donc le poids prend la valeur 0.54 :

Ce processus est effectué sur tous les poids car on peut toujours exprimer la valeur d’un neurone par rapport aux poids desquels il dépend.
Il faut penser qu’il faut dériver la fonction d’activation, qui ici était la fonction identité.
Convolutional Neural Network (CNN)
YOLO traite des images, le fonctionnement du modèle est donc différent de ce que l’on a montré précédemment. C’est un modèle CNN qui utilise des filtres, afin d’extraire les caractéristiques des images. Les valeurs contenues dans les filtres sont les paramètres du CNN. Voici un exemple d’extraction de caractéristique avec un filtre.

Si on regarde le calcul ayant donné la case rouge R de la sortie on a :

Comme pour l’exemple précédent il y a une fonction d’activation. Chaque couche contient plusieurs filtres différents et il y a en général plusieurs couches successives.
La rétropropagation fonctionne de la même manière que dans l’exemple précédent afin de mettre à jour les paramètres, qui sont ici les valeurs des filtres.
Nous avons vu de manière succincte comment fonctionnait un modèle. Jusque là nous avons vu les paramètres, donc ce qui compose effectivement notre modèle, similaires à des neurones. Maintenant, nous allons parler des hyperparamètres.
Par opposition aux paramètres qui sont modifiés tout au cours de l’entraînement, les hyperparamètres sont fixés au début de l’entrainement et ne bougent plus après (avec quelques exceptions).
Comme hyperparamètre on retrouve :
- le nombre d’époques (fixé au début mais peut-être interrompue grace à l’hyperparamètre patience)
- la taille des batchs (valeur constante, peut être fixée ou choisie en fonction de la puissance de calcul de votre machine)
- tous les coefficients que l’on a vu jusque là donc λ1 (cls_loss), λ2 (box_loss), λ3 (dfl_loss), α (weight decay) qu’on retrouve dans la fonction de perte. (fixes)
- le taux d’apprentissage (varie pendant l’entrainement)
- tout ce qui est lié à l’augmentation de données (fixe)
- et plusieurs autres sur lesquels nous allons nous attarder
Ces hyperparamètres jouent un rôle important dans l’entrainement et il est parfois compliqué de savoir exactement les valeurs optimales, alors il faut tester plusieurs combinaisons.
Ajuster ces paramètres s’appelle le finetuning. Et chaque combinaison d’hyperparamètre aura des résultats différents.

Passons maintenant sur quelques hyperparamètres intéressants.
Dropout
Le dropout est un hyperparamètre qui va agir directement sur l’entrainement en changeant quelques dynamiques.
Revenons à notre classe d’élèves. Supposons une épreuve où les élèves doivent s’organiser par petits groupes pour faire des exercices notés avec pour objectif d’avoir la meilleure moyenne générale. Chaque groupe est assigné une matière différente. Si jamais le groupe assigné aux mathématiques est très bon, les autres groupes des autres matières n’auront pas besoin d’être bon pour avoir une bonne moyenne de classe. Dans le schéma, les flèches représentent les élèves et les neurones sont les matières.
Comme on a vu dans l’exemple, l’activation d’un neurone se fait avec tous les paramètres qui lui sont associés, cela va de même pour la sortie, la moyenne dans notre analogie.
Le but du dropout est de désactiver certains neurones lors des différentes propagations avant afin de ne pas dépendre de neurones spécifiques et de leurs paramètres associés et de bien généraliser le modèle. C’est une technique de régularisation.
Par exemple, si le modèle a “compris” que les oiseaux avaient un bec et ne se focalise plus que là-dessus, le moment où le bec est caché pour x raison, il ne sait plus reconnaitre un oiseau.
Le dropout est une valeur comprise entre 0 et 1. Il faut le comprendre comme une probabilité qu’un neurone se désactive lors d’une propagation avant.
On peut le schématiquement le voir comme ça :

Momentum
Le momentum est un hyperparamètre qui va agir directement sur l'optimiseur en influençant la direction prise pour la descente de gradient.
Regardons le phénomène visible sur le schéma ci-dessous. C’est une vue “du dessus” de la descente de gradient :

On voit bien que le chemin peut être très zigzaguant et que cela nous fait perdre en rapidité pour atteindre le minimum.
Pour éviter cela, il existe une méthode qui s’appelle le momentum, qui consiste à garder en mémoire les déplacements précédents, similairement à une boule très lourde qui roule et dont la direction est difficile à changer à cause de l’inertie.
Concrètement que se passe-t-il ? On calcule le gradient du point où nous sommes, mais au lieu d’aller strictement dans cette direction, on va faire une somme de vecteur en combinant le nouveau avec celui de l’itération précédente. Faisons un schéma :

On se retrouve donc avec une descente de gradients beaucoup plus fluide et continue, comme sur le schéma ci-dessous :

Mathématiquement, cela s’écrit :

Où ν est un coefficient compris entre 0 et 1 et qui permet de pondérer la prise en compte de la direction précédente. Sachant que le coefficient (1-ν) est pas systématique et sa présence dépend de la méthode utilisée.
Conclusion
Lors de l'entrainement d'un modèle d'intelligence artificielle, il y a de nombreux hyperparamètres qui sont là pour différentes raisons, soit pour converger plus rapidement, soit pour avoir un modèle plus précis ou plus robuste. En fonction de ce que vous voulez, vous pouvez modifier les hyperparamètres, mais chaque entrainement est unique et le même changement n'aura pas la même la même réaction sur deux entrainement différents. Changer les hyperparamètres n'est donc pas une science exacte mais un processus empirique, donc il vous faudra tester plusieurs combinaison pour savoir laquelle fonctionne le mieux.
Ultralytics fournit aussi un algorithme qui permet de chercher les meilleurs hyperparamètres, c'est la fonction model.tune(). Elle permet de lancer un entrainement qui va se répéter automatiquement en changeant ses hyperparamètres toute seule. Ce processus qui consiste à chercher les meilleurs hyperparamètres s'appelle le finetuning.
Voyons rapidement comment fonctionne la fonction. Pour la syntaxe de base on a :
model.tune(data=data.yaml,epochs=30,iterations=300)On retrouve data et epochs qui sont identiques à un entrainement normal. En revanche, iterations est un nouveau paramètre, c'est le paramètre qui permet de préciser le nombre de répétition que fera le modèle. C'est-à-dire que dans notre cas, le modèle va s'entrainer sur 30 époques en changeant 300 fois la combinaison d'hyperparamètres. On aura donc un temps de travail équivalent à 9000 époques, ce qui est très grand, surtout si vous avez beaucoup d'images, mais avec les bonnes ressources de calcul, cela peut vous permettre d'avoir un modèle plus performant à la fin. Vous trouverez toutes les informations nécessaires sur cette page d'Ultralytics.
De manière générale, le site d'Ultralytics est très bien fait avec beaucoup de ressource mais est en anglais. Vous pouvez cependant poser des question à leur chatbot à qui vous pourrez parlez en français si vous y êtes plus à l'aise.












































