Ultralytics YOLO27:

Guida alla configurazione YAML del modello#

Il file di configurazione YAML del modello funge da schema architetturale per le reti neurali Ultralytics. Definisce come si collegano i layer, quali parametri utilizza ogni modulo e come l'intera rete si adatta alle diverse dimensioni del modello.

Model YAML configuration workflow.

Struttura della configurazione#

I file YAML del modello sono organizzati in tre sezioni principali che, insieme, definiscono l'architettura.

Sezione dei parametri#

La sezione parameters specifica le caratteristiche globali e il comportamento di ridimensionamento del modello:

# 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 previste dal modello.
  • scales definisce i fattori di compound scaling che regolano la profondità, la larghezza e il numero massimo di canali del modello per produrre varianti di dimensioni diverse (da nano a extra-large).
  • kpt_shape si applica ai modelli pose. Può essere [N, 2] per i keypoint (x, y) oppure [N, 3] per (x, y, visibility).
Riduci la ridondanza con `scales`

Il parametro scales consente di generare più dimensioni del modello da un singolo YAML di base. Ad esempio, quando carichi yolo26n.yaml, Ultralytics legge il file yolo26.yaml di base e applica i fattori di scaling n (depth=0.50, width=0.25) per creare 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 durante l'esecuzione per adattarla al file YAML del dataset.

Architettura del backbone e della head#

L'architettura del modello è composta dalle sezioni backbone (estrazione delle feature) e head (specifica per il task):

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 layer

Gli indici dei layer proseguono attraverso backbone e head e le feature map concatenate devono avere dimensioni spaziali corrispondenti.

Formato della specifica dei layer#

Ogni layer segue il seguente schema coerente: [from, repeats, module, args]

ComponenteScopoEsempi
fromConnessioni di input-1 (precedente), 6 (layer 6), [4, 6, 8] (input multipli)
repeatsNumero di ripetizioni1 (singola), 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 flessibili di flusso dei dati all'interno della rete:

- [-1, 1, Conv, [64, 3, 2]]    # Takes input from previous layer
Indicizzazione dei layer

I 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 dei moduli#

Il parametro repeats crea sezioni più profonde della rete:

- [-1, 3, C2f, [128, True]] # Creates 3 consecutive C2f blocks
- [-1, 1, Conv, [64, 3, 2]] # Single convolution layer

Il numero effettivo di ripetizioni viene moltiplicato per il fattore di scaling della profondità della configurazione relativa alla dimensione del modello.

Moduli disponibili#

I moduli sono organizzati per funzionalità e definiti nella directory dei moduli Ultralytics. Le tabelle seguenti mostrano i moduli più utilizzati per categoria, mentre nel codice sorgente sono disponibili molti altri moduli:

Operazioni di base#

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

Blocchi compositi#

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

Moduli specializzati#

ModuloScopoOrigineArgomenti
TorchVisionCarica qualsiasi modello torchvisionblock.py[out_ch, model_name, weights, unwrap, truncate, split]
IndexEstrae un tensore specifico dall'elencoconv.py[out_ch, index]
DetectHead di rilevamento YOLOhead.py[nc]
Elenco completo dei moduli

Questo rappresenta un sottoinsieme dei moduli disponibili. Per consultare l'elenco completo dei moduli e dei relativi parametri, esplora la directory dei moduli.

Funzionalità avanzate#

Integrazione con TorchVision#

Il modulo TorchVision consente di integrare facilmente 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)
Feature multi-scala

Imposta l'ultimo parametro su True per ottenere feature map intermedie per il rilevamento multi-scala.

Modulo Index per la selezione delle feature#

Quando utilizzi modelli che producono più feature map, 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 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 m.startswith("nn.")
    else getattr(__import__("torchvision").ops, m[16:])
    if m.startswith("torchvision.ops.")
    else globals()[m]
)  # get module
  1. Moduli PyTorch: i nomi che iniziano con 'nn.' → namespace torch.nn
  2. Operazioni TorchVision: i nomi che iniziano con 'torchvision.ops.' → namespace torchvision.ops
  3. Moduli Ultralytics: tutti gli altri nomi → namespace globale tramite le importazioni

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 moduli personalizzati, ma può essere complesso. Per definire e utilizzare un modulo personalizzato, segui questi passaggi:

  1. Installa Ultralytics in modalità sviluppo utilizzando il metodo del clone Git dalla guida introduttiva.

  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. Aggiungilo alle importazioni in ultralytics/nn/tasks.py:

    from ultralytics.nn.modules import CustomBlock  # noqa
  5. Aggiungi il modulo a base_modules all'interno di parse_model(). I moduli di questo insieme ricevono automaticamente i canali di input e output:

    base_modules = frozenset(
        {
            # Existing modules...
            CustomBlock,
        }
    )
  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 verificare 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 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]] # 7

Modello con 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]]

head:
    - [-1, 1, Classify, [nc]]

Classify esegue già internamente l'adaptive average pooling.

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 apporta modifiche incrementali invece di costruire tutto da zero.

