YOLO Vision 2026:

YOLO 架构解析:从 YOLOv3 到 YOLO26#

每个 Ultralytics YOLO 模型都由三个阶段构成:用于提取特征的 主干网络、用于跨尺度融合特征的 颈部网络,以及用于预测框和类别的 检测头。本指南介绍组成各阶段的模块,以及它们从 YOLOv3YOLO26 的变化,并将每个组件追溯到 ultralytics/cfg/models/ 下配置文件中的定义和 ultralytics/nn/modules/ 中的模块类。

每个模型都在 YAML 文件中以有序层列表的形式声明,其中每一层都遵循 [from, repeats, module, args] 格式:由哪些层提供输入、模块重复多少次、层类别(ConvC3k2SPPFDetect,……)以及构造函数参数。模型 YAML 配置指南详细介绍了这种格式,包括 repeatsargs 如何随模型变体的深度和宽度倍数进行缩放,以及完整的模块解析系统。本指南重点介绍模块本身,以及它们在不同版本中的变化。

三个阶段#

每个 Ultralytics YOLO 模型都会将图像依次经过三个阶段,每个阶段承担不同的任务:

阶段任务输出
主干网络以多种分辨率从输入图像中提取特征步长为 8、16 和 32 的特征图(P3、P4、P5)
颈部网络跨尺度融合特征,使小目标和大目标都能获得上下文信息多尺度融合特征图
检测头根据融合特征预测边界框和类别分数每个锚点的检测结果

基本单元是 Conv 模块(定义于 conv.py):依次执行二维卷积、批归一化SiLU 激活。下面的每个更大模块都通过组合 Conv 模块构建。

架构图#

每个版本都保留相同的 主干网络 → 颈部网络 → 检测头 骨架,并对特定阶段进行调整。下面的选项卡展示各版本的结构:主干网络和颈部网络阶段遵循 ultralytics/cfg/models/ 中的配置,而 YOLOv3 和 YOLOv5 的检测头则以原始的基于锚框形式绘制,而不是其软件包配置实际提供的无锚框 u-变体检测头。依次查看各选项卡,可以了解每一代新增的内容。简而言之,演进过程如下:YOLOv3 是仅使用 FPN 的基于锚框检测器;YOLOv5 增加自底向上的 PAN 路径和 SPPF;YOLOv8 切换到 C2f 模块,并采用带 DFL 检测头的无锚框设计;YOLO11 加入 C2PSA 注意力机制和 C3k2 模块;YOLO26 增加 SPPF 残差,并使检测头无需 NMS 且无需 DFL。节点颜色遵循文档图示约定:绿色表示输入,蓝色表示主干网络,石板色表示空间池化和注意力,橙色表示颈部网络,紫色表示检测头和输出。

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

YOLOv3 和 YOLOv5 图示展示了原始的基于锚框检测头。ultralytics 软件包提供无锚框的 YOLOv3uYOLOv5u 配置——使用相同的 Darknet-53 和 C3 主干网络,但采用 YOLOv8 的 Detect 检测头——详见检测头

主干网络模块:Bottleneck → C3 → C2f → C3k2#

主干网络在步长为 2 的 Conv 下采样层之间堆叠重复的 CSP(跨阶段部分)模块。这个重复模块是各版本变化最大的部分。下面的所有模块都位于 block.py 中;c1/c2 表示输入/输出通道,c = 0.5 * c2 表示隐藏宽度。

Bottleneck(YOLOv3)#

基本单元是 Bottleneck:包含两个 Conv 层(默认内核为 (3, 3)),并在 shortcut=Truec1 == c2 时可选地执行残差相加。YOLOv3Darknet-53 主干网络直接堆叠这些单元,不使用 CSP 分支,并在三个尺度上进行检测(步长为 8、16、32)。

C3(YOLOv5)#

YOLOv5C3 将输入分到两个 1x1 卷积中:cv1 依次经过 nBottleneck 模块(内核先为 (1, 1),再为 (3, 3)),而 cv2 绕过这些模块。两条路径进行拼接,并由第三个 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))

