Come eseguire il fine-tuning di YOLO su un dataset personalizzato#
Il fine-tuning adatta un modello preaddestrato al riconoscimento di nuove classi partendo da pesi appresi anziché da un’inizializzazione casuale. Invece di addestrare un modello da zero per centinaia di epoche, il fine-tuning sfrutta le caratteristiche preaddestrate di COCO e converge sui dati personalizzati in una frazione del tempo.
Questa guida illustra il fine-tuning di YOLO26 su dataset personalizzati, dall’utilizzo di base a tecniche avanzate come il congelamento dei layer e l’addestramento in due fasi.
Fine-tuning vs addestramento da zero#
Un modello preaddestrato ha già appreso caratteristiche visive generali — rilevamento dei bordi, riconoscimento delle texture, comprensione delle forme — da milioni di immagini. Il transfer learning tramite fine-tuning riutilizza queste conoscenze e insegna al modello solo l’aspetto delle nuove classi, consentendogli così di convergere più rapidamente e richiedendo meno dati. L’addestramento da zero scarta tutto ciò e costringe il modello ad apprendere ogni cosa a partire dai pattern a livello di pixel, richiedendo molte più risorse. Consulta la Guida alla configurazione YAML del modello per scoprire in che modo i file .yaml contenenti solo l’architettura differiscono dai checkpoint.
| Fine-tuning | Addestramento da zero | |
|---|---|---|
| Pesi iniziali | Preaddestrato su COCO (80 classi) | Inizializzazione casuale |
| Comando | YOLO("yolo26n.pt") | YOLO("yolo26n.yaml") |
| Convergenza | Più rapida: il backbone è già addestrato | Più lenta: tutti i layer apprendono da zero |
| Requisiti dei dati | Minori: le caratteristiche preaddestrate compensano la quantità ridotta di dati | Maggiori: il modello deve apprendere tutte le caratteristiche usando solo il dataset |
| Quando usarlo | Classi personalizzate con immagini naturali | Domini fondamentalmente diversi da COCO (medicina, satellite, radar) |
Quando carichi un file .pt con YOLO("yolo26n.pt"), i pesi preaddestrati vengono memorizzati nel modello. In seguito, chiamando .train(data="custom.yaml"), tutti i pesi compatibili vengono trasferiti automaticamente alla nuova architettura del modello, i layer non corrispondenti vengono reinizializzati (ad esempio la testa di rilevamento se il numero di classi è diverso) e l’addestramento ha inizio. Non è necessario caricare manualmente i pesi, modificare i layer o scrivere codice personalizzato per il transfer learning.
Come funziona il trasferimento dei pesi preaddestrati#
Quando esegui il fine-tuning di un modello preaddestrato su un dataset con un numero diverso di classi (ad esempio, passando dalle 80 classi di COCO a 5 classi personalizzate), Ultralytics esegue il trasferimento dei pesi tenendo conto delle dimensioni:
- Trasferimento completo del backbone e del neck: questi layer estraggono caratteristiche visive generali e le loro dimensioni non dipendono dal numero di classi.
- Reinizializzazione parziale della testa di rilevamento: i layer di output della classificazione (
cv3,one2one_cv3) hanno dimensioni legate al numero di classi (80 vs 5). Prima di inizializzare le righe non corrispondenti, le righe compatibili con nomi di classe corrispondenti vengono rimappate. I layer di regressione dei riquadri (cv2,one2one_cv2) nella testa hanno dimensioni fisse, indipendentemente dal numero di classi, quindi vengono trasferiti normalmente. - La stragrande maggioranza dei pesi viene trasferita quando si modifica il numero di classi. Ad esempio, eseguendo il fine-tuning di YOLO26n da COCO (80 classi) su un dataset con 5 classi, vengono trasferiti 606 dei 708 tensori dei pesi, oltre alle righe di classificazione compatibili abbinate per nome.
Per i dataset con lo stesso numero di classi del modello preaddestrato (ad esempio, se esegui il fine-tuning di pesi preaddestrati su COCO usando un altro dataset con 80 classi), viene trasferito il 100% dei pesi, inclusa la testa di rilevamento.
Trasferire le classi con alias nei nomi#
Ultralytics trasferisce le righe corrispondenti della testa di classificazione tra i dataset in base al nome della classe, ignorando maiuscole, minuscole e spazi circostanti. Quando classi equivalenti hanno nomi diversi, rinomina in memoria le classi del checkpoint di origine prima di caricarlo. In questo modo, i pesi di classificazione preaddestrati vengono mantenuti per i concetti condivisi che altrimenti verrebbero considerati non corrispondenti e inizializzati casualmente.
Questo esempio di passaggio da Objects365 v2 a COCO rinomina le classi di origine nel checkpoint caricato; train() le trasferisce quindi come pesi preaddestrati:
from ultralytics import YOLO
# Nome della classe Objects365 v2 (in minuscolo) -> nome della classe COCO di destinazione
ALIASES = {
"wild bird": "bird",
"handbag/satchel": "handbag",
"luggage": "suitcase",
"bowl/basin": "bowl",
"orange/tangerine": "orange",
"monitor/tv": "tv",
"stuffed toy": "teddy bear",
"hair dryer": "hair drier",
}
model = YOLO("path/to/yolo26s-objects365.pt")
# I nomi delle classi di Objects365 usano le maiuscole iniziali, quindi il confronto avviene sul nome in minuscolo
model.model.names = {i: ALIASES.get(name.lower(), name) for i, name in model.model.names.items()}
model.train(data="coco.yaml", epochs=100, imgsz=640)L’impostazione cls_remap abilita per impostazione predefinita questo trasferimento basato sui nomi. Durante l’addestramento viene stampato Remapped N/M cls head rows from pretrained weights by class name quando vengono copiate righe compatibili; imposta cls_remap=False per disabilitare questa funzione.
Esempio di fine-tuning di base#
from ultralytics import YOLO
model = YOLO("yolo26n.pt") # carica il modello preaddestrato
model.train(data="custom.yaml", epochs=50, imgsz=640)Scegliere le dimensioni del modello#
I modelli più grandi hanno una capacità maggiore, ma anche più parametri da aggiornare, il che può aumentare il rischio di overfitting quando i dati di addestramento sono limitati. Un approccio pratico consiste nel partire da un modello più piccolo (YOLO26n o YOLO26s) e aumentare le dimensioni solo se le metriche di validazione si appiattiscono. Le dimensioni ottimali del modello dipendono dalla complessità dell’attività, dal numero di classi, dalla varietà del dataset e dall’hardware disponibile per la distribuzione. Consulta la pagina completa dei modelli YOLO26 per scoprire le dimensioni disponibili e i benchmark delle prestazioni.
Scelta dell’ottimizzatore e del learning rate#
L’impostazione predefinita optimizer=auto seleziona l’ottimizzatore e il learning rate in base al numero totale di iterazioni di addestramento:
- 10.000 iterazioni o meno (dataset piccoli o poche epoche): AdamW con un learning rate basso, calcolato automaticamente
- Più di 10.000 iterazioni (dataset grandi): MuSGD (un ottimizzatore ibrido Muon+SGD) con lr=0.01
Per la maggior parte delle attività di fine-tuning, l’impostazione predefinita funziona bene senza regolazioni manuali. Valuta di impostare esplicitamente l’ottimizzatore quando:
- L’addestramento è instabile (la loss presenta picchi o diverge): prova
optimizer=AdamW, lr0=0.001per una convergenza più stabile - Esegui il fine-tuning di un modello grande su un dataset piccolo: un ottimizzatore esplicito con un learning rate più basso, come
optimizer=AdamW, lr0=0.001, può aiutare a preservare le caratteristiche preaddestrate
Quando usi optimizer=auto, i valori lr0 e momentum vengono ignorati. Per controllare manualmente il learning rate, imposta esplicitamente l’ottimizzatore: optimizer=SGD, lr0=0.005.
Congelamento dei layer#
Il congelamento impedisce l’aggiornamento di layer specifici durante l’addestramento. Questa tecnica accelera l’addestramento e riduce l’overfitting quando il dataset è piccolo rispetto alla capacità del modello.
Il parametro freeze accetta un intero o un elenco. Un intero freeze=10 congela i primi 10 layer (indici 0-9), che comprendono la maggior parte del backbone di YOLO26. Il backbone si estende dai layer 0 a 10, quindi freeze=10 lascia addestrabile il blocco C2PSA finale (layer 10); usa freeze=11 per congelare l’intero backbone. Un elenco può contenere indici di layer, come freeze=[0, 3, 5], per congelare parzialmente il backbone, oppure stringhe con i nomi dei moduli, come freeze=["23.cv2", "23.one2one_cv2"], per controllare in modo dettagliato rami specifici all’interno di un layer (in questo caso, entrambi i rami di regressione dei riquadri della testa di rilevamento).
from ultralytics import YOLO
model = YOLO("yolo26n.pt")
model.train(data="custom.yaml", epochs=50, freeze=10)Il livello di congelamento più adatto dipende dalla somiglianza tra il dominio di destinazione e i dati preaddestrati, oltre che dalla quantità di dati di addestramento disponibili:
| Scenario | Consiglio | Motivazione |
|---|---|---|
| Dataset grande, dominio simile | freeze=None (predefinito) | Dati sufficienti per adattare tutti i layer senza overfitting |
| Dataset piccolo, dominio simile | freeze=10 | Preserva le caratteristiche del backbone e riduce i parametri addestrabili |
| Dataset molto piccolo | freeze=23 | Si addestra solo la testa di rilevamento, riducendo al minimo il rischio di overfitting |
| Dominio molto diverso da COCO | freeze=None | Le caratteristiche del backbone potrebbero non trasferirsi bene e richiedere un nuovo addestramento |
Il livello di congelamento può anche essere considerato un iperparametro: provare alcuni valori (0, 5, 10) e confrontare il mAP di validazione è un metodo pratico per trovare l’impostazione migliore per un dataset specifico.
Iperparametri chiave per il fine-tuning#
In genere, il fine-tuning richiede meno regolazioni degli iperparametri rispetto all’addestramento da zero. I parametri più importanti sono:
epochs: il fine-tuning converge più rapidamente rispetto all’addestramento da zero. Inizia con un valore moderato e usapatienceper interrompere l’addestramento quando le metriche di validazione si appiattiscono.patience: il valore predefinito di 100 è pensato per sessioni di addestramento lunghe. Riducendolo a 10-20 eviti di sprecare tempo con sessioni già giunte a convergenza.warmup_epochs: il warmup porta gradualmente il learning rate al valore previsto dalla pianificazione nelle prime epoche, riducendo la probabilità che i batch iniziali alterino le caratteristiche preaddestrate. Mantienilo diverso da zero durante il fine-tuning, ma non è necessario usare il valore predefinito completo di 3 epoche: la ricerca evolutiva alla base del fine-tuning ufficiale di YOLO26 su COCO — una continuazione di più epoche a partire dai pesi di Objects365 — ha stabilito un valore di circa un’epoca per ogni dimensione del modello.
Per l’elenco completo dei parametri di addestramento, consulta il riferimento alla configurazione di addestramento. Se hai bisogno di funzionalità non offerte dai parametri — learning rate per layer, gradient clipping o metriche di validazione personalizzate — crea una sottoclasse del trainer.
Fine-tuning in due fasi#
Il fine-tuning in due fasi suddivide l’addestramento in due fasi. Nella prima fase, il backbone viene congelato e si addestrano solo il neck e la testa, consentendo ai layer di rilevamento di adattarsi alle nuove classi senza compromettere le caratteristiche preaddestrate. Nella seconda fase, tutti i layer vengono scongelati e l’intero modello viene addestrato con un learning rate inferiore, così da perfezionare il backbone per il dominio di destinazione.
Questo approccio è particolarmente utile quando il dominio di destinazione differisce notevolmente da COCO (immagini mediche, immagini aeree, microscopia), situazione in cui il backbone potrebbe aver bisogno di essere adattato, ma addestrare tutto contemporaneamente causa instabilità. Per lo scongelamento automatico tramite callback, consulta la guida Congelamento e scongelamento del backbone.
from ultralytics import YOLO
# Fase 1: congela il backbone e addestra la testa e il neck
model = YOLO("yolo26n.pt")
model.train(data="custom.yaml", epochs=20, freeze=10, name="stage1", exist_ok=True)
# Fase 2: scongela tutto ed esegui il fine-tuning con un lr più basso
model = YOLO("runs/detect/stage1/weights/best.pt")
model.train(data="custom.yaml", epochs=30, optimizer="AdamW", lr0=0.001, name="stage2", exist_ok=True)Problemi comuni#
Il modello non produce predizioni#
-
Dati di addestramento insufficienti: l’addestramento con pochissimi campioni è la causa più comune; il modello non riesce ad apprendere o generalizzare con così pochi dati. Prima di esaminare altre cause, assicurati di avere un numero sufficiente di esempi diversificati per ogni classe.
-
Controlla i percorsi del dataset: i percorsi delle immagini non validi generano un errore del dataset. I singoli file delle etichette mancanti o vuoti vengono trattati come immagini di sfondo e segnalati durante l’analisi; se lo split di addestramento non contiene etichette, viene generato un errore. Convalida il dataset prima dell’addestramento:
yolo detect val model=yolo26n.pt data=custom.yaml -
Abbassa la soglia di confidenza: se le predizioni sono presenti ma vengono filtrate, prova
conf=0.1durante l’inferenza. -
Verifica il numero di classi: assicurati che
ncindata.yamlcorrisponda al numero effettivo di classi nei file delle etichette.
Il mAP di validazione si appiattisce precocemente#
- Aggiungi altri dati: il fine-tuning trae notevoli vantaggi da ulteriori dati di addestramento, soprattutto da esempi diversificati con angolazioni, illuminazione e sfondi vari.
- Controlla il bilanciamento delle classi: le classi sottorappresentate avranno un AP basso. Aggiungi altri esempi oppure regola
cls_pwsul set di validazione. - Riduci l’aumento dei dati: con dataset molto piccoli, un aumento dei dati eccessivo può essere più dannoso che utile. Prova
mosaic=0.5omosaic=0.0. - Aumenta la risoluzione: se il dataset contiene oggetti piccoli, prova
imgsz=1280per preservare i dettagli.
Le prestazioni sulle classi originali peggiorano dopo il fine-tuning#
Questo fenomeno è noto come oblio catastrofico: durante il fine-tuning esclusivo sui nuovi dati, il modello perde le conoscenze apprese in precedenza. Senza includere le immagini del dataset originale insieme ai nuovi dati, l’oblio è perlopiù inevitabile. Per ridurlo:
- Unisci i dataset: durante il fine-tuning, includi esempi delle classi originali insieme a quelli delle nuove classi. È l’unico metodo affidabile per prevenire l’oblio.
- Congela il backbone e il neck: congelare sia il backbone sia il neck, in modo che si addestri solo la testa di rilevamento, è utile per sessioni di fine-tuning brevi con un learning rate molto basso.
- Riduci il numero di epoche: più a lungo il modello si addestra esclusivamente sui nuovi dati, più aumenta l’oblio.
Domande frequenti#
Non esiste un minimo prestabilito: i risultati dipendono dalla complessità dell’attività, dal numero di classi e dalla somiglianza del dominio con COCO. La varietà delle immagini (illuminazione, angolazioni e sfondi diversi) conta più della quantità assoluta. Inizia con i dati disponibili e aumenta la quantità se le metriche di validazione non sono soddisfacenti.
Carica un file
.ptpreaddestrato e chiama.train()specificando il percorso di undata.yamlpersonalizzato. Ultralytics gestisce automaticamente il trasferimento dei pesi, la reinizializzazione della testa di rilevamento e la selezione dell’ottimizzatore. Consulta la sezione Fine-tuning di base per l’esempio di codice completo.Le cause più comuni sono percorsi delle immagini non validi, file delle etichette mancanti o vuoti, una mancata corrispondenza tra
ncnel file YAML e i file effettivi delle etichette, oppure una soglia di confidenza troppo alta. Consulta Problemi comuni per l’elenco completo delle verifiche per la risoluzione dei problemi.Dipende dalle dimensioni del dataset e dalla somiglianza tra i domini. Per i dataset piccoli con un dominio simile a COCO, congelare il backbone (
freeze=10) evita l'overfitting. Per i domini molto diversi da COCO, lasciare tutti i layer non congelati (freeze=None) consente al backbone di adattarsi. Consulta Congelamento dei layer per consigli dettagliati.Includi nel set di dati di addestramento esempi delle classi originali insieme alle nuove classi. Se non è possibile, congelare più layer (
freeze=10o un numero maggiore) e usare un tasso di apprendimento più basso aiuta a preservare le conoscenze preaddestrate. Consulta Le prestazioni peggiorano sulle classi originali per ulteriori dettagli.