Reprendre et itérer
Reprends exactement un entraînement interrompu, commence à chaud une nouvelle itération à partir de best.pt avec un taux d’apprentissage réellement appliqué, et compare les exécutions côte à côte.
Les projets réels se composent d’une série d’exécutions d’entraînement. Certaines s’arrêtent en cours de route — ordinateur portable fermé, session SSH interrompue, GPU cloud préempté — et repartir de zéro fait perdre des heures. D’autres arrivent à leur terme, et l’itération suivante doit s’appuyer sur elles plutôt que de recommencer avec COCO.
Dans cette leçon, tu vas interrompre une exécution puis la reprendre, commencer à chaud la deuxième itération à partir de best.pt avec un taux d’apprentissage réellement appliqué, et comparer toutes les exécutions dans un seul tableau. Tu découvriras aussi deux comportements de resume qui font perdre du temps discrètement.
Pratique
Choisir le bon type d’exécution#

| Situation | Type d’exécution | Point de départ |
|---|---|---|
| Coupure de courant, déconnexion ou manque de mémoire en cours d’exécution | Reprise | last.pt, avec son état d’optimiseur et son calendrier |
| Exécution terminée ; davantage de données, une correction des annotations ou un entraînement plus long | Démarrage à chaud | best.pt comme modèle préentraîné |
Classes ajoutées ou supprimées, nombreuses annotations modifiées ou imgsz fortement modifié | Nouvelle exécution | yolo26n.pt |
Exemple pratique : reprendre une exécution interrompue#
resume=True restaure le modèle, l’état de l’optimiseur, le calendrier du taux d’apprentissage et le compteur d’époques à partir de last.pt, puis poursuit le plan initial :
yolo train resume=True model=runs/detect/pills_resume/weights/last.ptSortie réelle d’une exécution de 5 époques arrêtée après l’époque 2 :
Resuming training runs/detect/pills_resume/weights/last.pt from epoch 3 to 5 total epochs
3/5 0G 1.232 2.393 0.005478 206 320: 100% 6/6 4.5s
4/5 0G 1.345 1.859 0.005833 208 320: 100% 6/6 4.5s
5/5 0G 1.31 1.625 0.005854 191 320: 100% 6/6 4.4s
3 epochs completed in 0.004 hours.from epoch 3 to 5 total epochs: l’exécution a repris exactement après la dernière époque enregistrée, avec l’objectif initial.- Tu n’as pas transmis
dataniepochs: tous les arguments proviennent du point de contrôle. Quelques paramètres d’exécution, commebatch,deviceetworkers, peuvent être remplacés lors de la reprise ; tout le reste est ignoré avec un avertissementResume ignores ....
Exemple pratique : commencer à chaud la deuxième itération#
La plupart des expériences de « prochaine itération » ne sont pas des reprises ; ce sont de nouvelles exécutions qui partent de ton dernier bon modèle — un simple apprentissage par transfert au sein de ton propre projet. Utilise un taux d’apprentissage plus faible pour affiner le modèle plutôt que de le réentraîner :
from ultralytics import YOLO
model = YOLO("runs/detect/pills_v1/weights/best.pt") # # démarrer à chaud à partir de l’itération 1
model.train(
data="my_dataset/data.yaml",
epochs=5,
imgsz=320,
optimizer="AdamW", # # définir explicitement : optimizer="auto" ignore lr0
lr0=0.0005, # # plus doux que le 0.002 sélectionné automatiquement pour l’itération 1
name="pills_v2_warm",
)Le journal confirme que le paramètre a bien été appliqué : optimizer: AdamW(lr=0.0005, momentum=0.937). Le guide d’ajustement fin aborde le gel des couches et l’entraînement en deux étapes ; le guide de réglage des hyperparamètres présente les balayages.
Exemple pratique : comparer les exécutions#
Nomme chaque exécution selon la modification — pills_v2_warm, pills_v3_imgsz640, pills_v4_edge_frames — jamais train2 ni final. Chaque exécution écrit un results.csv, donc la comparaison ne demande que quelques lignes :
from pathlib import Path
import pandas as pd
for csv in sorted(Path("runs/detect").glob("*/results.csv")):
df = pd.read_csv(csv)
best = df["metrics/mAP50-95(B)"].max()
print(f"{csv.parent.name:<14} epochs={len(df):<3} best mAP50-95={best:.3f}")pills_resume epochs=5 best mAP50-95=0.579
pills_v1 epochs=10 best mAP50-95=0.659
pills_v2_warm epochs=5 best mAP50-95=0.694Cinq époques avec démarrage à chaud ont fait passer mAP50-95 de 0.659 à 0.694, tandis que cinq époques à partir des poids COCO (pills_resume) n’ont atteint que 0.579. Le démarrage à chaud permet de progresser à moindre coût — tant que les classes et les annotations n’ont pas changé entre-temps. Après quelques exécutions, un outil de suivi devient vite rentable : Ultralytics Platform (voir Comparer les exécutions et choisir la meilleure), ou les intégrations Comet et Weights & Biases, qui enregistrent automatiquement chaque exécution.
Limiter le coût de chaque itération#
La plupart des itérations répondent à une question, par exemple « les nouvelles images ont-elles aidé ? ». Ces arguments permettent d’obtenir des réponses plus rapidement pendant l’exploration :
| Argument | Exemple | Effet |
|---|---|---|
fraction | fraction=0.5 | Entraîne le modèle sur la première moitié des images d’entraînement (triées par nom de fichier) |
time | time=0.25 | Arrête après 0.25 heure, en remplaçant epochs |
patience | patience=10 | Arrête si les performances de validation ne se sont pas améliorées pendant 10 époques |
imgsz | imgsz=320 | Un quart du nombre de pixels utilisé pour 640 ; compare les exécutions uniquement à la même taille |
cache | cache=True | Conserve les images décodées en RAM pour accélérer leur chargement lors des époques suivantes |
Ne change qu’un élément par itération, et confirme le meilleur résultat avec une exécution à taille réelle avant de le déployer. Quand tu dois repartir de zéro, utilise le même appel avec les poids préentraînés :
from ultralytics import YOLO
model = YOLO("yolo26n.pt") # retour aux poids préentraînés sur COCO
model.train(data="my_dataset/data.yaml", epochs=10, imgsz=320, name="pills_v3_relabeled")Éviter ces erreurs#
Symptôme : WARNING ⚠️ model '.../last.pt' is not a resumable training checkpoint ... Starting new training instead, suivi du lancement d'un nouvel entraînement — sur le jeu de données par défaut coco8, sauf si tu as passé data. Cause : resume=True ne reprend que les entraînements interrompus prématurément. Solution : arrête-le et lance volontairement un nouvel entraînement à partir de best.pt.
Symptôme : optimizer: 'optimizer=auto' found, ignoring 'lr0=0.0005' and determining best 'optimizer' and 'lr0' automatically... Cause : le optimizer=auto par défaut choisit son propre taux d'apprentissage. Solution : définis explicitement optimizer (par exemple "AdamW" ou "SGD") chaque fois que tu définis lr0, et vérifie la ligne optimizer: du journal.
Entraîner une deuxième fois avec name="pills_v1" écrit dans pills_v1-2, ce qui peut facilement prêter à confusion par la suite. Utilise un nom nouveau et descriptif pour chaque entraînement.
Afficher la solution
Si le timing de Ctrl+C est difficile sur une machine rapide, un callback peut arrêter l'exécution pour toi après l'époque 2 :
from ultralytics import YOLO
def power_cut(trainer):
if trainer.epoch == 1: # Indexation à partir de 0 : arrêter après l'enregistrement de l'époque 2
raise KeyboardInterrupt
model = YOLO("yolo26n.pt")
model.add_callback("on_model_save", power_cut)
model.train(data="my_dataset/data.yaml", epochs=5, imgsz=320, name="pills_resume")yolo train resume=True model=runs/detect/pills_resume/weights/last.pt
python round2.py
python compare_runs.pypills_v2_warm has the best mAP50-95 (0.694 vs 0.659 for pills_v1), with the same
classes and labels, so round three warm-starts from pills_v2_warm/weights/best.pt.