只有 最后一个 Bottleneck 输出会进入融合卷积,因此 cv3 接收 2 个特征图。

C2f(YOLOv8)#

YOLOv8C2f(“具有 2 个卷积且速度更快的 CSP Bottleneck”)改变了到达融合卷积的特征:

  1. cv1 = Conv(c1, 2 * c, 1) 随后由 chunk(2) 将输出拆分为两个 c 通道的张量。
  2. nBottleneck(c, c) 模块(内核为 (3, 3)(3, 3))依次运行,每个模块都接收前一个模块的输出。
  3. 所有 n + 2 中间张量都会进行拼接,并由 cv2 = Conv((2 + n) * c, c2, 1) 融合。

C3 将 2 个特征图传入其融合卷积,而 C2f 传入 n + 2 个——每个中间 Bottleneck 输出都会被重新利用。

C3k2(YOLO11 和 YOLO26)#

YOLO11YOLO26 使用 C3k2,它是 C2f 的子类,会替换重复单元。根据构造函数标志,每个 n 模块会变为:

  • 普通的 Bottleneck(默认值,c3k=False),
  • 一个 C3k 模块(c3k=True)——一种内核大小可配置的 C3 变体,或
  • 一个 Bottleneck + PSABlock 对(attn=True)。

第二个 YAML 参数会设置 c3k,除非尺度为 mlx,这些尺度会强制将其设为 True——这就是一个 yolo11.yaml 如何服务全部五种变体的方式。因此,[-1, 2, C3k2, [512, False]] 会在 ns 构建包含 Bottleneck 内部模块的结构,但在 mlx 构建包含 C3k 内部模块的结构;512 是缩放前的通道数,变体的宽度倍数会将其转换为 n 中的 128 和 x 中的 768。对于 CSP 模块,repeats 字段(此处为 2,在按变体的深度倍数缩放之前)会成为模块内部的重复次数,而不是堆叠独立模块。

空间池化:SPP → SPPF#

在主干网络末端,空间金字塔池化模块会扩大感受野。YOLOv5 将原始的多内核 SPP 替换为 SPPF(空间金字塔池化 - 快速):依次应用 n = 3 次单个 MaxPool2d(kernel_size=5, stride=1, padding=2),然后将输入和全部三个池化输出拼接,并由 1x1 Conv 进行融合。从数学上看,这等价于 SPP(k=(5, 9, 13)),但计算成本更低,因为链式的 5x5 池化覆盖了更大内核的感受野。

YOLO26 传入一个快捷连接标志(SPPF, [1024, 5, 3, True]);由于最深层为 c1 == c2 == 1024SPPF 会添加残差连接(return y + x)。

空间注意力:C2PSA(YOLO11+)#

YOLO11SPPF 之后添加了 C2PSA。这是一个 CSP 模块,其有效分支由一组 nPSABlock(位置敏感注意力)模块组成:cv1 = Conv(c1, 2 * c, 1) 将特征拆分,其中一半经过 PSABlock 堆栈,cv2 = Conv(2 * c, c1, 1) 再融合拼接结果。每个 PSABlock 都会应用多头注意力,随后经过两层前馈网络(Conv(c, 2 * c, 1)Conv(2 * c, c, 1)),二者都带有残差连接。YOLO26 保留相同的 C3k2 + C2PSA 主干网络。

颈部网络:FPN + PAN#

颈部网络使用自顶向下的特征金字塔网络(FPN),再结合自底向上的路径聚合网络(PAN),融合主干网络的 P3/P4/P5 特征图。在 YAML 检测头部分,FPN 是 nn.Upsample + Concat(将语义信息向下传递到更高分辨率),PAN 是步长为 2 的 Conv + Concat(将定位信息向上传递):

# 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

颈部网络会复用其所属版本的主干网络模块——YOLOv5 中为 C3,YOLOv8 中为 C2f,YOLO11 和 YOLO26 中为 C3k2——因此每个融合点都运行主干网络所使用的相同模块。三个融合输出会传入检测头。YOLOv3 是例外:其颈部网络仅包含自顶向下的 FPN(其 YAML 检测头没有步长为 2 的下采样),不具备 YOLOv5 引入的自底向上 PAN 路径。

