Vai al contenuto

Configurazione YAML del modello

Il file di configurazione YAML del modello è il progetto architettonico delle reti neurali di Ultralytics . Definisce il modo in cui gli strati si collegano, i parametri utilizzati da ciascun modulo e il modo in cui l'intera rete si adatta alle diverse dimensioni del modello.

Struttura di configurazione

I file YAML del modello sono organizzati in tre sezioni principali che lavorano insieme per definire l'architettura.

Sezione Parametri

La sezione dei parametri specifica le caratteristiche globali del modello e il suo comportamento in scala:

# 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 definire fattori di scala composti che regolano la profondità, la larghezza e i canali massimi del modello per produrre diverse varianti di dimensioni (da nano a extra-large).
  • kpt_shape si applica ai modelli di posa. Può essere [N, 2] per (x, y) punti chiave o [N, 3] per (x, y, visibility).

Ridurre la ridondanza con scales

Il scales consente di generare più dimensioni di modelli da un singolo YAML di base. Per esempio, quando si carica yolo11n.yamlUltralytics legge la base yolo11.yaml e applica il n fattori di scala (depth=0.50, width=0.25) per costruire la variante nano.

nc e kpt_shape sono dipendenti dal set di dati

Se il set di dati specifica un diverso nc oppure kpt_shapeUltralytics sovrascriverà automaticamente la configurazione del modello in fase di esecuzione, in modo che corrisponda allo YAML del dataset.

Architettura backbone e head

L'architettura del modello è composta da sezioni backbone (estrazione delle caratteristiche) e head (attività specifiche):

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 delle specifiche di livello

Ogni strato segue lo stesso schema: [from, repeats, module, args]

Componente Scopo Esempi
da Connessioni di ingresso -1 (precedente), 6 (strato 6), [4, 6, 8] (multi ingresso)
ripete Numero di ripetizioni 1 (singolo), 3 (ripetere 3 volte)
modulo Tipo di modulo Conv, C2f, TorchVision, Detect
argomenti Argomenti del modulo [64, 3, 2] (canali, kernel, stride)

Modelli di connessione

Il from crea modelli di flusso di dati flessibili in tutta la rete:

- [-1, 1, Conv, [64, 3, 2]]    # Takes input from previous layer
- [[-1, 6], 1, Concat, [1]]    # Combines current layer with layer 6
- [[4, 6, 8], 1, Detect, [nc]] # Detection head using 3 feature scales

Indicizzazione dei livelli

I livelli sono indicizzati a partire da 0. Gli indici negativi si riferiscono ai livelli precedenti (-1 = strato precedente), mentre gli indici positivi si riferiscono a strati specifici in base alla loro posizione.

Ripetizione del modulo

Il 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 delle dimensioni del modello.

Moduli disponibili

I moduli sono organizzati per funzionalità e definiti nella directoryUltralytics modules. Le tabelle seguenti mostrano i moduli comunemente utilizzati per categoria, mentre molti altri sono 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 Sovracampionamento spaziale PyTorch [size, scale_factor, mode]
nn.Identity Funzionamento passante PyTorch []

Blocchi compositi

Modulo Scopo Sorgente Argomenti
C2f Collo di bottiglia CSP con 2 convoluzioni blocco.py [out_ch, shortcut, expansion]
SPPF Pooling spaziale a piramide (veloce) blocco.py [out_ch, kernel_size]
Concat Concatenazione a livello di canale conv.py [dimension]

Moduli specializzati

Modulo Scopo Sorgente Argomenti
TorchVision Caricare qualsiasi modello torchvision blocco.py [out_ch, model_name, weights, unwrap, truncate, split]
Index Estrarre un tensor specifico dall'elenco blocco.py [out_ch, index]
Detect Testa di rilevamento YOLO head.py [nc, anchors, ch]

Elenco completo dei moduli

Questo rappresenta un sottoinsieme dei moduli disponibili. Per l'elenco completo dei moduli e dei loro parametri, esplorare la directory modules.

Caratteristiche avanzate

Integrazione di TorchVision

Il modulo TorchVision consente la perfetta integrazione 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)
backbone:
  - [-1, 1, TorchVision, [768, convnext_tiny, DEFAULT, True, 2, False]]
head:
  - [-1, 1, Classify, [nc]]

