Iperparametri

Ogni argomento di addestramento è un campo di una dataclass TrainConfig. La classe base definisce il campo e il suo default; ogni famiglia di modelli ne fa una sottoclasse e sovrascrive i default che la sua ricetta pubblicata cambia.

Impostare gli argomenti

train() accetta argomenti keyword e la CLI accetta gli stessi nomi in forma key=value.

Python
from libreyolo import LibreYOLO model = LibreYOLO("LibreYOLO9s.pt")results = model.train(    data="my-dataset.yaml",    epochs=100,    batch=16,    imgsz=640,    lr0=0.01,) print(results["best_mAP50_95"])
CLI
libreyolo train model=LibreYOLO9s.pt data=my-dataset.yaml \  epochs=100 batch=16 imgsz=640 lr0=0.01

Entrambe le strade finiscono nello stesso punto. I kwarg vengono passati a TrainConfig.from_kwargs(), che costruisce la dataclass di configurazione della famiglia.

Un refuso non solleva errori

from_kwargs() scarta qualsiasi chiave che non sia un campo della configurazione ed emette un UserWarning che la nomina. A quel punto l'addestramento parte con il valore predefinito al suo posto:

python
# UserWarning: Unknown training config keys (ignored): ['learning_rate']model.train(data="my-dataset.yaml", learning_rate=0.001)

Niente fallisce, la run arriva in fondo e il learning rate (il tasso di apprendimento) non è mai stato quello che il chiamante aveva chiesto. Leggi i warning alla prima epoca di una nuova ricetta. La CLI è più severa, perché valida i nomi dei flag prima che la configurazione venga costruita, quindi un flag CLI scritto male viene rifiutato subito.

I default sono per famiglia

TrainConfig definisce il campo e un default di base. Ogni famiglia ne fa una sottoclasse e sovrascrive ciò che la sua ricetta pubblicata cambia, quindi non esiste una sola risposta corretta a «qual è il learning rate predefinito».

I default di base sono optimizer="sgd", lr0=0.01, momentum=0.937, weight_decay=5e-4, scheduler="yoloxwarmcos", epochs=300, batch=16, imgsz=640 e amp=True. Tre esempi di quanto una famiglia possa allontanarsi da quei valori:

CampoBaseYOLOv9D-FINEYOLO-NAS
optimizersgdsgdadamwadamw
lr00.010.012e-45e-4
weight_decay5e-45e-41e-41e-5
scheduleryoloxwarmcoslinearflat_cosinecos
epochs300300132300
ampTrueTrueTrueTrue

D-FINE, DEIM, RT-DETRv4 e il rilevamento YOLO-NAS usano amp=True con amp_dtype="float16" di default. Dome-DETR, PP-YOLOE e YOLO-NAS OBB mantengono FP32 come default. Passa amp=False quando è necessario FP32.

Per leggere i default reali di una famiglia invece di tirare a indovinare:

Leggere i default risolti di una famiglia
from dataclasses import fields from libreyolo import LibreYOLO9from libreyolo.training.config import TrainConfig family_cfg = LibreYOLO9.TRAIN_CONFIG()base_cfg = TrainConfig() for f in fields(family_cfg):    family_value = getattr(family_cfg, f.name)    base_value = getattr(base_cfg, f.name, None)    if not hasattr(base_cfg, f.name) or family_value != base_value:        print(f"{f.name}: {family_value}")
CLI
# Stampa i default di train, val e predict, comprese le sovrascritture di famiglia.libreyolo cfg

Dimensione del batch

batch è il batch globale. Nell'addestramento multi-GPU ogni rank carica batch // world_size, quindi il numero che passi è il numero di immagini per passo dell'optimizer, indipendentemente da quante GPU sono coinvolte. Vedi Addestramento multi-GPU.

batch=-1 attiva l'autobatch. Il trainer sonda il modello in modalità di addestramento con un vero passo backward su potenze di due, interpola una retta sulla curva di memoria e sceglie la più grande potenza di due strettamente sotto il valore estrapolato che rientra nel 60 per cento della VRAM totale.

Python
from libreyolo import LibreYOLO model = LibreYOLO("LibreYOLO9s.pt") # batch=-1 sonda la memoria GPU e si risolve in una potenza di due concreta.model.train(data="my-dataset.yaml", batch=-1, imgsz=640)
CLI
libreyolo train model=LibreYOLO9s.pt data=my-dataset.yaml batch=-1

Sondare in modalità di addestramento con un passo backward è il punto chiave: una sonda in modalità inferenza non tiene conto delle attivazioni trattenute e dei tensori dei gradienti, che per una CNN profonda valgono diverse volte l'ingombro dell'inferenza. RF-DETR abbassa la frazione obiettivo al 45 per cento, perché il backward sintetico della sonda sottostima comunque quanto costano il suo criterion e i layer del decoder ausiliario.

