YOLO Vision 2026:

Architettura di YOLO spiegata: da YOLOv3 a YOLO26#

Ogni modello Ultralytics YOLO è costruito in tre fasi: un backbone che estrae le caratteristiche, un neck che le fonde tra diverse scale e una head che predice riquadri e classi. Questa guida documenta i moduli che compongono ogni fase e il modo in cui sono cambiati da YOLOv3 a YOLO26, ricond​​ucendo ogni componente alla relativa definizione nei file di configurazione in ultralytics/cfg/models/ e alle classi dei moduli in ultralytics/nn/modules/.

Ogni modello è definito in modo dichiarativo in un file YAML come elenco ordinato di layer, in cui ogni layer segue il formato [from, repeats, module, args]: quali layer lo alimentano, quante volte il modulo viene ripetuto, la classe del layer (Conv, C3k2, SPPF, Detect, …) e i relativi argomenti del costruttore. La Guida alla configurazione YAML del modello documenta questo formato — incluso il modo in cui repeats e args scalano con i moltiplicatori di profondità e larghezza della variante — insieme al sistema completo di risoluzione dei moduli. Questa guida si concentra sui moduli in sé e sul modo in cui sono cambiati da una versione all'altra.

Le tre fasi#

Ogni modello Ultralytics YOLO instrada l'immagine attraverso tre fasi sequenziali, ciascuna con un compito distinto:

FaseCompitoOutput
BackboneEstrae le caratteristiche dall'immagine di input a più risoluzioniMappe delle caratteristiche con stride 8, 16 e 32 (P3, P4, P5)
NeckFonde le caratteristiche tra le scale, così che sia gli oggetti piccoli sia quelli grandi dispongano del contestoMappe delle caratteristiche fuse multi-scala
HeadPredice i riquadri di delimitazione e i punteggi delle classi dalle caratteristiche fuseRilevamenti per punto di ancoraggio

L'unità fondamentale è il blocco Conv (definito in conv.py): una convoluzione 2D, la normalizzazione batch e un'attivazione SiLU, applicate in sequenza. Ogni modulo più grande riportato di seguito è costruito componendo blocchi Conv.

Diagrammi dell'architettura#

Ogni versione mantiene lo stesso scheletro backbone → neck → head e modifica fasi specifiche. Le schede seguenti mostrano la struttura per versione: le fasi del backbone e del neck seguono le configurazioni in ultralytics/cfg/models/, mentre le head di YOLOv3 e YOLOv5 sono rappresentate nella loro forma originale basata su anchor, anziché nella head della variante u anchor-free effettivamente distribuita dalle configurazioni dei rispettivi pacchetti. Scorrendo le schede puoi vedere cosa ha aggiunto ogni generazione. In breve, l'evoluzione è questa: YOLOv3 è un rilevatore basato su anchor e solo FPN; YOLOv5 aggiunge il percorso PAN bottom-up e SPPF; YOLOv8 passa al blocco C2f con una head anchor-free e DFL; YOLO11 inserisce l'attenzione C2PSA e il blocco C3k2; YOLO26 aggiunge un residuo SPPF e rende la head priva di NMS e DFL. I colori dei nodi seguono la convenzione dei diagrammi della documentazione: input verde, backbone blu, pooling spaziale e attenzione ardesia, neck arancione, head e output viola.

flowchart TD
    IN[Input 640x640]:::start --> ST[Conv stem<br/>5x stride-2 down to P1-P5]:::proc
    ST --> BB[Darknet-53 backbone<br/>stacked Bottleneck]:::proc
    BB --> FPN[Neck FPN only<br/>top-down Upsample + Concat]:::decide
    FPN --> HD[Detect head<br/>3 scales, anchor-based]:::out
    HD --> O[Predictions + NMS]:::out
    classDef start fill:#4CAF50,color:#fff
    classDef proc fill:#2196F3,color:#fff
    classDef decide fill:#FF9800,color:#fff
    classDef out fill:#9C27B0,color:#fff