检测头:基于锚框 → 无锚框 → 无 NMS#

检测头将三个融合特征图转换为检测任务的预测结果。其设计经历了从基于锚框到无锚框,再到无需 NMS 的变化。

无锚框、解耦的 Detect#

原始 YOLOv3 和 YOLOv5 使用基于锚框的耦合检测头:预定义锚框,以及用于框和类别预测的共享分支。独立的 ultralytics/yolov3ultralytics/yolov5 代码仓库保留了这种基于锚框的设计。主 ultralytics 软件包则提供无锚框的 YOLOv3uYOLOv5u 变体——使用相同的 Darknet-53 和 C3 主干网络,以及 YOLOv8 的无锚框 Detect 检测头——本文介绍的 yolov3.yamlyolov5.yaml 配置就是这些 u 变体,而不是历史设计。

Detect 检测头(head.py)采用无锚框、解耦设计:在每个金字塔层运行两个并行分支,并直接在网格点上进行预测,而不是针对锚框进行预测。

  • 框分支(cv2): Conv(x, c2, 3)Conv(c2, c2, 3)Conv2d(c2, 4 * reg_max, 1)
  • 类别分支(cv3): 在 YOLO11 和 YOLO26 中,两个深度可分离模块(DWConv + 1x1 Conv)→ Conv2d(c3, nc, 1);YOLOv8 使用旧版变体,即两个 3x3 Conv 层 → Conv2d(c3, nc, 1)

因此,每个锚点都会输出 no = nc + 4 * reg_max 个结果。移除预定义锚框后,就无需再调优超参数中的锚框尺寸和宽高比。

分布焦点损失(DFL)#

YOLOv8 和 YOLO11 将 4 个框坐标中的每一个回归为在 reg_max = 16 个区间上的分布,而不是单个标量(来自广义焦点损失的积分形式)。DFL 模块将 4 * reg_max 个框通道重塑为 (4, reg_max),在 reg_max 个区间上应用 softmax,并取期望区间索引作为预测坐标——即用每个区间的 softmax 概率加权其索引,再求和。该过程通过固定的 1x1 卷积实现,其权重为区间索引 arange(reg_max),因此加权和就是一次点积。

YOLO26:无需 NMS、无需 DFL#

YOLO26 设置了两个由检测头直接读取的 YAML 参数:

  • end2end: True —— Detect 将其分支深复制到一对一检测头(one2one_cv2/one2one_cv3),为每个目标生成一个预测结果,从而移除非极大值抑制(NMS)后处理步骤。有关导出和迁移详情,请参阅端到端检测指南
  • reg_max: 1 —— 当区间数为 1 时,self.dfl 会变为 nn.Identity()no = nc + 4;检测头直接回归坐标,导出的 ONNX 图中不会出现 DFL 操作。

在五种模型尺寸(n/s/m/l/x)中,YOLO26 在 COCO 上达到 40.9–57.5 mAP,T4 TensorRT 延迟为 1.7–11.8 ms,数据来自 YOLO26 论文

逐版本总结#