L'autobatch è una funzionalità CUDA. Su CPU o MPS scrive una riga di log e mantiene il batch predefinito.

min_samples=0 lascia invariata la lunghezza dell'epoca. Un minimo positivo campiona con reinserimento i dataset di rilevamento più piccoli. class_balanced=False, se impostato a true, attiva il campionamento con fattore di ripetizione per immagine; si combina con min_samples e DDP. I loader specializzati che non usano il campionatore condiviso rifiutano il bilanciamento attivo.

Accumulo dei gradienti

nbs imposta la dimensione nominale, o effettiva, del batch. Il trainer accumula round(nbs / batch) micro-batch per passo dell'optimizer.

Python
from libreyolo import LibreYOLO model = LibreYOLO("LibreYOLO9s.pt") # 4 micro-batch da 16 per passo dell'optimizer, batch effettivo 64.model.train(data="my-dataset.yaml", batch=16, nbs=64)

Lasciato a None, il valore predefinito, l'accumulo è disattivato e l'addestramento non cambia.

Learning rate e schedule

lr0 è il learning rate iniziale e optimizer accetta sgd, adam e adamw. momentum è il momentum di SGD o beta1 di Adam, weight_decay è il termine L2 e nesterov vale per SGD.

La forma dello schedule è data da scheduler, warmup_epochs, warmup_lr_start e min_lr_ratio. no_aug_epochs stabilisce quante epoche finali girano senza data augmentation forte, e diversi schedule lo usano anche per dare forma alla loro coda, quindi non è solo una leva per la data augmentation. Cosa fa ogni famiglia con la parte di data augmentation è su Data augmentation.

Alcune famiglie aggiungono le proprie leve per il learning rate. backbone_lr_mult scala il gruppo del backbone rispetto alla testa, clip_max_norm imposta il gradient clipping e SegFormer usa head_lr_mult per far girare la sua decode head a dieci volte il learning rate del backbone. Queste stanno sulla sottoclasse di configurazione della famiglia, non su quella di base.

clip_max_norm limita la norma L2 del gradiente a quel valore prima di ogni passo dell'ottimizzatore, e 0 disattiva il clipping. YOLOv9, YOLOv9-E2E e YOLOv9-P2 lo impostano di default a 10. D-FINE, Dome-DETR, DEIM, DEIMv2, TinyFormer, RT-DETR, RT-DETRv2, RT-DETRv4, RF-DETR, DINOv2, GTR ed EC lo impostano di default a 0.1. Sulla CLI è clip_max_norm= o --clip-max-norm; vedi libreyolo train per le famiglie che lo accettano lì.

EMA

ema=True mantiene una media mobile esponenziale dei pesi accanto a quelli addestrati. È attiva per default ovunque tranne che su FOMO.

ema_decay è il decay obiettivo. Il decay sale gradualmente invece di partire dal suo obiettivo: il valore effettivo all'aggiornamento n è ema_decay * (1 - exp(-n / tau)) con tau che vale 2000 per default, quindi gli aggiornamenti iniziali seguono il modello più da vicino e quelli tardivi lo smussano. I default di famiglia vanno da 0.997 su YOLO-NAS pose, passando per 0.9998 su YOLOX, fino a 0.9999 su YOLOv9 e sulla linea DETR.

I pesi EMA sono quelli che vengono validati e quelli che best.pt e last.pt portano con sé. Anche i pesi addestrati grezzi vengono salvati, sotto la chiave train_model, così un resume riprende dalla traiettoria addestrata invece che dalla media.

Precisione

amp=True esegue il passo forward sotto l'autocast CUDA. amp_dtype sceglie float16 (il default) o bfloat16; fp16 e bf16 sono grafie accettate.

Float16 ha bisogno del loss scaling dinamico e riceve un GradScaler attivo. Il range di esponenti più ampio di bfloat16 non ne ha bisogno, quindi il suo scaler viene costruito ma disabilitato, il che mantiene identico il percorso dell'optimizer. Chiedere bfloat16 su un dispositivo CUDA senza supporto bfloat16 solleva un errore durante il setup invece di degradare in silenzio.

Output, checkpoint e arresto

Le run vengono scritte in project/name. project vale runs/train per default ovunque, ma name è una delle sovrascritture per famiglia: il default di base è exp, mentre YOLOv9 usa yolo9_exp e D-FINE usa dfine_exp. Con exist_ok=False, il valore predefinito, una directory esistente riceve un suffisso incrementale invece di essere sovrascritta.