Ripartizione dei parametri:

  • 768: Canali di uscita previsti
  • convnext_tiny: Architettura del modello (modelli disponibili)
  • DEFAULT: Utilizzare i pesi preaddestrati
  • True: Rimuovere la testa di classificazione
  • 2: Tronca gli ultimi 2 strati
  • False: Restituisce un singolo tensor (non un elenco)

Caratteristiche multiscala

Impostare l'ultimo parametro su True per ottenere mappe di caratteristiche intermedie per il rilevamento multiscala.

Modulo indice per la selezione delle caratteristiche

Quando si utilizzano modelli che producono più mappe di caratteristiche, il modulo Indice seleziona gli 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 del modulo

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.'torch.nn spazio dei nomi
  2. Operazioni TorchVision: Nomi che iniziano con 'ops.'torchvision.ops spazio dei nomi
  3. ModuliUltralytics : Tutti gli altri nomi → spazio dei nomi globale tramite importazioni

Catena di importazione dei moduli

I moduli standard diventano disponibili attraverso le importazioni in tasks.py:

from ultralytics.nn.modules import (  # noqa: F401, E501
    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 moduli personalizzati, ma può essere complicata. Per definire e utilizzare un modulo personalizzato, seguite questi passaggi:

  1. Definire il modulo in ultralytics/nn/modules/block.py:

    class CustomBlock(nn.Module):
        def __init__(self, c1, c2):
            super().__init__()
            self.layers = nn.Sequential(nn.Conv2d(c1, c2, 3, 1, 1), nn.BatchNorm2d(c2), nn.ReLU())
    
        def forward(self, x):
            return self.layers(x)
    
  2. Esporre il proprio modulo a livello di pacchetto in ultralytics/nn/modules/__init__.py:

    from .block import CustomBlock  # noqa makes CustomBlock available as ultralytics.nn.modules.CustomBlock
    
  3. Aggiungi alle importazioni in ultralytics/nn/tasks.py:

    from ultralytics.nn.modules import CustomBlock  # noqa
    
  4. Gestire argomenti speciali (se necessario) all'interno parse_model() in ultralytics/nn/tasks.py:

    elif m is CustomBlock:
        c1, c2 = ch[f], args[0]  # input channels, output channels
        args = [c1, c2, *args[1:]]
    
  5. Utilizzare il modulo nel modello YAML:

    # custom_model.yaml
    nc: 1
    backbone:
        - [-1, 1, CustomBlock, [64]]
    head:
        - [-1, 1, Classify, [nc]]
    
  6. Controllare i FLOP per verificare che il passaggio in avanti 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 di 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]]

Migliori pratiche

Suggerimenti per il design dell'architettura

Iniziare in modo semplice: Iniziare con architetture collaudate prima di personalizzare. Utilizzate le configurazioni YOLO esistenti come modelli e modificatele in modo incrementale piuttosto che costruirle da zero.

Eseguire i test in modo incrementale: Convalidare ogni modifica passo dopo passo. Aggiungete un modulo personalizzato alla volta e verificate che funzioni prima di procedere alla modifica successiva.

Canali di monitoraggio: Assicurarsi che le dimensioni dei canali corrispondano tra i livelli collegati. I canali di uscita (c2) di uno strato deve corrispondere ai canali di ingresso (c1) dello strato successivo nella sequenza.

Utilizzare le connessioni a salto: Sfruttare il riutilizzo delle funzionalità con [[-1, N], 1, Concat, [1]] modelli. Queste connessioni aiutano a gestire il flusso dei gradienti e consentono al modello di combinare caratteristiche provenienti da scale diverse.

Scala appropriata: Scegliere le scale del modello in base ai vincoli computazionali. Usare nano (n) per i dispositivi edge, piccoli (s) per prestazioni equilibrate, e scale più grandi (m, l, x) per ottenere la massima precisione.

Considerazioni sulle prestazioni

Profondità vs. larghezza: le reti profonde catturano caratteristiche gerarchiche complesse attraverso più livelli di trasformazione, mentre le reti larghe elaborano più informazioni in parallelo a ogni livello. Bilanciate questi aspetti in base alla complessità del vostro compito.

Saltare le connessioni: 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 evitare che i gradienti svaniscano.

