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 del modello sono organizzati in tre sezioni principali che lavorano insieme per definire l'architettura.
Sezione 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 predice.scalesdefinisce i fattori di scala composti che regolano la profondità, la larghezza e i canali massimi del modello per produrre varianti di dimensioni diverse (da nano a extra-large).kpt_shapesi applica ai modelli di stima della posa. Può essere[N, 2]per(x, y)keypoints o[N, 3]per(x, y, visibility).
Il parametro scales ti consente di generare più dimensioni di modello da un unico YAML di base. Ad esempio, quando carichi yolo26n.yaml, Ultralytics legge il file di base yolo26.yaml e applica i fattori di scala n (depth=0.50, width=0.25) per costruire la variante nano.
Se il tuo dataset specifica un valore diverso per nc o kpt_shape, Ultralytics sovrascriverà automaticamente la configurazione del modello in fase di esecuzione per farlo corrispondere allo YAML del dataset.
Architettura di Backbone e Head#
L'architettura del modello è composta dalle sezioni backbone (estrazione delle caratteristiche) e head (specifica per il compito):
nc: 80
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]] # 3: Upsample
- [[-1, 0], 1, Concat, [1]] # 4: Spatially compatible skip connection
- [-1, 3, C2f, [256]] # 5: Process features
- [[5], 1, Detect, [nc]] # 6: Detection layerGli indici dei layer continuano attraverso il backbone e la head, e le feature map concatenate devono avere dimensioni spaziali corrispondenti.
Formato di specifica del livello#
Ogni layer segue lo schema coerente: [from, repeats, module, args]
| Componente | Scopo | Esempi |
|---|---|---|
| from | Connessioni in ingresso | -1 (precedente), 6 (layer 6), [4, 6, 8] (multi-input) |
| 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) |
Modelli di connessione#
Il campo from crea modelli di flusso dati flessibili in tutta la tua rete:
- [-1, 1, Conv, [64, 3, 2]] # Takes input from previous layerI layer sono indicizzati a partire da 0. Gli indici negativi fanno riferimento ai layer precedenti (-1 = layer precedente), mentre gli indici positivi fanno riferimento a layer 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 modello.
Moduli disponibili#
I moduli sono organizzati per funzionalità e definiti nella directory dei moduli di Ultralytics. Le tabelle seguenti mostrano i moduli più comunemente usati 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 composti#
| Modulo | Scopo | Sorgente | Argomenti |
|---|---|---|---|
C2f | Bottleneck CSP con 2 convoluzioni | block.py | [out_ch, shortcut, groups, expansion] |
SPPF | Spatial Pyramid Pooling (veloce) | block.py | [out_ch, kernel_size] |
Concat | Concatenazione basata sui 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 dalla lista | conv.py | [out_ch, index] |
Detect | Head di rilevamento YOLO | head.py | [nc] |
Questo rappresenta un sottoinsieme dei moduli disponibili. Per l'elenco completo dei moduli e dei relativi parametri, esplora la directory dei moduli.
Funzionalità avanzate#
Integrazione TorchVision#
Il modulo TorchVision consente l'integrazione trasparente di qualsiasi modello TorchVision come backbone:
from ultralytics import YOLO
# Model with ConvNeXt backbone
model = YOLO("convnext_backbone.yaml")
results = model.train(data="imagenet10", epochs=100)Imposta l'ultimo parametro su True per ottenere mappe di caratteristiche intermedie per il rilevamento multi-scala.
Modulo Index per la selezione delle caratteristiche#
Quando utilizzi modelli che producono mappe delle caratteristiche multiple, il modulo Index seleziona output specifici:
nc: 80
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 del modulo#
Capire come Ultralytics individua e importa i moduli è fondamentale per la personalizzazione:
Processo di ricerca del modulo#
Ultralytics utilizza un sistema a tre livelli in parse_model:
# Core resolution logic
m = (
getattr(torch.nn, m[3:])
if m.startswith("nn.")
else getattr(__import__("torchvision").ops, m[16:])
if m.startswith("torchvision.ops.")
else globals()[m]
) # get module- Moduli PyTorch: Nomi che iniziano con
'nn.'→ namespacetorch.nn - Operazioni TorchVision: Nomi che iniziano con
'torchvision.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#
La modifica del codice sorgente è il modo più versatile per integrare i tuoi moduli personalizzati, ma può essere complicata. Per definire e utilizzare un modulo personalizzato, segui questi passaggi:
-
Installa Ultralytics in modalità di sviluppo utilizzando il metodo di clonazione Git dalla guida rapida.
-
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 -
Aggiungi il modulo a
base_modulesall'interno diparse_model(). I moduli in questo set ricevono automaticamente i canali di input e output:base_modules = frozenset( { # Existing modules... CustomBlock, } ) -
Usa 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 passaggio in avanti (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 di 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]]
head:
- [-1, 1, Classify, [nc]]Classify esegue già internamente il pooling medio adattivo.
Best practice#
Suggerimenti per la progettazione dell'architettura#
Inizia in modo semplice: Parti da architetture collaudate prima di personalizzarle. Usa le configurazioni YOLO esistenti come modelli e modifica in modo incrementale anziché 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 layer collegati. I canali di output (c2) di un layer devono corrispondere ai canali di input (c1) del layer successivo nella sequenza.
Usa i collegamenti di salto (Skip Connections): Sfrutta il riutilizzo delle caratteristiche con i pattern [[-1, N], 1, Concat, [1]]. Questi collegamenti aiutano il flusso dei gradienti e consentono al modello di combinare caratteristiche provenienti da scale diverse.
Scala in modo appropriato: Scegli le scale del modello in base ai tuoi vincoli di calcolo. 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 caratteristiche gerarchiche complesse attraverso molteplici strati di trasformazione, mentre le reti larghe elaborano più informazioni in parallelo ad ogni strato. Bilancia questi aspetti in base alla complessità del tuo compito.
Connessioni di salto: Migliorano il flusso del gradiente durante l'addestramento e consentono il riutilizzo delle caratteristiche in tutta la rete. Sono particolarmente importanti in architetture più profonde per prevenire la scomparsa dei gradienti.
Blocchi Bottleneck: Riduci i costi di calcolo mantenendo l'espressività del modello. Moduli come C2f utilizzano meno parametri rispetto alle convoluzioni standard pur preservando la capacità di apprendimento delle caratteristiche.
Caratteristiche multi-scala: Essenziali per rilevare oggetti di dimensioni diverse nella stessa immagine. Usa schemi Feature Pyramid Network (FPN) con molteplici 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 nella dimensione dei canali | Specifiche errate per args | Verifica la compatibilità dei canali di ingresso/uscita |
AttributeError: 'int' object has no attribute | Tipo di argomento errato | Controlla la documentazione del modulo per i tipi di argomento corretti |
| Il modello non viene compilato | Riferimento non valido per from | Assicurati che gli strati 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 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", task="detect")
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 strato 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 passaggio in avanti (forward pass). Eseguire un semplice passaggio in avanti dovrebbe mostrare l'errore esatto riscontrato.
from ultralytics import YOLO
# Build model with verbose output to see layer details
model = YOLO("debug_model.yaml", task="detect", 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à strato per strato
- Controlla le dimensioni: Verifica la compatibilità tra canali e dimensioni spaziali
- Valida la scalatura: Testa con diverse scale di modello (
n,s,m)
FAQ#
Imposta il parametro
ncall'inizio del tuo file YAML affinché corrisponda al numero di classi del tuo dataset.nc: 5 # 5 classesSì. Puoi usare qualsiasi modulo supportato, inclusi i backbone di TorchVision, oppure definire il tuo modulo personalizzato e importarlo come descritto in Integrazione di moduli personalizzati.
Usa la sezione
scalesnel tuo file YAML per definire i fattori di scala per profondità, larghezza e canali massimi. Il modello li applicherà automaticamente quando caricherai il file YAML di base con la scala aggiunta alla fine del nome del file (ad es.,yolo26n.yaml).Questo formato specifica come viene costruito ogni strato:
from: sorgente/i di inputrepeats: numero di volte in cui ripetere il modulomodule: il tipo di layerargs: argomenti per il modulo
Verifica che i canali di output di un layer corrispondano ai canali di input attesi del successivo. Usa
print(model.model.model)per ispezionare l'architettura del tuo modello.Controlla il codice sorgente nella directory
ultralytics/nn/modulesper tutti i moduli disponibili e i relativi argomenti.Definisci il tuo modulo nel codice sorgente, importalo come mostrato in Modifica del codice sorgente e riferisciti ad esso per nome nel tuo file YAML.
Sì, puoi usare
model.load("path/to/weights")per caricare i pesi da un checkpoint preaddestrato. Tuttavia, verranno caricati con successo solo i pesi dei layer corrispondenti.Usa
model.info()per verificare se il conteggio dei FLOP è diverso da zero. Un modello valido dovrebbe mostrare un conteggio dei FLOP diverso da zero. Se è zero, segui i suggerimenti nei Suggerimenti per il debug per trovare il problema.