save_period scrive un weights/epoch_<N>.pt extra ogni N epoche, in aggiunta a weights/last.pt dopo ogni epoca e a weights/best.pt ogni volta che la metrica tracciata migliora. eval_interval stabilisce ogni quanto gira la validazione, e l'ultima epoca viene sempre validata; val=False disattiva la validazione, e una run così non scrive best.pt. patience ferma la run dopo quel numero di epoche senza miglioramenti, con 0 che disattiva l'early stopping.

cache accelera le epoche ripetute tenendo le immagini decodificate in RAM (True o "ram") o come file .npy accanto alle sorgenti ("disk"). Le letture dalla cache sono identiche byte per byte a quelle lette direttamente dalle sorgenti. Con i worker del dataloader, "disk" è la più sicura delle due.

average_best=0 disattiva la media dei checkpoint; un N positivo scrive weights/average.pt usando fino a N snapshot migliori. I tensori in virgola mobile vengono mediati uniformemente e i buffer interi provengono dallo snapshot migliore. export_check=False può essere attivato per interrompere l'esecuzione prima della prima epoca se l'esportazione ONNX fallisce. Gli output grezzi corrispondenti vengono confrontati con rtol=1e-3, atol=1e-4; strutture incompatibili vengono registrate come confronto saltato.

precise_bn=0 disattiva la ricalibrazione finale di BatchNorm. Un valore positivo limita il numero di immagini del loader di addestramento prima della validazione finale; con DDP il budget si applica a ogni rank partecipante. BatchNorm congelata resta congelata. Le callback di fitness personalizzate possono scegliere i checkpoint migliori e la patience.

Resume

resume=True continua una run interrotta dal checkpoint caricato; resume="path/to/last.pt" continua invece da quel file.

Python
from libreyolo import LibreYOLO # Carica il checkpoint della run interrotta, poi chiedi di riprendere.model = LibreYOLO("runs/train/yolo9_exp/weights/last.pt")model.train(data="my-dataset.yaml", resume=True)
CLI
libreyolo train model=runs/train/yolo9_exp/weights/last.pt \  data=my-dataset.yaml resume=true

Resume ripristina gli argomenti di addestramento salvati della run, e un argomento passato esplicitamente ha la precedenza su quello salvato. Continua a scrivere nella directory di run del checkpoint. Ripristina i pesi addestrati, lo stato dell'optimizer, i pesi EMA e il conteggio degli aggiornamenti, il tracciamento della metrica migliore, la scala del GradScaler e gli stati random di PyTorch, CUDA e NumPy. Riparte dall'epoca del checkpoint più uno e manda avanti lo schedule fino a quella posizione.

Ci sono tre cose che non fa. resume=True non si può combinare con pretrained, e provarci solleva un errore. I pesi pubblicati e una run che ha già raggiunto le sue epochs non hanno nulla da riprendere, e sollevano un ValueError che lo dice. E quando la chiave della metrica migliore del checkpoint è diversa da quella della run corrente, il tracciamento della metrica migliore si azzera con un warning invece di confrontare valori che non significano la stessa cosa.

Ricette in un file

cfg= carica una mappatura YAML di nomi di campo di TrainConfig e la fonde sotto gli argomenti keyword espliciti, quindi un kwarg vince sempre sul file.

Python
from libreyolo import LibreYOLO # Le chiavi nello yaml sono nomi di campo di TrainConfig. I kwarg espliciti vincono.model = LibreYOLO("LibreYOLO9s.pt")model.train(data="my-dataset.yaml", cfg="my-recipe.yaml", epochs=50)

size e num_classes vengono rimossi dal file, perché l'istanza del modello li possiede già. Non c'è un flag --cfg sulla CLI; il percorso del file è un argomento Python.

Selezione delle classi e ponderazione della loss

Per il rilevamento YOLO9, RF-DETR, EdgeCrafter, RT-DETR, D-FINE, DEIM, TinyFormer e YOLO-NAS, classes=None mantiene tutte le classi del dataset; una lista filtra la supervisione conservando gli ID originali, nc e names. single_cls=False può essere attivato per mappare le etichette mantenute sulla classe 0, chiamata object. Ripresa e validazione ereditano le impostazioni salvate. L'addestramento OBB del modello rifiuta single_cls.

ResNet, ConvNeXt, ConvNeXt V2, MobileNetV4, EfficientNetV2 e DINOv2 supportano cls_pw=0.0: i valori in [0, 1] pesano ogni classe con l'inverso della frequenza elevato a quella potenza, normalizzato a media 1. class_weights=False, se attivato, seleziona la ponderazione alternativa N / (C * n_c). Non è combinabile con cls_pw positivo; la ripresa richiede impostazioni di ponderazione corrispondenti.

plot_samples=8 imposta il numero massimo di immagini nel grafico dei campioni di validazione. Usa 0 per nessuna o -1 per tutte; non riduce le immagini valutate.

Verificato con LibreYOLO v1.6.0.