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.

Model YAML configuration workflow.

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 only
  • nc imposta il numero di classi che il modello prevede.
  • scales definisce 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_shape si applica ai modelli di posa. Può essere [N, 2] per i keypoint (x, y) o [N, 3] per (x, y, visibility).
Riduci la ridondanza con `scales`

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.

`nc` e `kpt_shape` dipendono dal dataset

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 layer

Formato di specifica del livello

Ogni livello segue lo schema coerente: [from, repeats, module, args]

ComponenteScopoEsempi
fromConnessioni di input-1 (precedente), 6 (livello 6), [4, 6, 8] (input multipli)
repeatsNumero di ripetizioni1 (singolo), 3 (ripeti 3 volte)
moduleTipo di moduloConv, C2f, TorchVision, Detect
argsArgomenti 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 layer
Indicizzazione dei livelli

I 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 layer

Il 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

ModuloScopoSorgenteArgomenti
ConvConvoluzione + BatchNorm + Attivazioneconv.py[out_ch, kernel, stride, pad, groups]
nn.UpsampleUpsampling spazialePyTorch[size, scale_factor, mode]
nn.IdentityOperazione pass-throughPyTorch[]

Blocchi compositi

ModuloScopoSorgenteArgomenti
C2fBottleneck CSP con 2 convoluzioniblock.py[out_ch, shortcut, expansion]
SPPFSpatial Pyramid Pooling (veloce)block.py[out_ch, kernel_size]
ConcatConcatenazione per canaliconv.py[dimension]

Moduli specializzati

ModuloScopoSorgenteArgomenti
TorchVisionCarica qualsiasi modello torchvisionblock.py[out_ch, model_name, weights, unwrap, truncate, split]
IndexEstrai un tensore specifico da una listablock.py[out_ch, index]
DetectHead di rilevamento YOLOhead.py[nc, anchors, ch]
Elenco completo dei moduli

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)
Caratteristiche multi-scala

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 detection

Sistema 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]
  1. Moduli PyTorch: Nomi che iniziano con 'nn.' → namespace torch.nn
  2. Operazioni TorchVision: Nomi che iniziano con 'ops.' → namespace torchvision.ops
  3. 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:

  1. Installa Ultralytics in modalità sviluppo utilizzando il metodo Git clone dalla guida di avvio rapido.

  2. 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)
  3. 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
  4. Aggiungi alle importazioni in ultralytics/nn/tasks.py:

    from ultralytics.nn.modules import CustomBlock  # noqa
  5. Gestisci argomenti speciali (se necessario) all'interno di parse_model() in ultralytics/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:]]
  6. Utilizza il modulo nel tuo YAML del modello:

    # custom_model.yaml
    nc: 1
    backbone:
        - [-1, 1, CustomBlock, [64]]
    head:
        - [-1, 1, Classify, [nc]]
  7. 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]] # 7

Modello 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 detection

Modello 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

ProblemaCausaSoluzione
KeyError: 'ModuleName'Modulo non importatoAggiungi alle importazioni di tasks.py
Discrepanza nelle dimensioni dei canaliSpecificazione args errataVerifica la compatibilità dei canali di input/output
AttributeError: 'int' object has no attributeTipo di argomento erratoControlla la documentazione del modulo per i tipi di argomento corretti
Il modello non riesce a costruireRiferimento from non validoAssicurati 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 debugging

Questo 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 dimensions

Ispezione 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

  1. Inizia in modo minimale: testa prima con l'architettura più semplice possibile
  2. Aggiungi in modo incrementale: costruisci la complessità livello per livello
  3. Controlla le dimensioni: verifica la compatibilità dei canali e delle dimensioni spaziali
  4. 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 classes

Posso 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 input
  • repeats: numero di volte in cui ripetere il modulo
  • module: il tipo di livello
  • args: 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.

Commenti