Architettura YOLO spiegata: da YOLOv3 a YOLO26#
Ogni modello Ultralytics YOLO è strutturato in tre fasi: una backbone che estrae le caratteristiche, una neck che le fonde su diverse scale e una head che predice i box e le classi. Questa guida documenta i moduli che compongono ciascuna fase e come si sono evoluti da YOLOv3 a YOLO26, tracciando ogni componente fino alla sua definizione nei file di configurazione in ultralytics/cfg/models/ e nelle classi dei moduli in ultralytics/nn/modules/.
Ogni modello è definito in modo dichiarativo in un file YAML come un elenco ordinato di layer, in cui ciascun layer segue il formato [from, repeats, module, args]: quale o quali layer lo alimentano, quante volte si ripete il modulo, la classe del layer (Conv, C3k2, SPPF, Detect, …) e i relativi argomenti del costruttore. La Guida alla configurazione YAML del modello documenta questo formato, inclusi il modo in cui repeats e args si scalano con i multipli di profondità e larghezza della variante, insieme al sistema di risoluzione dei moduli in dettaglio. Questa guida si concentra sui moduli stessi e su come sono cambiati da una versione all'altra.
I tre stadi#
Ogni modello Ultralytics YOLO instrada l'immagine attraverso tre stadi sequenziali, ognuno con un compito distinto:
| Fase | Compito | Output |
|---|---|---|
| Backbone | Estrai feature dall'immagine di input a risoluzioni multiple | Mappe delle feature a stride 8, 16 e 32 (P3, P4, P5) |
| Neck | Fondi le feature attraverso diverse scale in modo che sia gli oggetti piccoli che quelli grandi abbiano un contesto | Mappe delle feature fuse multi-scala |
| Head | Predici i bounding box e i punteggi delle classi dalle feature fuse | Rilevamenti per anchor point |
L'unità fondamentale è il blocco Conv (definito in conv.py): una convoluzione 2D, la normalizzazione batch e un'attivazione SiLU, applicate in sequenza. Ciascuno dei moduli più grandi sottostanti è costruito componendo blocchi Conv.
Diagrammi dell'architettura#
Ogni versione mantiene lo stesso scheletro backbone → neck → head e modifica fasi specifiche. Le schede sottostanti mostrano la struttura per versione: le fasi di backbone e neck seguono le configurazioni in ultralytics/cfg/models/, mentre le head di YOLOv3 e YOLOv5 sono disegnate nella loro forma originale basata su ancore anziché nella head della variante u priva di ancore effettivamente inclusa nei pacchetti di configurazione. Cliccando sulle schede si mostra ciò che ogni generazione ha aggiunto. In breve, la progressione è la seguente: YOLOv3 è un rilevatore basato su ancore e basato solo su FPN; YOLOv5 aggiunge il percorso PAN dal basso verso l'alto e SPPF; YOLOv8 passa al blocco C2f con una head senza ancore e basata su DFL; YOLO11 inserisce l'attenzione C2PSA e il blocco C3k2; e YOLO26 aggiunge un residuo SPPF e rende la head priva di NMS e priva di DFL. I colori dei nodi seguono la convenzione dei diagrammi della documentazione: verde per l'input, blu per la backbone, grigio ardesia per il pooling spaziale e l'attenzione, arancione per la neck, viola per la head e l'output.
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:#fffI diagrammi di YOLOv3 e YOLOv5 mostrano la head originale basata su ancore. Il pacchetto ultralytics include le configurazioni YOLOv3u e YOLOv5u senza ancore — le stesse backbone Darknet-53 e C3 con la head Detect di YOLOv8 — descritte nella sezione Head di rilevamento.
Blocchi backbone: Bottleneck → C3 → C2f → C3k2#
La backbone impila un blocco CSP (Cross-Stage Partial) ripetuto tra i layer di sottocampionamento a stride-2 Conv. Quel blocco ripetuto è ciò che è cambiato maggiormente tra le versioni. Tutti i blocchi sottostanti 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. La backbone Darknet-53 di YOLOv3 le impila direttamente, senza alcuna divisione CSP, ed effettua il rilevamento su tre scale (stride 8, 16, 32).
C3 (YOLOv5)#
Il C3 di YOLOv5 divide l'input tra due convoluzioni 1x1: cv1 alimenta blocchi Bottleneck sequenziali di n (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 di caratteristiche.
C2f (YOLOv8)#
Il C2f di YOLOv8 ("CSP Bottleneck with 2 convolutions, faster") modifica quali feature raggiungono la convoluzione di fusione:
cv1 = Conv(c1, 2 * c, 1), quindichunk(2)divide l'output in due tensor a canalic.- I blocchi
nBottleneck(c, c)(kernel(3, 3),(3, 3)) vengono eseguiti in sequenza, ciascuno alimentato dall'output del blocco precedente. - Tutti i tensor intermedi di
n + 2vengono concatenati e fusi dacv2 = Conv((2 + n) * c, c2, 1).
Laddove C3 passa 2 mappe di caratteristiche alla sua convoluzione di fusione, C2f ne passa n + 2: ogni output di bottleneck intermedio viene riutilizzato.
C3k2 (YOLO11 e YOLO26)#
YOLO11 e YOLO26 utilizzano C3k2, una sottoclasse di C2f che scambia l'unità ripetuta. Ciascuno dei blocchi n diventa, a seconda dei flag del costruttore:
- un semplice
Bottleneck(predefinito,c3k=False), - un blocco
C3k(c3k=True) — una variante diC3con una dimensione del kernel configurabile, oppure - una coppia
Bottleneck+PSABlock(attn=True).
Il secondo argomento YAML imposta c3k; ad esempio [-1, 2, C3k2, [512, True]] costruisce un modulo C3k2 a 512 canali di output i cui blocchi interni sono C3k (poiché c3k=True). Per i moduli CSP, il campo repeats — qui impostato a 2, prima di essere scalato dal multiplo di profondità della variante — diventa il conteggio delle ripetizioni interne del blocchi anziché impilare moduli separati.
Spatial pooling: SPP → SPPF#
Alla fine della backbone, un blocco di spatial-pyramid-pooling amplia il campo recettivo. 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 di pooling concatenati e fusi da un 1x1 Conv. Questo è matematicamente equivalente a SPP(k=(5, 9, 13)) ma più economico, poiché i pool concatenati 5x5 coprono i campi recettivi dei kernel più grandi.
YOLO26 passa un flag di collegamento rapido (SPPF, [1024, 5, 3, True]); poiché c1 == c2 == 1024 si trova al layer più profondo, SPPF aggiunge una connessione residua (return y + x).
Spatial Attention: C2PSA (YOLO11+)#
YOLO11 ha aggiunto C2PSA dopo SPPF. Si tratta di un blocco CSP il cui ramo attivo è una pila di moduli n PSABlock (Position-Sensitive Attention): 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. Ciascun PSABlock applica l'attenzione multi-testa attention 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 la stessa backbone C3k2 + C2PSA.
Neck: FPN + PAN#
La neck fonde le mappe di caratteristiche P3/P4/P5 della backbone con una Feature Pyramid Network (FPN) top-down seguita da una Path Aggregation Network (PAN) bottom-up. Nella sezione YAML della head, la FPN è nn.Upsample + Concat (che trasporta informazioni semantiche verso risoluzioni più alte) e la PAN è Conv a stride-2 + Concat (che riporta verso l'alto le informazioni di localizzazione):
# 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]] # 19La neck riutilizza il blocco della backbone della sua generazione — C3 in YOLOv5, C2f in YOLOv8, C3k2 in YOLO11 e YOLO26 — in modo che ogni punto di fusione esegua lo stesso modulo utilizzato dalla backbone. I tre output fusi alimentano la head. YOLOv3 costituisce un'eccezione: la sua neck è composta esclusivamente da FPN top-down (la sua head YAML non ha alcun sottocampionamento a stride-2), senza il percorso PAN bottom-up introdotto da YOLOv5.
Detection Head: da basato su anchor → anchor-free → NMS-free#
La head trasforma le tre mappe di caratteristiche fuse in predizioni per il compito di rilevamento. Il suo design è cambiato nel corso delle versioni, passando da basato su ancore a senza ancore e infine a privo di NMS.
Senza ancore, disaccoppiata Detect#
Gli originali YOLOv3 e YOLOv5 utilizzavano una head accoppiata e basata su ancore: box di ancoraggio predefiniti e un ramo condiviso per le predizioni dei box e delle classi. I repository indipendenti ultralytics/yolov3 e ultralytics/yolov5 mantengono quel design basato su ancore. Il pacchetto principale ultralytics fornisce invece le varianti YOLOv3u e YOLOv5u senza ancore — le stesse backbone Darknet-53 e C3 con la head Detect senza ancore 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) è priva di ancore e disaccoppiata: per ogni livello della piramide esegue due rami paralleli e compie predizioni direttamente sui punti della griglia anziché rispetto a box di ancoraggio.
- Ramo dei box (
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 in profondità (DWConv+1x1 Conv) →Conv2d(c3, nc, 1); YOLOv8 utilizza la variante legacy, due layer3x3 Conv→Conv2d(c3, nc, 1).
Ogni punto di ancoraggio emette pertanto no = nc + 4 * reg_max output. La rimozione delle ancore predefinite elimina le dimensioni e i rapporti di aspetto dei box di ancoraggio dai gli iperparametri da ottimizzare.
Distribution Focal Loss (DFL)#
YOLOv8 e YOLO11 eseguono la regressione di ciascuna delle 4 coordinate del box come una distribuzione su reg_max = 16 bin anziché come un singolo scalare (la forma integrale derivata da Generalized Focal Loss). Il modulo DFL ridimensiona i canali dei box 4 * reg_max a (4, reg_max), applica una funzione softmax sui bin reg_max e assume l'indice del bin atteso — in cui ciascun indice di bin viene ponderato per la sua probabilità softmax e quindi sommato — come coordinata predetta. Questa operazione è implementata come una convoluzione fissa 1x1 i cui pesi sono gli indici dei bin arange(reg_max), in modo che la somma ponderata risulti in un unico prodotto scalare.
YOLO26: NMS-free, DFL-free#
YOLO26 imposta due parametri YAML che la head legge direttamente:
end2end: True—Detectcopia in profondità i suoi rami in una head uno-a-uno (one2one_cv2/one2one_cv3) che produce una singola predizione per oggetto, rimuovendo la fase di post-elaborazione Non-Maximum Suppression (NMS). Consulta la Guida al rilevamento end-to-end per i dettagli sull'esportazione e sulla migrazione.reg_max: 1— con un solo bin,self.dfldiventann.Identity()eno = nc + 4; la head esegue la regressione delle coordinate direttamente e nessuna operazione DFL compare nel grafo ONNX esportato.
Attraverso le sue cinque dimensioni di modello (n/s/m/l/x), YOLO26 raggiunge 40,9-57,5 mAP su COCO con una latenza T4 TensorRT di 1,7-11,8 ms, come riportato nel documento di YOLO26.
Riepilogo versione per versione#
| Versione | Blocco backbone | Spatial pooling | Attenzione | Detection head | DFL |
|---|---|---|---|---|---|
| YOLOv3 | Darknet-53 (Bottleneck) | nessuno nella configurazione base | nessuna | Originale: basato su ancore; variante u: senza ancore | no / sì (u) |
| YOLOv5 | C3 (CSP) | SPPF | nessuna | Originale: basato su ancore; variante u: senza ancore | no / sì (u) |
| YOLOv8 | C2f | SPPF | nessuna | Anchor-free, disaccoppiata | sì (reg_max=16) |
| YOLO11 | C3k2 | SPPF | C2PSA | Anchor-free, disaccoppiata | sì (reg_max=16) |
| YOLO26 | C3k2 | SPPF + shortcut | C2PSA | Senza ancore, priva di NMS (end2end) | rimossa (reg_max=1) |
Per i dettagli sui singoli modelli, le tabelle delle prestazioni e gli esempi d'uso, consulta le singole pagine per YOLOv3, YOLOv5, YOLOv8, YOLO11 e YOLO26.
Esamina l'architettura da solo#
Il metodo model.info() stampa un riepilogo del layer, dei parametri e dei FLOPs, e l'elenco dei moduli analizzati è disponibile su model.model.model.
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 i cambiamenti in forma numerica. Si tratta di output reali di modelli fusi provenienti dal pacchetto ultralytics, che corrispondono ai conteggi dei parametri e dei FLOPs pubblicati in ciascuna pagina del modello:
| Modello | Livelli | Parametri | GFLOPs | reg_max | end2end | Livello DFL |
|---|---|---|---|---|---|---|
| YOLOv8n | 72 | 3,151,904 | 8.7 | 16 | False | DFL |
| YOLO11n | 100 | 2,616,248 | 6.5 | 16 | False | DFL |
| YOLO26n | 122 | 2,408,932 | 5.4 | 1 | True | Identity |
YOLO26n riporta reg_max=1, end2end=True e un layer DFL Identity — la firma architetturale della sua head priva di NMS e priva di DFL.
I valori dei parametri e dei FLOPs sono riportati per il modello fuso (model.fuse()), che unisce ciascun Conv e il relativo layer di normalizzazione batch. Questo corrisponde alle specifiche pubblicate; un checkpoint caricato di recente restituisce conteggi leggermente superiori prima della fusione.
Conclusione#
Attraverso le versioni, l'architettura YOLO è cambiata una fase alla volta: la backbone è passata da Darknet-53 a blocchi basati su CSP C3, C2f e C3k2 con attenzione C2PSA; la neck ha mantenuto la sua struttura FPN + PAN mentre SPP è diventato SPPF; e la head è passata da basata su ancore a senza ancore, per poi evolversi nel design end-to-end privo di NMS e privo di DFL di YOLO26.
Per definire architetture personalizzate, consulta la Guida alla configurazione YAML del modello o confronta i modelli nelle pagine dei modelli. Per qualsiasi domanda, contattaci su GitHub o Discord.
FAQ#
Un modello YOLO ha un backbone che estrae le caratteristiche dall'immagine a stride 8, 16 e 32, un neck che fonde tali caratteristiche attraverso le scale con FPN e PAN, e un head che predice i bounding box 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 ogniBottleneckinterno —n + 2mappe di caratteristiche — prima della sua convoluzione di fusione, laddove il precedenteC3ne passa solo 2.C3k2(YOLO11 e YOLO26) è una sottoclasse diC2fche può sostituire ciascunBottleneckcon un bloccoC3k(una variante diC3con una dimensione del kernel configurabile) quando il suo flagc3kè impostato. Entrambi sono definiti inblock.py.YOLO11 apporta tre modifiche strutturali a YOLOv8: sostituisce il blocco backbone e neck
C2fconC3k2, inserisce un blocco di auto-attenzioneC2PSAdopoSPPFe passa il ramo di classificazione della head a convoluzioni separabili in profondità più leggere. Entrambi mantengono la stessa headDetectsenza ancore e disaccoppiata con regressione DFLreg_max=16, in modo che le modifiche riducano il conteggio dei parametri e dei FLOPs aumentando al contempo la precisione anziché riprogettare l'interfaccia di rilevamento.I moderni modelli Ultralytics YOLO sono privi di ancore. YOLOv8, YOLO11 e YOLO26 utilizzano una head
Detectpriva di ancore e disaccoppiata con rami separati per la regressione dei box e la classificazione. Gli originali YOLOv3 e YOLOv5 erano basati su ancore, ma Ultralytics li distribuisce come le varianti YOLOv3u e YOLOv5u, le cui configurazioni utilizzano la stessa head senza ancore di YOLOv8.Sì — YOLO26 imposta
end2end=True, il che dotaDetectdi una head uno-a-uno che produce una singola predizione per oggetto e rimuove la fase di post-elaborazione Non-Maximum Suppression richiesta dai modelli precedenti. Consulta la Guida al rilevamento end-to-end per i dettagli.Il DFL esegue la regressione di ciascuna coordinata del box come una distribuzione softmax su
reg_maxbin (16 per impostazione predefinita in YOLOv8 e YOLO11) e assume il valore atteso come coordinata, anziché predire un singolo scalare. YOLO26 impostareg_max=1, in modo che il layer DFL diventi un'operazione di identità, la head esegua la regressione delle coordinate direttamente e nessuna operazione DFL appaia nei grafi ONNX o TensorRT esportati.Carica il modello in Python e chiama
model.info()per ottenere un riepilogo del layer, dei parametri e dei GFLOPs. I layer analizzati si trovano inmodel.model.model— ad esempio,model.model.model[-1]è la headDetect, che espone attributi comereg_maxeend2end. L'intera architettura è definita nel file di configurazione YAML del modello.