Ultralytics YOLO27: Iscriviti alla lista d'attesa.
Get Started

Come ottimizzare YOLO su un dataset personalizzato#

L'ottimizzazione fine adatta un modello pretrained al riconoscimento di nuove classi, partendo da pesi appresi anziché da un'inizializzazione casuale. Invece di addestrare il modello da zero per centinaia di epoche, l'ottimizzazione fine sfrutta le caratteristiche pretrained di COCO e converge sui dati personalizzati in una frazione del tempo.

Questa guida illustra l'ottimizzazione fine di YOLO26 su dataset personalizzati, dall'uso di base a tecniche avanzate come il congelamento dei layer e l'addestramento in due fasi.

Ottimizzazione fine o addestramento da zero#

Un modello pretrained ha già appreso caratteristiche visive generali — rilevamento dei bordi, riconoscimento delle texture e comprensione delle forme — da milioni di immagini. Il transfer learning tramite ottimizzazione fine riutilizza queste conoscenze e insegna al modello soltanto l'aspetto delle nuove classi, consentendo una convergenza più rapida e richiedendo meno dati. L'addestramento da zero elimina tutto questo e costringe il modello ad apprendere ogni aspetto partendo 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 che definiscono solo l'architettura differiscono dai checkpoint.

Ottimizzazione fineAddestramento da zero
Pesi inizialiPretrained su COCO (80 classi)Inizializzazione casuale
ComandoYOLO("yolo26n.pt")YOLO("yolo26n.yaml")
ConvergenzaPiù rapida: il backbone è già addestratoPiù lenta: tutti i layer apprendono da zero
Requisiti dei datiInferiori: le caratteristiche pretrained compensano la minore quantità di datiSuperiori: il modello deve apprendere tutte le caratteristiche solo dal dataset
Quando usarlaClassi personalizzate con immagini naturaliDomini fondamentalmente diversi da COCO (medicina, satellite, radar)
L'ottimizzazione fine non richiede codice aggiuntivo

Quando un file .pt viene caricato con YOLO("yolo26n.pt"), i pesi preaddestrati vengono memorizzati nel modello. La chiamata a .train(data="custom.yaml") trasferisce automaticamente tutti i pesi compatibili alla nuova architettura del modello, reinizializza i layer non corrispondenti (come il layer di classificazione finale quando il numero di classi è diverso) e avvia l'addestramento. Non è necessario caricare manualmente i pesi, manipolare i layer o scrivere codice personalizzato per il transfer learning.

Come funziona il trasferimento dei pesi pretrained#

Quando si ottimizza un modello pretrained 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 forme:

  1. Il backbone e il neck vengono trasferiti completamente: questi layer estraggono caratteristiche visive generali e le loro forme non dipendono dal numero di classi.
  2. La head di rilevamento viene reinizializzata parzialmente - solo la convoluzione finale di ciascun ramo di classificazione (cv3, one2one_cv3) ha una forma legata al numero di classi (80 contro 5); i layer nascosti del ramo vengono trasferiti quando entrambi i modelli condividono una scala. Le righe compatibili i cui nomi delle classi corrispondono vengono rimappate prima di inizializzare quelle non corrispondenti. I layer di regressione delle box (cv2, one2one_cv2) nella head hanno forme fisse indipendentemente dal numero di classi, quindi vengono trasferiti normalmente.
  3. La stragrande maggioranza dei pesi viene trasferita quando si cambia il numero di classi. Ad esempio, il fine-tuning di YOLO26n da COCO (80 classi) a un dataset con 5 classi trasferisce 696 dei 708 tensori dei pesi, oltre alle righe di classificazione compatibili abbinate in base al nome.

Per i dataset con lo stesso numero di classi del modello pretrained (ad esempio, ottimizzando pesi pretrained su COCO su un altro dataset di 80 classi), viene trasferito il 100% dei pesi, inclusa la testa di rilevamento.

Trasferire classi con nomi alternativi#

Ultralytics trasferisce le righe corrispondenti della testa di classificazione tra dataset in base al nome della classe, ignorando maiuscole, minuscole e spazi iniziali o finali. Se classi equivalenti hanno nomi diversi, rinomina in memoria le classi del checkpoint sorgente prima di caricarlo. In questo modo si preservano i pesi di classificazione pretrained per i concetti condivisi, che altrimenti verrebbero considerati senza corrispondenza e inizializzati casualmente.

Questo esempio di passaggio da Objects365 v2 a COCO rinomina le classi sorgente nel checkpoint caricato; train() le passa quindi come pesi pretrained:

from ultralytics import YOLO