I diagrammi di YOLOv3 e YOLOv5 mostrano la head originale basata su anchor. Il pacchetto ultralytics distribuisce le configurazioni anchor-free YOLOv3u e YOLOv5u — gli stessi backbone Darknet-53 e C3, con la head Detect di YOLOv8 — descritti nella sezione Detection Head.

Blocchi del backbone: Bottleneck → C3 → C2f → C3k2#

Il backbone concatena un blocco CSP (parziale tra fasi (CSP)) ripetuto tra layer di downsampling Conv con stride 2. È proprio questo blocco ripetuto a essere cambiato maggiormente tra le versioni. Tutti i blocchi seguenti si trovano in block.py; c1/c2 sono i canali di input/output e c = 0.5 * c2 è la larghezza nascosta.

Bottleneck (YOLOv3)#

L'unità di base è Bottleneck: due layer Conv (kernel predefiniti (3, 3)) con un'addizione residua opzionale quando shortcut=True e c1 == c2. Il backbone Darknet-53 di YOLOv3 li concatena direttamente, senza suddivisione CSP, ed esegue il rilevamento a tre scale (stride 8, 16 e 32).

C3 (YOLOv5)#

Il C3 di YOLOv5 divide l'input attraverso due convoluzioni 1x1: cv1 alimenta n blocchi Bottleneck sequenziali (kernel (1, 1) e poi (3, 3)), mentre cv2 li bypassa. I due percorsi vengono concatenati e fusi da un terzo 1x1 Conv:

def forward(self, x):
    # C3: bottleneck path m(cv1(x)) concatenated with bypass cv2(x), then fused by cv3
    return self.cv3(torch.cat((self.m(self.cv1(x)), self.cv2(x)), 1))

Solo l'output del bottleneck finale raggiunge la convoluzione di fusione, quindi cv3 vede 2 mappe delle caratteristiche.

C2f (YOLOv8)#

Il C2f di YOLOv8 ("Bottleneck CSP con 2 convoluzioni, più veloce") modifica le caratteristiche che raggiungono la convoluzione di fusione:

  1. cv1 = Conv(c1, 2 * c, 1), quindi chunk(2) divide l'output in due tensori con c canali.
  2. I blocchi n Bottleneck(c, c) (kernel (3, 3), (3, 3)) vengono eseguiti in sequenza, ciascuno alimentato dall'output del blocco precedente.
  3. Tutti i tensori intermedi n + 2 vengono concatenati e fusi da cv2 = Conv((2 + n) * c, c2, 1).

Dove C3 passa 2 mappe delle caratteristiche alla propria convoluzione di fusione, C2f ne passa n + 2: ogni output intermedio del bottleneck viene riutilizzato.

C3k2 (YOLO11 e YOLO26)#

YOLO11 e YOLO26 usano C3k2, una sottoclasse di C2f che sostituisce l'unità ripetuta. Ciascuno dei n blocchi diventa, a seconda dei flag del costruttore:

  • un semplice Bottleneck (predefinito, c3k=False),
  • un blocco C3k (c3k=True) — una variante C3 con dimensione del kernel configurabile, oppure
  • una coppia Bottleneck + PSABlock (attn=True).

Il secondo argomento YAML imposta c3k, a meno che la scala non sia m, l o x, valori che lo forzano a True: è così che un unico yolo11.yaml serve tutte e cinque le varianti. Pertanto [-1, 2, C3k2, [512, False]] costruisce gli interni Bottleneck a n e s, ma gli interni C3k a m, l e x; 512 è il numero di canali prima del ridimensionamento, che il moltiplicatore di larghezza della variante trasforma in 128 a n e in 768 a x. Per i moduli CSP, il campo repeats — qui pari a 2, prima di essere scalato dal moltiplicatore di profondità della variante — diventa il numero di ripetizioni interne del blocco anziché concatenare moduli separati.

Pooling spaziale: SPP → SPPF#

Alla fine del backbone, un blocco di spatial-pyramid-pooling amplia il campo ricettivo. YOLOv5 ha sostituito l'originale SPP multi-kernel con SPPF (Spatial Pyramid Pooling - Fast): un singolo MaxPool2d(kernel_size=5, stride=1, padding=2) applicato n = 3 volte in sequenza, con l'input e tutti e tre gli output sottoposti a pooling concatenati e fusi da un 1x1 Conv. È matematicamente equivalente a SPP(k=(5, 9, 13)), ma più economico, perché i pooling concatenati 5x5 coprono i campi ricettivi dei kernel più grandi.