Esegui test incrementali: convalida ogni modifica passo dopo passo. Aggiungi un modulo personalizzato alla volta e verifica che funzioni prima di procedere con la 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 connessioni skip: sfrutta il riutilizzo delle caratteristiche con i pattern [[-1, N], 1, Concat, [1]]. Queste connessioni favoriscono il flusso del gradiente e consentono al modello di combinare caratteristiche provenienti da scale diverse.

Ridimensiona in modo appropriato: scegli le scale del modello in base ai tuoi vincoli computazionali. Usa nano (n) per i dispositivi edge, small (s) per un compromesso equilibrato tra prestazioni e risorse e le scale più grandi (m, l, x) per ottenere la massima accuratezza.

Considerazioni sulle prestazioni#

Profondità e ampiezza: le reti profonde acquisiscono caratteristiche gerarchiche complesse attraverso più layer di trasformazione, mentre le reti ampie elaborano più informazioni in parallelo a ogni layer. Bilancia questi aspetti in base alla complessità del tuo task.

Connessioni skip: migliorano il flusso del gradiente durante l'addestramento e consentono il riutilizzo delle caratteristiche in tutta la rete. Sono particolarmente importanti nelle architetture più profonde per prevenire la scomparsa dei gradienti.

Blocchi bottleneck: riducono il costo computazionale mantenendo la capacità espressiva del modello. Moduli come C2f usano meno parametri rispetto alle convoluzioni standard, preservando al contempo la capacità di apprendere le caratteristiche.

Caratteristiche multi-scala: sono essenziali per rilevare oggetti di dimensioni diverse nella stessa immagine. Usa pattern di Rete piramidale delle caratteristiche (FPN) con più teste di rilevamento a scale diverse.

Risoluzione dei problemi#

Problemi comuni#

ProblemaCausaSoluzione
KeyError: 'ModuleName'Modulo non importatoAggiungilo agli import di tasks.py
Incompatibilità delle dimensioni dei canaliSpecifica args errataVerifica la compatibilità dei canali di input/output
AttributeError: 'int' object has no attributeTipo di argomento erratoControlla la documentazione del modulo per conoscere i tipi di argomento corretti
Il modello non viene compilatoRiferimento from non validoAssicurati che i layer a cui si fa riferimento esistano

Suggerimenti per il debugging#

Quando sviluppi architetture personalizzate, un debugging sistematico aiuta a identificare tempestivamente i problemi:

Usa una testa Identity 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 di esaminare direttamente gli 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 dimensions

Ispezione dell'architettura del modello

Controllare il conteggio dei FLOPs e stampare ogni layer può aiutare a eseguire il debugging dei problemi nella configurazione del tuo modello personalizzato. Il conteggio dei FLOPs dovrebbe essere diverso da zero per un modello valido. Se è zero, è probabile che ci sia un problema nel forward pass. Eseguire un semplice forward pass dovrebbe mostrare l'errore esatto che si sta verificando.

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

  1. Inizia con il minimo indispensabile: esegui prima i test con l'architettura più semplice possibile
  2. Aggiungi in modo incrementale: aumenta la complessità layer dopo layer
  3. Controlla le dimensioni: verifica la compatibilità dei canali e delle dimensioni spaziali
  4. Convalida lo scaling: esegui test con scale diverse del modello (n, s, m)

FAQ#

  • Imposta il parametro nc all'inizio del tuo file YAML in modo che corrisponda al numero di classi del tuo dataset.

    nc: 5 # 5 classes
  • Sì. Puoi usare qualsiasi modulo supportato, inclusi i backbone TorchVision, oppure definire un modulo personalizzato e importarlo come descritto in Integrazione di moduli personalizzati.

  • Usa la sezione scales nel tuo YAML per definire i fattori di scaling per profondità, ampiezza e numero massimo di canali. Il modello li applicherà automaticamente quando carichi il file YAML di base con la scala aggiunta al nome del file (ad esempio, yolo26n.yaml).

  • Questo formato specifica come viene costruito ogni layer:

    • from: sorgente o sorgenti di input
    • repeats: numero di volte in cui ripetere il modulo
    • module: tipo di layer
    • args: argomenti del modulo
  • Verifica che i canali di output di un layer corrispondano ai canali di input previsti dal layer successivo. Usa print(model.model.model) per ispezionare l'architettura del tuo modello.

  • Controlla il codice sorgente nella directory ultralytics/nn/modules per trovare tutti i moduli disponibili e i relativi argomenti.

  • Definisci il modulo nel codice sorgente, importalo come mostrato in Modifica del codice sorgente e fai riferimento a esso per nome nel tuo file YAML.

  • Sì, puoi usare model.load("path/to/weights") per caricare i pesi da un checkpoint pretrained. Tuttavia, verranno caricati correttamente solo i pesi dei layer corrispondenti.

  • Usa model.info() per verificare che il conteggio dei FLOPs sia diverso da zero. Un modello valido dovrebbe mostrare un conteggio dei FLOPs diverso da zero. Se è zero, segui i suggerimenti in Suggerimenti per il debugging per individuare il problema.

Commenti