# # Nome della classe sorgente Objects365 v2 (in minuscolo) -> nome della classe di destinazione COCO
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 Objects365 sono in formato Titolo, quindi confrontali 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 disabilitarlo.

Esempio di ottimizzazione fine di base#

Esempio
from ultralytics import YOLO

model = YOLO("yolo26n.pt")  # carica il modello preaddestrato
model.train(data="custom.yaml", epochs=50, imgsz=640)

Scegliere la dimensione 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. Iniziare con un modello più piccolo (YOLO26n o YOLO26s) e aumentare le dimensioni solo se le metriche di validazione raggiungono un plateau è un approccio pratico. La dimensione ottimale del modello dipende dalla complessità dell'attività, dal numero di classi, dalla diversità del dataset e dall'hardware disponibile per la distribuzione. Consulta la pagina completa del modello YOLO26 per le dimensioni disponibili e i benchmark delle prestazioni.

Scelta dell'ottimizzatore e del tasso di apprendimento#

L'impostazione predefinita optimizer=auto seleziona l'ottimizzatore e il tasso di apprendimento in base al numero totale di iterazioni di addestramento:

  • 10.000 iterazioni o meno (dataset piccoli o poche epoche): AdamW con un tasso di apprendimento 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 ottimizzazione fine, l'impostazione predefinita funziona bene senza regolazioni manuali. Valuta di impostare esplicitamente l'ottimizzatore nei seguenti casi:

  • Addestramento instabile (la perdita aumenta improvvisamente o diverge): prova optimizer=AdamW, lr0=0.001 per una convergenza più stabile
  • Ottimizzazione fine di un modello grande su un dataset piccolo: un ottimizzatore esplicito con un tasso di apprendimento più basso, come optimizer=AdamW, lr0=0.001, può aiutare a preservare le caratteristiche pretrained
L'ottimizzatore automatico ignora lr0 manuale

Quando è impostato optimizer=auto, il valore lr0 viene ignorato. Per controllare manualmente il tasso di apprendimento, imposta esplicitamente l'ottimizzatore: optimizer=SGD, lr0=0.005.

Congelamento dei layer#

Il congelamento impedisce a determinati layer di aggiornarsi durante l'addestramento. Questo 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 gran 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 nel dettaglio rami specifici all'interno di un layer (in questo caso, entrambi i rami di regressione dei box della testa di rilevamento).

Esempio
from ultralytics import YOLO

model = YOLO("yolo26n.pt")
model.train(data="custom.yaml", epochs=50, freeze=10)

La profondità di congelamento ideale dipende da quanto il dominio di destinazione è simile ai dati di preaddestramento e dalla quantità di dati di addestramento disponibile:

ScenarioConsiglioMotivazione
Dataset ampio, dominio similefreeze=None (predefinito)Dati sufficienti per adattare tutti i layer senza overfitting
Dataset piccolo, dominio similefreeze=10Mantiene le feature del backbone e riduce i parametri addestrabili
Dataset molto piccolofreeze=23Si addestra solo la testa di rilevamento, riducendo al minimo il rischio di overfitting
Dominio molto diverso da COCOfreeze=NoneLe feature del backbone potrebbero non essere trasferibili in modo efficace e potrebbero richiedere un nuovo addestramento

La profondità di congelamento può anche essere trattata come un iperparametro: provare alcuni valori (0, 5, 10) e confrontare mAP di validazione è un modo pratico per trovare l'impostazione migliore per un dataset specifico.

Iperparametri chiave per il fine-tuning#

In genere, il fine-tuning richiede meno modifiche agli iperparametri rispetto all'addestramento da zero. I parametri più importanti sono:

  • epochs: il fine-tuning converge più rapidamente dell'addestramento da zero. Inizia con un valore moderato e usa patience per interrompere in anticipo quando le metriche di validazione si stabilizzano.
  • patience: il valore predefinito di 100 è pensato per addestramenti lunghi. Ridurlo a 10-20 evita di sprecare tempo in esecuzioni già convergenti.
  • warmup_epochs: il warmup porta gradualmente il learning rate al valore previsto dal programma durante le prime epoche, così i batch iniziali hanno meno probabilità di alterare le feature preaddestrate. Mantienilo diverso da zero durante il fine-tuning, ma non è necessario usare il valore predefinito 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 circa un'epoca per ogni dimensione del modello.

Per l'elenco completo dei parametri di addestramento, consulta il riferimento alla configurazione di addestramento. Per controllare comportamenti non esposti 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 neck e head, consentendo ai layer di rilevamento di adattarsi alle nuove classi senza alterare le feature preaddestrate. Nella seconda fase, si scongelano tutti i layer e si addestra il modello completo con un learning rate inferiore, per perfezionare il backbone in funzione del dominio di destinazione.