版本主干网络模块空间池化注意力检测头DFL
YOLOv3Darknet-53(Bottleneck基础配置中无原始版本:基于锚框;u 变体:无锚框否 / 是(u
YOLOv5C3(CSP)SPPF原始版本:基于锚框;u 变体:无锚框否 / 是(u
YOLOv8C2fSPPF无锚框、解耦是(reg_max=16
YOLO11C3k2SPPFC2PSA无锚框、解耦是(reg_max=16
YOLO26C3k2SPPF + 快捷连接C2PSA无锚框、无需 NMSend2end已移除reg_max=1

有关每个模型的详细信息、性能表和使用示例,请参阅 YOLOv3YOLOv5YOLOv8YOLO11YOLO26 的单独页面。

自行检查架构#

model.info() 方法会打印层、参数和 FLOPs 摘要,解析后的模块列表可在 model.model.model 上获取。

检查 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)

在三代模型上运行这段代码,可以用数值展示这些变化。这些是来自 ultralytics 软件包的真实融合模型输出,与各个模型页面公布的参数量和 FLOPs 数量一致:

模型层数参数量GFLOPsreg_maxend2endDFL 层
YOLOv8n723,151,9048.716FalseDFL
YOLO11n1002,616,2486.516FalseDFL
YOLO26n1222,408,9325.51TrueIdentity

YOLO26n 报告包含 reg_max=1end2end=True 和一个 Identity DFL 层——这正是其无需 NMS、无需 DFL 检测头的架构特征。

融合与未融合的数量

参数量和 FLOPs 值针对融合模型(model.fuse())报告,该模型会合并每个 Conv 及其批归一化层。这与公布的规格一致;新加载的检查点在融合前会报告略高的数量。

结论#

在不同版本中,YOLO 架构逐个阶段发生变化:主干网络从 Darknet-53 转变为基于 CSP 的 C3C2fC3k2 模块,并加入 C2PSA 注意力;颈部网络保留 FPN + PAN 结构,同时 SPP 变为 SPPF;检测头则从基于锚框转为无锚框,最终发展为 YOLO26 无 NMS、无 DFL 的端到端设计。

要定义自定义架构,请参阅模型 YAML 配置指南,或在模型页面上比较模型。如有疑问,请通过 GitHubDiscord 联系我们。

常见问题#

  • YOLO 模型包含一个主干网络,以步长 8、16 和 32 从图像中提取特征;一个颈部网络,通过 FPN 和 PAN 跨尺度融合这些特征;以及一个检测头,用于预测边界框和类别分数。从 YOLOv3 到 YOLO26,每个 Ultralytics YOLO 模型都遵循这一三阶段设计。

  • C2f(YOLOv8)是一个 CSP 模块,在融合卷积之前连接每个内部 Bottleneckn + 2 特征图的输出,而较早的 C3 只传递 2 个。C3k2(YOLO11 和 YOLO26)是 C2f 的子类,当其 c3k 标志设置后,可以将每个 Bottleneck 替换为 C3k 模块(可配置内核大小的 C3 变体)。两者都定义在 block.py 中。

  • YOLO11 对 YOLOv8 进行了三项结构性改动:将 C2f 主干网络和颈部模块替换为 C3k2,在 SPPF 后插入 C2PSA 自注意力模块,并将检测头的分类分支切换为更轻量的深度可分离卷积。两者都保留了相同的无锚框、解耦式 Detect 检测头和 reg_max=16 DFL 回归,因此这些改动降低了参数量和 FLOPs,同时提高了准确率,而不是重新设计检测接口。

  • 现代 Ultralytics YOLO 模型都是无锚框的。YOLOv8、YOLO11 和 YOLO26 使用无锚框、解耦式 Detect 检测头,为边界框回归和分类分别设置分支。最初的 YOLOv3 和 YOLOv5 基于锚框,但 Ultralytics 以 YOLOv3uYOLOv5u 变体提供它们,这些变体的配置使用与 YOLOv8 相同的无锚框检测头。

  • 是的 — YOLO26 设置了 end2end=True,使 Detect 使用一对一检测头,为每个目标生成单个预测,并移除了早期模型所需的非极大值抑制后处理步骤。详情请参阅端到端检测指南

  • DFL 将每个边界框坐标回归为在 reg_max 个区间上的 softmax 分布(YOLOv8 和 YOLO11 中默认为 16 个),并将期望值作为坐标,而不是预测单个标量。YOLO26 设置了 reg_max=1,因此 DFL 层变为恒等运算,检测头直接回归坐标,并且导出的 ONNX 或 TensorRT 图中不会出现 DFL 运算。

  • 在 Python 中加载模型,并调用 model.info() 以获取层、参数和 GFLOPs 摘要。解析后的层位于 model.model.model 中 — 例如,model.model.model[-1]Detect 检测头,会公开 reg_maxend2end 等属性。完整架构定义在模型的 YAML 配置文件 中。

贡献者

评论