Blocchi a collo di bottiglia: Ridurre il costo computazionale mantenendo l'espressività del modello. Moduli come C2f utilizzano un numero inferiore di parametri rispetto alle convoluzioni standard, pur mantenendo la capacità di apprendimento delle caratteristiche.

Caratteristiche multiscala: Essenziale per rilevare oggetti di dimensioni diverse nella stessa immagine. Utilizzare modelli di 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 a tasks.py importazioni
Disadattamento delle dimensioni del canale Non corretto args specifiche Verificare la compatibilità dei canali di ingresso/uscita
AttributeError: 'int' object has no attribute Tipo di argomento sbagliato Controllare la documentazione del modulo per verificare i tipi di argomenti corretti
Il modello non riesce a costruire Non valido from riferimento Assicurarsi che i livelli di riferimento esistano

Suggerimenti per il debug

Quando si sviluppano architetture personalizzate, il debug sistematico aiuta a identificare tempestivamente i problemi:

Utilizzare Identity Head per i test

Sostituire le teste complesse con nn.Identity per isolare i problemi della spina dorsale:

nc: 1
backbone:
    - [-1, 1, CustomBlock, [64]]
head:
    - [-1, 1, nn.Identity, []] # Pass-through for debugging

Ciò consente di ispezionare direttamente le uscite della dorsale:

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

Il controllo del conteggio delle FLOPs e la stampa di ogni livello possono aiutare a individuare i problemi con la configurazione del modello personalizzato. Il conteggio dei FLOP dovrebbe essere diverso da zero per un modello valido. Se è zero, è probabile che ci sia un problema con il forward pass. L'esecuzione di 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", 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. Iniziare in modo minimale: Testare prima con l'architettura più semplice possibile
  2. Aggiungere in modo incrementale: Costruire la complessità strato per strato
  3. Controllare le dimensioni: Verificare la compatibilità del canale e delle dimensioni spaziali
  4. Convalidare il ridimensionamento: Test con diverse scale di modelli (n, s, m)

FAQ

Come posso modificare il numero di classi nel mio modello?

Impostare il nc all'inizio del file YAML, in modo che corrisponda al numero di classi del dataset.

nc: 5 # 5 classes

Posso usare un backbone personalizzato nel mio modello YAML?

Sì. È possibile utilizzare qualsiasi modulo supportato, comprese le dorsali di TorchVision, oppure definire un proprio modulo personalizzato e importarlo come descritto in Integrazione di moduli personalizzati.

Come faccio a scalare il mio modello per dimensioni diverse (nano, piccolo, medio, ecc.)?

Utilizzare il scales sezione nel file YAML per definire i fattori di scala per la profondità, la larghezza e i canali massimi. Il modello li applicherà automaticamente quando si caricherà il file YAML di base con la scala aggiunta al nome del file (ad esempio, yolo11n.yaml).

Che cosa fa il [from, repeats, module, args] formato significa?

Questo formato specifica come viene costruito ogni strato:

  • from: sorgente/i di ingresso
  • repeatsNumero di volte in cui ripetere il modulo
  • module: il tipo di strato
  • args: argomenti per il modulo

Come si risolvono gli errori di mancata corrispondenza dei canali?

Verificare che i canali di uscita di un livello corrispondano ai canali di ingresso previsti per il livello successivo. Utilizzare print(model.model.model) per ispezionare l'architettura del modello.

Dove posso trovare un elenco dei moduli disponibili e dei loro argomenti?

Controllare il codice sorgente nella sezione ultralytics/nn/modules directory per tutti i moduli disponibili e i loro argomenti.

Come si aggiunge un modulo personalizzato alla configurazione YAML?

Definire il modulo nel codice sorgente, importarlo come mostrato in Modifica del codice sorgente e riferirlo per nome nel file YAML.

È possibile utilizzare i pesi preaddestrati con uno YAML personalizzato?

Sì, è possibile utilizzare model.load("path/to/weights") per caricare i pesi da un checkpoint preaddestrato. Tuttavia, solo i pesi dei livelli corrispondenti vengono caricati correttamente.

Come si convalida la configurazione del modello?

Usa model.info() per verificare se il conteggio dei FLOP è diverso da zero. Un modello valido dovrebbe mostrare un conteggio di FLOPs non nullo. Se è zero, seguire i suggerimenti in Suggerimenti per il debug per trovare il problema.



📅 Creato 0 giorni fa ✏️ Aggiornato 0 giorni fa