YOLO26 passa un flag shortcut (SPPF, [1024, 5, 3, True]); poiché c1 == c2 == 1024 si trova al layer più profondo, SPPF aggiunge una connessione residua (return y + x).

Attenzione spaziale: C2PSA (YOLO11+)#

YOLO11 ha aggiunto C2PSA dopo SPPF. È un blocco CSP il cui ramo attivo è una pila di moduli n PSABlock (attenzione sensibile alla posizione): cv1 = Conv(c1, 2 * c, 1) divide le caratteristiche, una metà passa attraverso la pila PSABlock e cv2 = Conv(2 * c, c1, 1) fonde la concatenazione. Ogni PSABlock applica l'attenzione multi-head seguita da una rete feed-forward a due layer (Conv(c, 2 * c, 1)Conv(2 * c, c, 1)), ciascuna con una connessione residua. YOLO26 mantiene lo stesso backbone C3k2 + C2PSA.

Neck: FPN + PAN#

Il neck fonde le mappe delle caratteristiche P3/P4/P5 del backbone con una rete FPN (Feature Pyramid Network) top-down seguita da una rete PAN (Path Aggregation Network) bottom-up. Nella sezione head dello YAML, FPN è nn.Upsample + Concat (che porta le informazioni semantiche verso risoluzioni più elevate) e PAN è Conv + Concat con stride 2 (che riporta le informazioni di localizzazione verso l'alto):

# YOLO11 head (FPN top-down, then PAN bottom-up)
- [-1, 1, nn.Upsample, [None, 2, "nearest"]]
- [[-1, 6], 1, Concat, [1]] # cat backbone P4
- [-1, 2, C3k2, [512, False]] # 13
# ... second upsample + concat to P3 ...
- [-1, 1, Conv, [256, 3, 2]]
- [[-1, 13], 1, Concat, [1]] # cat head P4 (PAN)
- [-1, 2, C3k2, [512, False]] # 19

Il neck riutilizza il blocco del backbone della propria generazione — C3 in YOLOv5, C2f in YOLOv8, C3k2 in YOLO11 e YOLO26 — quindi ogni punto di fusione esegue lo stesso modulo utilizzato dal backbone. I tre output fusi alimentano la head. YOLOv3 è l'eccezione: il suo neck è costituito solo da FPN top-down (la sua head YAML non include downsampling con stride 2), senza il percorso PAN bottom-up introdotto da YOLOv5.

Head di rilevamento: basata su anchor → anchor-free → priva di NMS#

La head trasforma le tre mappe delle caratteristiche fuse in predizioni per il task di rilevamento. Il suo design è cambiato tra le versioni, passando da basato su anchor ad anchor-free e infine privo di NMS.

Detect anchor-free e disaccoppiata#

YOLOv3 e YOLOv5 originali usavano una head basata su anchor e accoppiata: riquadri anchor predefiniti e un ramo condiviso per le predizioni dei riquadri e delle classi. I repository autonomi ultralytics/yolov3 e ultralytics/yolov5 mantengono questo design basato su anchor. Il pacchetto principale ultralytics distribuisce invece le varianti anchor-free YOLOv3u e YOLOv5u — gli stessi backbone Darknet-53 e C3 con la head anchor-free Detect di YOLOv8 — e le configurazioni yolov3.yaml e yolov5.yaml documentate qui sono queste varianti u, non il design storico.

La head Detect (head.py) è anchor-free e disaccoppiata: per ogni livello della piramide esegue due rami paralleli e predice direttamente sui punti della griglia anziché rispetto a riquadri anchor.

  • Ramo dei riquadri (cv2): Conv(x, c2, 3)Conv(c2, c2, 3)Conv2d(c2, 4 * reg_max, 1).
  • Ramo delle classi (cv3): in YOLO11 e YOLO26, due blocchi separabili depthwise (DWConv + 1x1 Conv) → Conv2d(c3, nc, 1); YOLOv8 usa la variante legacy, due layer 3x3 ConvConv2d(c3, nc, 1).

Ogni punto di ancoraggio emette quindi no = nc + 4 * reg_max output. La rimozione degli anchor predefiniti elimina dagli iperparametri da ottimizzare le dimensioni e i rapporti d'aspetto dei riquadri anchor.

Distribution Focal Loss (DFL)#

YOLOv8 e YOLO11 regrediscono ciascuna delle 4 coordinate del riquadro come una distribuzione su reg_max = 16 bin anziché come un singolo scalare (la forma integrale della Generalized Focal Loss). Il modulo DFL rimodella i canali del riquadro 4 * reg_max in (4, reg_max), applica una softmax sui reg_max bin e usa come coordinata predetta l'indice atteso del bin — ogni indice ponderato per la propria probabilità softmax, quindi sommato. Questo è implementato come una convoluzione 1x1 fissa, i cui pesi sono gli indici dei bin arange(reg_max), perciò la somma ponderata è un singolo prodotto scalare.

YOLO26: privo di NMS e DFL#

YOLO26 imposta due parametri YAML che la head legge direttamente:

  • end2end: TrueDetect clona in profondità i suoi rami in una head one-to-one (one2one_cv2/one2one_cv3) che produce una singola predizione per oggetto, rimuovendo il passaggio di post-processing Non-Maximum Suppression (NMS). Consulta la guida al rilevamento end-to-end per i dettagli su esportazione e migrazione.
  • reg_max: 1 — con un solo bin, self.dfl diventa nn.Identity() e no = nc + 4; la head regredisce direttamente le coordinate e nel grafo ONNX esportato non compare alcuna operazione DFL.

Nelle sue cinque dimensioni del modello (n/s/m/l/x), YOLO26 raggiunge 40.9-57.5 mAP su COCO con una latenza TensorRT T4 di 1.7-11.8 ms, secondo quanto riportato nel paper di YOLO26.

Riepilogo versione per versione#

VersioneBlocco del backbonePooling spazialeAttenzioneHead di rilevamentoDFL
YOLOv3Darknet-53 (Bottleneck)nessuno nella configurazione di basenessunaOriginale: basata su anchor; variante u: anchor-freeno / sì (u)
YOLOv5C3 (CSP)SPPFnessunaOriginale: basata su anchor; variante u: anchor-freeno / sì (u)
YOLOv8C2fSPPFnessunaAnchor-free, disaccoppiatasì (reg_max=16)
YOLO11C3k2SPPFC2PSAAnchor-free, disaccoppiatasì (reg_max=16)
YOLO26C3k2SPPF + shortcutC2PSAAnchor-free, priva di NMS (end2end)rimosso (reg_max=1)

Per i dettagli sui singoli modelli, le tabelle delle prestazioni e gli esempi di utilizzo, consulta le pagine dedicate a YOLOv3, YOLOv5, YOLOv8, YOLO11 e YOLO26.

Esamina personalmente l'architettura#

Il metodo model.info() stampa un riepilogo di layer, parametri e FLOPs, mentre l'elenco dei moduli analizzato è disponibile in model.model.model.

Esamina l'architettura di un modello YOLO
from ultralytics import YOLO

# Load a pretrained model
model = YOLO("yolo11n.pt")

# Fuse Conv + BatchNorm layers so counts match the published specs
model.fuse()

# Print a summary: layers, parameters, gradients, GFLOPs
model.info()

# Inspect the detection head (the last module in the network)
head = model.model.model[-1]
print(type(head).__name__, "| reg_max:", head.reg_max, "| end2end:", head.end2end)

L'esecuzione dello snippet su tre generazioni mostra numericamente i cambiamenti. Questi sono output reali di modelli fusi dal pacchetto ultralytics, in linea con i conteggi di parametri e FLOPs pubblicati su ogni pagina del modello:

ModelloLayerParametriGFLOPsreg_maxend2endLayer DFL
YOLOv8n723,151,9048.716FalseDFL
YOLO11n1002,616,2486.516FalseDFL
YOLO26n1222,408,9325.51TrueIdentity

YOLO26n riporta reg_max=1, end2end=True e un layer DFL Identity: la firma architetturale della sua head priva di NMS e DFL.

Conteggi con e senza fusione

I valori di parametri e FLOPs sono riportati per il modello fuso (model.fuse()), che unisce ogni Conv e il relativo layer di normalizzazione batch. Questo corrisponde alle specifiche pubblicate; un checkpoint appena caricato restituisce conteggi leggermente più elevati prima della fusione.

Conclusioni#

Tra le versioni, l'architettura YOLO è cambiata una fase alla volta: il backbone è passato da Darknet-53 ai blocchi C3, C2f e C3k2 basati su CSP, con l'attenzione C2PSA; il neck ha mantenuto la struttura FPN + PAN, mentre SPP è diventato SPPF; la head è passata da basata su anchor ad anchor-free e infine al design end-to-end privo di NMS e DFL di YOLO26.

Per definire architetture personalizzate, consulta la Guida alla configurazione YAML del modello oppure confronta i modelli nelle pagine dei modelli. Per domande, contattaci su GitHub o Discord.

FAQ#

  • Un modello YOLO dispone di un backbone che estrae le caratteristiche dall'immagine con stride 8, 16 e 32, di un neck che fonde queste caratteristiche tra le scale con FPN e PAN e di una head che predice i riquadri di delimitazione e i punteggi delle classi. Ogni modello Ultralytics YOLO da YOLOv3 a YOLO26 segue questo design a tre fasi.

  • C2f (YOLOv8) è un blocco CSP che concatena gli output di tutte le mappe delle caratteristiche interne Bottleneckn + 2 — prima della convoluzione di fusione, mentre il precedente C3 ne utilizza solo 2. C3k2 (YOLO11 e YOLO26) è una sottoclasse di C2f che può sostituire ogni Bottleneck con un blocco C3k (una variante di C3 con una dimensione del kernel configurabile) quando il relativo flag c3k è impostato. Entrambi sono definiti in block.py.

  • YOLO11 apporta tre modifiche strutturali a YOLOv8: sostituisce il blocco backbone e neck C2f con C3k2, inserisce un blocco di self-attention C2PSA dopo SPPF e sostituisce il ramo di classificazione della head con convoluzioni depthwise separable più leggere. Entrambi mantengono la stessa head Detect anchor-free e disaccoppiata, con regressione DFL reg_max=16, quindi le modifiche riducono il numero di parametri e di FLOPs aumentando al contempo la precisione, invece di riprogettare l'interfaccia di rilevamento.

  • I moderni modelli Ultralytics YOLO sono anchor-free. YOLOv8, YOLO11 e YOLO26 utilizzano una head Detect anchor-free e disaccoppiata, con rami separati per la regressione dei box e la classificazione. Gli YOLOv3 e YOLOv5 originali erano basati sulle anchor, ma Ultralytics li distribuisce nelle varianti YOLOv3u e YOLOv5u, le cui configurazioni utilizzano la stessa head anchor-free di YOLOv8.

  • Sì: YOLO26 imposta end2end=True, fornendo a Detect una head one-to-one che produce una sola predizione per oggetto e rimuove il passaggio di post-processing della soppressione dei massimi non adiacenti richiesto dai modelli precedenti. Per i dettagli, consulta la guida al rilevamento end-to-end.

  • DFL esegue la regressione di ciascuna coordinata del box come una distribuzione softmax su reg_max bin (16 per impostazione predefinita in YOLOv8 e YOLO11) e utilizza il valore atteso come coordinata, invece di prevedere un singolo scalare. YOLO26 imposta reg_max=1, quindi il livello DFL diventa un'operazione identità, la head esegue direttamente la regressione delle coordinate e nei grafi ONNX o TensorRT esportati non compare alcuna operazione DFL.

  • Carica il modello in Python e chiama model.info() per ottenere un riepilogo dei livelli, dei parametri e dei GFLOPs. I livelli analizzati si trovano in model.model.model: ad esempio, model.model.model[-1] è la head Detect, che espone attributi come reg_max e end2end. L'architettura completa è definita nel file di configurazione YAML del modello.

Collaboratori

Commenti