Guida alla configurazione YAML del modello
Il file di configurazione YAML del modello funge da progetto architettonico per le reti neurali Ultralytics. Definisce come si collegano i livelli, quali parametri utilizza ciascun modulo e come l'intera rete si adatta alle diverse dimensioni del modello.
Struttura della configurazione
I file YAML dei modelli sono organizzati in tre sezioni principali che lavorano insieme per definire l'architettura.
Sezione dei parametri
La sezione parameters specifica le caratteristiche globali del modello e il comportamento di scalabilità:
# Parameters
nc: 80 # number of classes
scales: # compound scaling constants [depth, width, max_channels]
n: [0.50, 0.25, 1024] # nano: shallow layers, narrow channels
s: [0.50, 0.50, 1024] # small: shallow depth, standard width
m: [0.50, 1.00, 512] # medium: moderate depth, full width
l: [1.00, 1.00, 512] # large: full depth and width
x: [1.00, 1.50, 512] # extra-large: maximum performance
kpt_shape: [17, 3] # pose models onlyncimposta il numero di classi che il modello prevede.scalesdefinisce i fattori di scala composti che regolano la profondità, la larghezza e i canali massimi del modello per produrre varianti di diverse dimensioni (da nano a extra-large).kpt_shapesi applica ai modelli di posa. Può essere[N, 2]per i keypoint(x, y)o[N, 3]per(x, y, visibility).
Il parametro scales ti permette di generare molteplici dimensioni del modello da un unico YAML di base. Ad esempio, quando carichi yolo26n.yaml, Ultralytics legge il yolo26.yaml di base e applica i fattori di scala n (depth=0.50, width=0.25) per costruire la variante nano.
Se il tuo dataset specifica un nc o un kpt_shape diverso, Ultralytics sovrascriverà automaticamente la configurazione del modello in fase di runtime per corrispondere allo YAML del dataset.
Architettura di Backbone e Head
L'architettura del modello consiste in sezioni di backbone (estrazione delle caratteristiche) e head (specifiche del compito):
backbone:
# [from, repeats, module, args]
- [-1, 1, Conv, [64, 3, 2]] # 0: Initial convolution
- [-1, 1, Conv, [128, 3, 2]] # 1: Downsample
- [-1, 3, C2f, [128, True]] # 2: Feature processing
head:
- [-1, 1, nn.Upsample, [None, 2, nearest]] # 6: Upsample
- [[-1, 2], 1, Concat, [1]] # 7: Skip connection
- [-1, 3, C2f, [256]] # 8: Process features
- [[8], 1, Detect, [nc]] # 9: Detection layerFormato di specifica del livello
Ogni livello segue lo schema coerente: [from, repeats, module, args]
| Componente | Scopo | Esempi |
|---|---|---|
| from | Connessioni di input | -1 (precedente), 6 (livello 6), [4, 6, 8] (input multipli) |
| repeats | Numero di ripetizioni | 1 (singolo), 3 (ripeti 3 volte) |
| module | Tipo di modulo | Conv, C2f, TorchVision, Detect |
| args | Argomenti del modulo | [64, 3, 2] (canali, kernel, stride) |
Schemi di connessione
Il campo from crea schemi di flusso dati flessibili in tutta la tua rete:
- [-1, 1, Conv, [64, 3, 2]] # Takes input from previous layerI livelli sono indicizzati a partire da 0. Gli indici negativi fanno riferimento ai livelli precedenti (-1 = livello precedente), mentre gli indici positivi fanno riferimento a livelli specifici in base alla loro posizione.
Ripetizione del modulo
Il parametro repeats crea sezioni di rete più profonde:
- [-1, 3, C2f, [128, True]] # Creates 3 consecutive C2f blocks
- [-1, 1, Conv, [64, 3, 2]] # Single convolution layerIl conteggio effettivo delle ripetizioni viene moltiplicato per il fattore di scala della profondità dalla configurazione della dimensione del tuo modello.
Moduli disponibili
I moduli sono organizzati per funzionalità e definiti nella directory dei moduli Ultralytics. Le seguenti tabelle mostrano i moduli utilizzati comunemente per categoria, con molti altri disponibili nel codice sorgente:
Operazioni di base
| Modulo | Scopo | Sorgente | Argomenti |
|---|---|---|---|
Conv | Convoluzione + BatchNorm + Attivazione | conv.py | [out_ch, kernel, stride, pad, groups] |
nn.Upsample | Upsampling spaziale | PyTorch | [size, scale_factor, mode] |
nn.Identity | Operazione pass-through | PyTorch | [] |
Blocchi compositi
| Modulo | Scopo | Sorgente | Argomenti |
|---|---|---|---|
C2f | Bottleneck CSP con 2 convoluzioni | block.py | [out_ch, shortcut, expansion] |
SPPF | Spatial Pyramid Pooling (veloce) | block.py | [out_ch, kernel_size] |
Concat | Concatenazione per canali | conv.py | [dimension] |
Moduli specializzati
| Modulo | Scopo | Sorgente | Argomenti |
|---|---|---|---|
TorchVision | Carica qualsiasi modello torchvision | block.py | [out_ch, model_name, weights, unwrap, truncate, split] |
Index | Estrai un tensore specifico da una lista | block.py | [out_ch, index] |
Detect | Head di rilevamento YOLO | head.py | [nc, anchors, ch] |
Questo rappresenta un sottoinsieme dei moduli disponibili. Per l'elenco completo dei moduli e i loro parametri, esplora la directory dei moduli.
Funzionalità avanzate
Integrazione TorchVision
Il modulo TorchVision abilita l'integrazione fluida di qualsiasi modello TorchVision come backbone:
from ultralytics import YOLO
# Model with ConvNeXt backbone
model = YOLO("convnext_backbone.yaml")
results = model.train(data="coco8.yaml", epochs=100)Imposta l'ultimo parametro su True per ottenere mappe delle caratteristiche intermedie per il rilevamento multi-scala.
Modulo Index per la selezione delle caratteristiche
Quando utilizzi modelli che producono molteplici mappe delle caratteristiche, il modulo Index seleziona output specifici:
backbone:
- [-1, 1, TorchVision, [768, convnext_tiny, DEFAULT, True, 2, True]] # Multi-output
head:
- [0, 1, Index, [192, 4]] # Select 4th feature map (192 channels)
- [0, 1, Index, [384, 6]] # Select 6th feature map (384 channels)
- [0, 1, Index, [768, 8]] # Select 8th feature map (768 channels)
- [[1, 2, 3], 1, Detect, [nc]] # Multi-scale detectionSistema di risoluzione dei moduli
Capire come Ultralytics individua e importa i moduli è fondamentale per la personalizzazione:
Processo di ricerca dei moduli
Ultralytics utilizza un sistema a tre livelli in parse_model:
# Core resolution logic
m = getattr(torch.nn, m[3:]) if "nn." in m else getattr(torchvision.ops, m[4:]) if "ops." in m else globals()[m]- Moduli PyTorch: Nomi che iniziano con
'nn.'→ namespacetorch.nn - Operazioni TorchVision: Nomi che iniziano con
'ops.'→ namespacetorchvision.ops - Moduli Ultralytics: Tutti gli altri nomi → namespace globale tramite import
Catena di importazione dei moduli
I moduli standard diventano disponibili tramite le importazioni in tasks.py:
from ultralytics.nn.modules import ( # noqa: F401
SPPF,
C2f,
Conv,
Detect,
# ... many more modules
Index,
TorchVision,
)Integrazione di moduli personalizzati
Modifica del codice sorgente
Modificare il codice sorgente è il modo più versatile per integrare i tuoi moduli personalizzati, ma può essere complicato. Per definire e utilizzare un modulo personalizzato, segui questi passaggi:
-
Installa Ultralytics in modalità sviluppo utilizzando il metodo Git clone dalla guida di avvio rapido.
-
Definisci il tuo modulo in
ultralytics/nn/modules/block.py:class CustomBlock(nn.Module): """Custom block with Conv-BatchNorm-ReLU sequence.""" def __init__(self, c1, c2): """Initialize CustomBlock with input and output channels.""" super().__init__() self.layers = nn.Sequential(nn.Conv2d(c1, c2, 3, 1, 1), nn.BatchNorm2d(c2), nn.ReLU()) def forward(self, x): """Forward pass through the block.""" return self.layers(x) -
Esponi il tuo modulo a livello di pacchetto in
ultralytics/nn/modules/__init__.py:from .block import CustomBlock # noqa makes CustomBlock available as ultralytics.nn.modules.CustomBlock -
Aggiungi alle importazioni in
ultralytics/nn/tasks.py:from ultralytics.nn.modules import CustomBlock # noqa -
Gestisci argomenti speciali (se necessario) all'interno di
parse_model()inultralytics/nn/tasks.py:# Add this condition in the parse_model() function if m is CustomBlock: c1, c2 = ch[f], args[0] # input channels, output channels args = [c1, c2, *args[1:]] -
Utilizza il modulo nel tuo YAML del modello:
# custom_model.yaml nc: 1 backbone: - [-1, 1, CustomBlock, [64]] head: - [-1, 1, Classify, [nc]] -
Controlla i FLOPs per assicurarti che il forward pass funzioni:
from ultralytics import YOLO model = YOLO("custom_model.yaml", task="classify") model.info() # should print non-zero FLOPs if working
Configurazioni di esempio
Modello di rilevamento base
# Simple YOLO detection model
nc: 80
scales:
n: [0.33, 0.25, 1024]
backbone:
- [-1, 1, Conv, [64, 3, 2]] # 0-P1/2
- [-1, 1, Conv, [128, 3, 2]] # 1-P2/4
- [-1, 3, C2f, [128, True]] # 2
- [-1, 1, Conv, [256, 3, 2]] # 3-P3/8
- [-1, 6, C2f, [256, True]] # 4
- [-1, 1, SPPF, [256, 5]] # 5
head:
- [-1, 1, Conv, [256, 3, 1]] # 6
- [[6], 1, Detect, [nc]] # 7Modello Backbone TorchVision
# ConvNeXt backbone with YOLO head
nc: 80
backbone:
- [-1, 1, TorchVision, [768, convnext_tiny, DEFAULT, True, 2, True]]
head:
- [0, 1, Index, [192, 4]] # P3 features
- [0, 1, Index, [384, 6]] # P4 features
- [0, 1, Index, [768, 8]] # P5 features
- [[1, 2, 3], 1, Detect, [nc]] # Multi-scale detectionModello di classificazione
# Simple classification model
nc: 1000
backbone:
- [-1, 1, Conv, [64, 7, 2, 3]]
- [-1, 1, nn.MaxPool2d, [3, 2, 1]]
- [-1, 4, C2f, [64, True]]
- [-1, 1, Conv, [128, 3, 2]]
- [-1, 8, C2f, [128, True]]
- [-1, 1, nn.AdaptiveAvgPool2d, [1]]
head:
- [-1, 1, Classify, [nc]]Best practice
Suggerimenti per la progettazione dell'architettura
Inizia in modo semplice: inizia con architetture collaudate prima di personalizzare. Usa le configurazioni YOLO esistenti come modelli e modifica in modo incrementale invece di costruire da zero.
Testa in modo incrementale: convalida ogni modifica passo dopo passo. Aggiungi un modulo personalizzato alla volta e verifica che funzioni prima di procedere alla modifica successiva.
Monitora i canali: assicurati che le dimensioni dei canali corrispondano tra i livelli collegati. I canali di output (c2) di un livello devono corrispondere ai canali di input (c1) del livello successivo nella sequenza.
Usa le connessioni di salto (skip connections): sfrutta il riutilizzo delle feature con pattern [[-1, N], 1, Concat, [1]]. Queste connessioni aiutano il flusso del gradiente e consentono al modello di combinare feature da scale diverse.
Scala in modo appropriato: scegli le scale del modello in base ai tuoi vincoli computazionali. Usa nano (n) per dispositivi edge, small (s) per prestazioni bilanciate e scale maggiori (m, l, x) per la massima precisione.
Considerazioni sulle prestazioni
Profondità vs Larghezza: le reti profonde catturano feature gerarchiche complesse attraverso molteplici livelli di trasformazione, mentre le reti larghe elaborano più informazioni in parallelo a ogni livello. Bilanciale in base alla complessità del tuo compito.
Skip Connections: migliorano il flusso del gradiente durante l'addestramento e consentono il riutilizzo delle feature in tutta la rete. Sono particolarmente importanti nelle architetture più profonde per prevenire la scomparsa del gradiente.
Blocchi Bottleneck: riducono il costo computazionale mantenendo l'espressività del modello. Moduli come C2f utilizzano meno parametri rispetto alle convoluzioni standard pur preservando la capacità di apprendimento delle feature.
Feature multi-scala: essenziali per rilevare oggetti di dimensioni diverse nella stessa immagine. Usa pattern Feature Pyramid Network (FPN) con più teste di rilevamento a scale diverse.
Risoluzione dei problemi
Problemi comuni
| Problema | Causa | Soluzione |
|---|---|---|
KeyError: 'ModuleName' | Modulo non importato | Aggiungi alle importazioni di tasks.py |
| Discrepanza nelle dimensioni dei canali | Specificazione args errata | Verifica la compatibilità dei canali di input/output |
AttributeError: 'int' object has no attribute | Tipo di argomento errato | Controlla la documentazione del modulo per i tipi di argomento corretti |
| Il modello non riesce a costruire | Riferimento from non valido | Assicurati che i livelli referenziati esistano |
Suggerimenti per il debug
Durante lo sviluppo di architetture personalizzate, il debug sistematico aiuta a identificare i problemi precocemente:
Usa Identity Head per i test
Sostituisci le teste complesse con nn.Identity per isolare i problemi del backbone:
nc: 1
backbone:
- [-1, 1, CustomBlock, [64]]
head:
- [-1, 1, nn.Identity, []] # Pass-through for debuggingQuesto consente l'ispezione diretta degli output del backbone:
import torch
from ultralytics import YOLO
model = YOLO("debug_model.yaml")
output = model.model(torch.randn(1, 3, 640, 640))
print(f"Output shape: {output.shape}") # Should match expected dimensionsIspezione dell'architettura del modello
Controllare il conteggio dei FLOPs e stampare ogni livello può anche aiutare a eseguire il debug dei problemi con la configurazione del tuo modello personalizzato. Il conteggio dei FLOPs dovrebbe essere diverso da zero per un modello valido. Se è zero, probabilmente c'è un problema con il forward pass. Eseguire un semplice forward pass dovrebbe mostrare l'errore esatto incontrato.
from ultralytics import YOLO
# Build model with verbose output to see layer details
model = YOLO("debug_model.yaml", verbose=True)
# Check model FLOPs. Failed forward pass causes 0 FLOPs.
model.info()
# Inspect individual layers
for i, layer in enumerate(model.model.model):
print(f"Layer {i}: {layer}")Convalida passo dopo passo
- Inizia in modo minimale: testa prima con l'architettura più semplice possibile
- Aggiungi in modo incrementale: costruisci la complessità livello per livello
- Controlla le dimensioni: verifica la compatibilità dei canali e delle dimensioni spaziali
- Convalida il ridimensionamento: testa con diverse scale del modello (
n,s,m)
FAQ
Come modifico il numero di classi nel mio modello?
Imposta il parametro nc all'inizio del tuo file YAML per corrispondere al numero di classi del tuo dataset.
nc: 5 # 5 classesPosso usare un backbone personalizzato nel mio YAML del modello?
Sì. Puoi usare qualsiasi modulo supportato, inclusi i backbone TorchVision, oppure definire il tuo modulo personalizzato e importarlo come descritto in Integrazione di moduli personalizzati.
Come ridimensiono il mio modello per diverse dimensioni (nano, small, medium, ecc.)?
Usa la sezione scales nel tuo YAML per definire i fattori di scala per profondità, larghezza e canali massimi. Il modello li applicherà automaticamente quando carichi il file YAML di base con la scala aggiunta al nome del file (es. yolo26n.yaml).
Cosa significa il formato [from, repeats, module, args]?
Questo formato specifica come viene costruito ogni livello:
from: sorgente/i di inputrepeats: numero di volte in cui ripetere il modulomodule: il tipo di livelloargs: argomenti per il modulo
Come risolvo gli errori di discrepanza dei canali?
Controlla che i canali di output di un livello corrispondano ai canali di input previsti del successivo. Usa print(model.model.model) per ispezionare l'architettura del tuo modello.
Dove posso trovare un elenco dei moduli disponibili e dei loro argomenti?
Controlla il codice sorgente nella directory ultralytics/nn/modules per tutti i moduli disponibili e i loro argomenti.
Come aggiungo un modulo personalizzato alla mia configurazione YAML?
Definisci il tuo modulo nel codice sorgente, importalo come mostrato in Modifica del codice sorgente e referenzialo per nome nel tuo file YAML.
Posso usare pesi pre-addestrati con uno YAML personalizzato?
Sì, puoi usare model.load("path/to/weights") per caricare pesi da un checkpoint pre-addestrato. Tuttavia, verranno caricati con successo solo i pesi per i livelli corrispondenti.
Come convalidare la configurazione del mio modello?
Usa model.info() per verificare se il conteggio dei FLOPs è diverso da zero. Un modello valido dovrebbe mostrare un conteggio dei FLOPs non zero. Se è zero, segui i suggerimenti in Suggerimenti per il debug per trovare il problema.