Questo approccio è particolarmente utile quando il dominio di destinazione è molto diverso da COCO (immagini mediche, immagini aeree, microscopia), poiché il backbone potrebbe richiedere un adattamento, mentre addestrare tutto in una volta può causare instabilità. Per scongelare automaticamente i layer con un approccio basato su callback, consulta Congelare e scongelare il backbone.

Fine-tuning in due fasi
from ultralytics import YOLO

# Fase 1: congela il backbone, addestra head e neck
model = YOLO("yolo26n.pt")
model.train(data="custom.yaml", epochs=20, freeze=10, name="stage1", exist_ok=True)

# Fase 2: scongela tutto, esegui il fine-tuning con un lr inferiore
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: addestrare con pochissimi campioni è la causa più comune; il modello non può apprendere né generalizzare con così pochi dati. Prima di indagare altre cause, assicurati di avere abbastanza esempi diversificati per ogni classe.

  • Controlla i percorsi del dataset: i percorsi delle immagini non validi generano un errore del dataset. I singoli file di etichette mancanti o vuoti vengono trattati come immagini di sfondo e segnalati durante la scansione; una suddivisione di addestramento senza etichette genera 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.1 durante l'inferenza.

  • Verifica il numero di classi: assicurati che nc in data.yaml corrisponda al numero effettivo di classi nei file di etichette.

La mAP di validazione si stabilizza presto#

  • Aggiungi altri dati: il fine-tuning trae notevole beneficio da ulteriori dati di addestramento, soprattutto da esempi diversificati con angolazioni, illuminazione e sfondi vari.
  • Controlla il bilanciamento delle classi: le classi sottorappresentate avranno AP bassi. Aggiungi altri esempi oppure ottimizza cls_pw sul set di validazione.
  • Riduci l'augmentation: con dataset molto piccoli, un'augmentation intensa può essere più dannosa che utile. Prova mosaic=0.5 oppure mosaic=0.0.
  • Aumenta la risoluzione: per i dataset con oggetti piccoli, prova imgsz=1280 per preservare i dettagli.

Le prestazioni sulle classi originali peggiorano dopo il fine-tuning#

Questo fenomeno è noto come oblio catastrofico: il modello perde le conoscenze apprese in precedenza quando viene sottoposto al fine-tuning esclusivamente su nuovi dati. L'oblio è per lo più inevitabile se non si includono immagini del dataset originale insieme ai nuovi dati. Per limitarlo:

  • Unisci i dataset: durante il fine-tuning, includi esempi delle classi originali insieme a quelli delle nuove classi. È l'unico metodo affidabile per evitare l'oblio.
  • Congela backbone e neck: congelare sia il backbone sia il neck, in modo da addestrare solo la testa di rilevamento, è utile per brevi sessioni di fine-tuning con un learning rate molto basso.
  • Riduci il numero di epoche: più a lungo il modello viene addestrato esclusivamente sui nuovi dati, più aumenta l'oblio.

Domande frequenti#

  • Non esiste un minimo fisso: i risultati dipendono dalla complessità dell'attività, dal numero di classi e dalla somiglianza del dominio con COCO. Le immagini più diversificate (con illuminazione, angolazioni e sfondi vari) contano più della quantità grezza. Inizia con i dati che hai e aumentali se le metriche di validazione non sono sufficienti.

  • Carica un file .pt preaddestrato e chiama .train() indicando il percorso di un data.yaml personalizzato. Ultralytics gestisce automaticamente il trasferimento dei pesi, la reinizializzazione del layer di classificazione e la selezione dell'ottimizzatore. Per l'esempio di codice completo, consulta la sezione Fine-tuning di base.

  • Le cause più comuni sono percorsi delle immagini non validi, file di etichette mancanti o vuoti, una mancata corrispondenza tra nc nel file YAML e i file di etichette effettivi, oppure una soglia di confidenza troppo alta. Consulta Problemi comuni per una checklist completa di risoluzione dei problemi.

  • Dipende dalle dimensioni del dataset e dalla somiglianza del dominio. Per dataset piccoli con un dominio simile a COCO, congelare il backbone (freeze=10) previene l'overfitting. Per domini molto diversi da COCO, lasciare scongelati tutti i layer (freeze=None) consente al backbone di adattarsi. Consulta Congelamento dei layer per consigli dettagliati.

  • Includi nei dati di addestramento esempi delle classi originali insieme a quelli delle nuove classi. Se non è possibile, congelare più layer (freeze=10 o un valore superiore) e usare un learning rate inferiore aiuta a preservare le conoscenze preaddestrate. Per maggiori dettagli, consulta Le prestazioni sulle classi originali peggiorano.

Commenti