Arquitetura do YOLO explicada: do YOLOv3 ao YOLO26#
Todos os modelos YOLO da Ultralytics são construídos em três etapas: um backbone que extrai características, um neck que as funde entre escalas e uma head que prevê caixas e classes. Este guia documenta os módulos que compõem cada etapa e como mudaram do YOLOv3 ao YOLO26, associando cada componente à sua definição nos ficheiros de configuração em ultralytics/cfg/models/ e às classes de módulos em ultralytics/nn/modules/.
Cada modelo é definido declarativamente num ficheiro YAML como uma lista ordenada de camadas, em que cada camada segue o formato [from, repeats, module, args]: que camada(s) a alimentam, quantas vezes o módulo se repete, a classe da camada (Conv, C3k2, SPPF, Detect, …) e os argumentos do seu construtor. O Model YAML Configuration Guide documenta este formato — incluindo a forma como repeats e args escalam com os múltiplos de profundidade e largura da variante — bem como todo o sistema de resolução de módulos. Este guia centra-se nos próprios módulos e na forma como mudaram de versão para versão.
As três etapas#
Todos os modelos YOLO da Ultralytics encaminham a imagem através de três etapas sequenciais, cada uma com uma função distinta:
| Etapa | Função | Saída |
|---|---|---|
| Backbone | Extrair características da imagem de entrada em várias resoluções | Mapas de características com strides de 8, 16 e 32 (P3, P4 e P5) |
| Neck | Fundir características entre escalas para que objetos pequenos e grandes tenham contexto | Mapas de características fundidos em várias escalas |
| Head | Prever caixas delimitadoras e pontuações de classe a partir das características fundidas | Deteções por ponto de ancoragem |
A unidade fundamental é o bloco Conv (definido em conv.py): uma convolução 2D, normalização de batch e uma ativação SiLU, aplicadas em sequência. Cada módulo maior abaixo é construído compondo blocos Conv.
Diagramas da arquitetura#
Cada versão mantém o mesmo esqueleto backbone → neck → head e altera etapas específicas. Os separadores abaixo mostram a estrutura de cada versão: as etapas do backbone e do neck seguem as configurações em ultralytics/cfg/models/, enquanto as heads do YOLOv3 e do YOLOv5 são apresentadas na sua forma original baseada em âncoras, em vez da head da variante u sem âncoras que as configurações dos respetivos pacotes realmente incluem. Percorrer os separadores mostra o que cada geração acrescentou. Em resumo, a progressão é: o YOLOv3 é um detetor baseado em âncoras e apenas com FPN; o YOLOv5 acrescenta o caminho PAN ascendente e SPPF; o YOLOv8 muda para o bloco C2f com uma head sem âncoras e DFL; o YOLO11 insere a atenção C2PSA e o bloco C3k2; e o YOLO26 acrescenta um residual SPPF e torna a head livre de NMS e de DFL. As cores dos nós seguem a convenção dos diagramas da documentação: entrada verde, backbone azul, pooling espacial e atenção em ardósia, neck laranja, head e saída roxas.
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:#fffOs diagramas do YOLOv3 e do YOLOv5 mostram a head original baseada em âncoras. O pacote ultralytics inclui as configurações sem âncoras YOLOv3u e YOLOv5u — os mesmos backbones Darknet-53 e C3, com a head Detect do YOLOv8 — descritas em Detection Head.
Blocos do backbone: Bottleneck → C3 → C2f → C3k2#
O backbone empilha um bloco CSP (parcial entre estágios) repetido entre camadas de redução de amostragem Conv com stride 2. Esse bloco repetido foi o elemento que mais mudou entre versões. Todos os blocos abaixo estão em block.py; c1/c2 são os canais de entrada/saída e c = 0.5 * c2 é a largura oculta.
Bottleneck (YOLOv3)#
A unidade base é Bottleneck: duas camadas Conv (kernels predefinidos (3, 3)) com uma soma residual opcional quando shortcut=True e c1 == c2. O backbone Darknet-53 do YOLOv3 empilha-as diretamente, sem divisão CSP, e deteta em três escalas (strides 8, 16 e 32).
C3 (YOLOv5)#
O C3 do YOLOv5 divide a entrada entre duas convoluções 1x1: cv1 alimenta n blocos Bottleneck sequenciais (kernels (1, 1) e depois (3, 3)), enquanto cv2 os contorna. Os dois caminhos são concatenados e fundidos por uma terceira 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))Apenas a saída do bottleneck final chega à convolução de fusão, pelo que cv3 recebe 2 mapas de características.
C2f (YOLOv8)#
O C2f do YOLOv8 ("CSP Bottleneck with 2 convolutions, faster") altera quais características chegam à convolução de fusão:
cv1 = Conv(c1, 2 * c, 1), e depoischunk(2), divide a saída em dois tensores comccanais.- Os blocos
nBottleneck(c, c)(kernels(3, 3),(3, 3)) são executados sequencialmente, cada um recebendo a saída do bloco anterior. - Todos os tensores intermédios
n + 2são concatenados e fundidos porcv2 = Conv((2 + n) * c, c2, 1).
Enquanto C3 passa 2 mapas de características para a sua convolução de fusão, C2f passa n + 2 — todas as saídas intermédias dos bottlenecks são reutilizadas.
C3k2 (YOLO11 e YOLO26)#
YOLO11 e YOLO26 usam C3k2, uma subclasse de C2f que substitui a unidade repetida. Cada um dos n blocos torna-se, dependendo dos sinalizadores do construtor:
- um
Bottlenecksimples (predefinido,c3k=False), - um bloco
C3k(c3k=True) — uma varianteC3com tamanho de kernel configurável, ou - um par
Bottleneck+PSABlock(attn=True).
O segundo argumento YAML define c3k, a menos que a escala seja m, l ou x, que a forçam para True — é assim que um yolo11.yaml serve todas as cinco variantes. Assim, [-1, 2, C3k2, [512, False]] constrói componentes internos Bottleneck em n e s, mas componentes internos C3k em m, l e x; 512 é a contagem de canais antes da escala, que o múltiplo de largura da variante transforma em 128 em n e em 768 em x. Para módulos CSP, o campo repeats — aqui 2, antes de ser escalado pelo múltiplo de profundidade da variante — torna-se a contagem de repetições internas do bloco, em vez de empilhar módulos separados.
Pooling espacial: SPP → SPPF#
No fim do backbone, um bloco de pooling espacial em pirâmide alarga o campo recetivo. O YOLOv5 substituiu o SPP original de vários kernels por SPPF (Spatial Pyramid Pooling - Fast): um único MaxPool2d(kernel_size=5, stride=1, padding=2) aplicado n = 3 vezes em sequência, com a entrada e as três saídas do pooling concatenadas e fundidas por uma 1x1 Conv. Isto é matematicamente equivalente a SPP(k=(5, 9, 13)), mas mais barato, porque os poolings encadeados 5x5 cobrem os campos recetivos dos kernels maiores.
O YOLO26 passa um sinalizador de atalho (SPPF, [1024, 5, 3, True]); como c1 == c2 == 1024 está na camada mais profunda, SPPF adiciona uma ligação residual (return y + x).
Atenção espacial: C2PSA (YOLO11+)#
O YOLO11 adicionou C2PSA depois de SPPF. É um bloco CSP cujo ramo ativo é uma pilha de módulos n PSABlock (Position-Sensitive Attention): cv1 = Conv(c1, 2 * c, 1) divide as características, metade passa pela pilha PSABlock e cv2 = Conv(2 * c, c1, 1) funde a concatenação. Cada PSABlock aplica atenção multi-head seguida de uma rede feed-forward de duas camadas (Conv(c, 2 * c, 1) → Conv(2 * c, c, 1)), cada uma com uma ligação residual. O YOLO26 mantém o mesmo backbone C3k2 + C2PSA.
Neck: FPN + PAN#
O neck funde os mapas de características P3/P4/P5 do backbone com uma Feature Pyramid Network (FPN) descendente, seguida de uma Path Aggregation Network (PAN) ascendente. Na secção head do YAML, FPN é nn.Upsample + Concat (transportando informação semântica para resoluções mais elevadas) e PAN é Conv + Concat com stride 2 (transportando informação de localização de volta para cima):
# 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]] # 19O neck reutiliza o bloco do backbone da sua geração — C3 no YOLOv5, C2f no YOLOv8, C3k2 no YOLO11 e no YOLO26 — pelo que cada ponto de fusão executa o mesmo módulo usado pelo backbone. As três saídas fundidas alimentam a head. O YOLOv3 é a exceção: o seu neck é apenas uma FPN descendente (a sua head YAML não tem redução de amostragem com stride 2), sem o caminho PAN ascendente introduzido pelo YOLOv5.
Head de deteção: baseada em âncoras → sem âncoras → sem NMS#
A head transforma os três mapas de características fundidos em previsões para a tarefa de deteção. O seu design mudou entre versões, de baseado em âncoras para sem âncoras e, depois, sem NMS.
Detect sem âncoras e desacoplada#
O YOLOv3 e o YOLOv5 originais usavam uma head baseada em âncoras e acoplada: caixas de âncora predefinidas e um ramo partilhado para as previsões de caixas e classes. Os repositórios autónomos ultralytics/yolov3 e ultralytics/yolov5 mantêm esse design baseado em âncoras. Em vez disso, o pacote principal ultralytics inclui as variantes sem âncoras YOLOv3u e YOLOv5u — os mesmos backbones Darknet-53 e C3 com a head Detect sem âncoras do YOLOv8 — e as configurações yolov3.yaml e yolov5.yaml documentadas aqui são estas variantes u, não o design histórico.
A head Detect (head.py) é sem âncoras e desacoplada: em cada nível da pirâmide, executa dois ramos paralelos e prevê diretamente em pontos da grelha, em vez de o fazer relativamente a caixas de âncora.
- Ramo de caixas (
cv2):Conv(x, c2, 3)→Conv(c2, c2, 3)→Conv2d(c2, 4 * reg_max, 1). - Ramo de classes (
cv3): no YOLO11 e no YOLO26, dois blocos separáveis em profundidade (DWConv+1x1 Conv) →Conv2d(c3, nc, 1); o YOLOv8 usa a variante legada, duas camadas3x3 Conv→Conv2d(c3, nc, 1).
Assim, cada ponto de ancoragem emite no = nc + 4 * reg_max saídas. A remoção das âncoras predefinidas elimina dos hiperparâmetros a ajustar os tamanhos e as proporções das caixas de âncora.
Distribution Focal Loss (DFL)#
O YOLOv8 e o YOLO11 regridem cada uma das 4 coordenadas da caixa como uma distribuição sobre reg_max = 16 bins, em vez de um único escalar (a forma integral de Generalized Focal Loss). O módulo DFL remodela os canais de caixa 4 * reg_max para (4, reg_max), aplica uma softmax sobre os reg_max bins e usa o índice esperado do bin — cada índice de bin ponderado pela sua probabilidade softmax e depois somado — como coordenada prevista. Isto é implementado como uma convolução fixa 1x1, cujos pesos são os índices dos bins arange(reg_max), pelo que a soma ponderada é um único produto escalar.
YOLO26: sem NMS e sem DFL#
O YOLO26 define dois parâmetros YAML que a head lê diretamente:
end2end: True—Detectfaz uma cópia profunda dos seus ramos para uma head um-para-um (one2one_cv2/one2one_cv3) que produz uma única previsão por objeto, removendo a etapa de pós-processamento Non-Maximum Suppression (NMS). Consulta o End-to-End Detection guide para obter detalhes sobre exportação e migração.reg_max: 1— com um bin,self.dfltorna-senn.Identity()eno = nc + 4; a head regride diretamente as coordenadas e nenhuma operação DFL aparece no grafo ONNX exportado.
Entre os seus cinco tamanhos de modelo (n/s/m/l/x), o YOLO26 alcança 40.9–57.5 mAP no COCO, com uma latência de 1.7–11.8 ms no T4 TensorRT, conforme reportado no artigo do YOLO26.
Resumo versão a versão#
| Versão | Bloco do backbone | Pooling espacial | Atenção | Head de deteção | DFL |
|---|---|---|---|---|---|
| YOLOv3 | Darknet-53 (Bottleneck) | nenhum na configuração base | nenhuma | Original: baseada em âncoras; variante u: sem âncoras | não / sim (u) |
| YOLOv5 | C3 (CSP) | SPPF | nenhuma | Original: baseada em âncoras; variante u: sem âncoras | não / sim (u) |
| YOLOv8 | C2f | SPPF | nenhuma | Sem âncoras, desacoplada | sim (reg_max=16) |
| YOLO11 | C3k2 | SPPF | C2PSA | Sem âncoras, desacoplada | sim (reg_max=16) |
| YOLO26 | C3k2 | SPPF + atalho | C2PSA | Sem âncoras, sem NMS (end2end) | removida (reg_max=1) |
Para obter detalhes por modelo, tabelas de desempenho e exemplos de utilização, consulta as páginas individuais do YOLOv3, YOLOv5, YOLOv8, YOLO11 e YOLO26.
Inspeciona a arquitetura por ti mesmo#
O método model.info() imprime um resumo das camadas, dos parâmetros e de FLOPs, e a lista de módulos analisada está disponível em 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)Executar o snippet nas três gerações mostra numericamente as alterações. Estas são saídas reais de modelos fundidos do pacote ultralytics, correspondentes às contagens de parâmetros e FLOPs publicadas em cada página de modelo:
| Modelo | Camadas | Parâmetros | GFLOPs | reg_max | end2end | Camada 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.5 | 1 | True | Identity |
O YOLO26n apresenta reg_max=1, end2end=True e uma camada DFL Identity — a assinatura arquitetural da sua head sem NMS e sem DFL.
Os valores de parâmetros e FLOPs são reportados para o modelo fundido (model.fuse()), que combina cada Conv com a sua camada de normalização de batch. Isto corresponde às especificações publicadas; um checkpoint carregado recentemente apresenta contagens ligeiramente superiores antes da fusão.
Conclusão#
Entre versões, a arquitetura YOLO mudou uma etapa de cada vez: o backbone passou de Darknet-53 para blocos C3, C2f e C3k2 baseados em CSP, com atenção C2PSA; o neck manteve a sua estrutura FPN + PAN, enquanto SPP se tornou SPPF; e a head passou de baseada em âncoras para sem âncoras e, depois, para o design end-to-end do YOLO26, sem NMS e sem DFL.
Para definir arquiteturas personalizadas, consulta o Model YAML Configuration Guide ou compara modelos nas páginas de modelos. Para esclarecer dúvidas, contacta-nos no GitHub ou no Discord.
Perguntas frequentes#
Um modelo YOLO tem um backbone que extrai características da imagem com strides de 8, 16 e 32, um neck que funde essas características entre escalas com FPN e PAN, e uma head que prevê caixas delimitadoras e pontuações de classe. Todos os modelos YOLO da Ultralytics, do YOLOv3 ao YOLO26, seguem este design de três etapas.
C2f(YOLOv8) é um bloco CSP que concatena as saídas de todos os mapas de características internosBottleneck—n + 2— antes da sua convolução de fusão, enquanto oC3mais antigo transmite apenas 2.C3k2(YOLO11 e YOLO26) é uma subclasse deC2fque pode substituir cadaBottleneckpor um blocoC3k(uma variante deC3com tamanho de kernel configurável) quando o seu sinalizadorc3kestá definido. Ambos são definidos emblock.py.YOLO11 faz três alterações estruturais ao YOLOv8: substitui o bloco de backbone e neck
C2fporC3k2, insere um bloco de autoatençãoC2PSAapósSPPFe muda o ramo de classificação da cabeça para convoluções separáveis em profundidade mais leves. Ambos mantêm a mesma cabeçaDetectsem âncoras e desacoplada, com regressão DFLreg_max=16, por isso as alterações reduzem a quantidade de parâmetros e de FLOPs e aumentam a precisão, em vez de reformularem a interface de detecção.Os modelos YOLO modernos da Ultralytics não usam âncoras. YOLOv8, YOLO11 e YOLO26 usam uma cabeça
Detectdesacoplada e sem âncoras, com ramos separados para regressão de caixas e classificação. O YOLOv3 e o YOLOv5 originais usavam âncoras, mas a Ultralytics disponibiliza-os como as variantes YOLOv3u e YOLOv5u, cujas configurações usam a mesma cabeça sem âncoras do YOLOv8.Sim — YOLO26 define
end2end=True, o que fornece aDetectuma cabeça um-para-um que produz uma única previsão por objeto e elimina a etapa de pós-processamento de supressão não máxima exigida pelos modelos anteriores. Consulta o guia de deteção de ponta a ponta para obter mais detalhes.A DFL faz a regressão de cada coordenada da caixa como uma distribuição softmax sobre
reg_maxintervalos (16 por predefinição no YOLOv8 e no YOLO11) e usa o valor esperado como coordenada, em vez de prever um único escalar. O YOLO26 definereg_max=1, fazendo com que a camada DFL se torne uma operação identidade, a cabeça faça a regressão direta das coordenadas e nenhuma operação DFL apareça nos grafos ONNX ou TensorRT exportados.Carrega o modelo em Python e chama
model.info()para obter um resumo das camadas, dos parâmetros e dos GFLOPs. As camadas analisadas encontram-se emmodel.model.model— por exemplo,model.model.model[-1]é a cabeçaDetect, que expõe atributos comoreg_maxeend2end. A arquitetura completa é definida no ficheiro de configuração YAML do modelo.