Ultralytics YOLO27:
Get Started

YOLO 架构详解:从 YOLOv3 到 YOLO26#

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

每个模型都以声明式方式定义在 YAML 文件中,文件由按顺序排列的层组成;每层都遵循 [from, repeats, module, args] 格式:输入来自哪些层、模块重复多少次、层类(Conv、C3k2、SPPF、Detect,……),以及构造函数参数。模型 YAML 配置指南详细介绍了这种格式,包括 repeats 和 args 如何随变体的深度和宽度倍数缩放,以及完整的模块解析系统。本指南聚焦于模块本身,以及它们在不同版本间的变化。

三个阶段#

每个 Ultralytics YOLO 模型都会依次将图像送入三个阶段,每个阶段各司其职:

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

基本单元是 Conv 块(定义于 conv.py:由 2D 卷积、批归一化和 SiLU 激活依次组成。下文中的每个更大型模块都由多个 Conv 块组合而成。

架构图#

每个版本都保留相同的 backbone → neck → head 骨架,只调整特定阶段。下方的选项卡展示了各版本的结构:backbone 和 neck 阶段遵循 ultralytics/cfg/models/ 中的配置,而 YOLOv3 和 YOLOv5 的 head 则以原始的基于锚框形式绘制,而非其软件包配置实际采用的无锚框 u 变体 head。逐个查看选项卡,可以了解每一代新增的内容。简而言之,演进过程如下:YOLOv3 是仅使用 FPN、基于锚框的检测器;YOLOv5 增加了自底向上的 PAN 路径和 SPPF;YOLOv8 切换到 C2f 模块,并采用无锚框的 DFL head;YOLO11 加入了 C2PSA 注意力机制和 C3k2 模块;YOLO26 则增加了 SPPF 残差结构、移除 DFL,并加入可选的无 NMS head。

YOLOv3 和 YOLOv5 的图示展示了原始的基于锚框检测头。ultralytics 软件包提供无锚框的 YOLOv3u 和 YOLOv5u 配置:它们采用相同的 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=True 和 c1 == c2 时可选地执行残差相加。YOLOv3 的 Darknet-53 主干网络直接堆叠这些单元,不进行 CSP 分支,并在三个尺度(步长为 8、16、32)上进行检测。

C3(YOLOv5)#

YOLOv5 的 C3 将输入拆分后分别送入两个 1x1 卷积:cv1 依次经过 n 个 Bottleneck 模块(卷积核依次为 (1, 1) 和 (3, 3)),cv2 则绕过这些模块。两条路径拼接后,由第三个 1x1 Conv 卷积进行融合:

def forward(self, x):
    # C3:瓶颈路径 m(cv1(x)) 与旁路 cv2(x) 拼接,然后由 cv3 融合
    return self.cv3(torch.cat((self.m(self.cv1(x)), self.cv2(x)), 1))

只有最后一个瓶颈输出会到达融合卷积,因此 cv3 会接收 2 个特征图。

C2f(YOLOv8)#

YOLOv8 的 C2f(“带两个卷积的 CSP Bottleneck,更快”)改变了到达融合卷积的特征:

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

C3 将 2 个特征图传入融合卷积,而 C2f 会传入 n + 2 个特征图,也就是重复利用每个中间瓶颈输出。

C3k2(YOLO11 和 YOLO26)#

YOLO11 和 YOLO26 使用 C3k2,这是 C2f 的子类,会替换重复单元。根据构造函数标志,每个 n 模块会变成以下其中一种:

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

第二个 YAML 参数会设置 c3k,但当缩放级别为 m、l 或 x 时,会强制设为 True——这就是一个 yolo11.yaml 如何适配所有五种变体的方式。因此,[-1, 2, C3k2, [512, False]] 在 n 和 s 处构建 Bottleneck 内部模块,而在 m、l 和 x 处构建 C3k 内部模块;512 是缩放前的通道数,经过变体的宽度倍数缩放后,在 n 处变为 128,在 x 处变为 768。对于 CSP 模块,repeats 字段(此处为 2,之后还会按变体的深度倍数缩放)会成为模块内部的重复次数,而不是用于堆叠独立模块。

空间池化:SPP → SPPF#

在主干网络末端,空间金字塔池化模块会扩大感受野。YOLOv5 将原来的多卷积核 SPP 替换为 SPPF(快速空间金字塔池化):对 MaxPool2d(kernel_size=5, stride=1, padding=2) 连续应用 n = 3 次,将输入和三个池化输出拼接,再由 1x1 Conv 卷积进行融合。从数学上看,这与 SPP(k=(5, 9, 13)) 等价,但计算成本更低,因为串联的 5x5 池化覆盖了较大卷积核的感受野。

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

空间注意力:C2PSA(YOLO11 及后续版本)#

YOLO11 在 SPPF 之后加入了 C2PSA。这是一个 CSP 模块,其活动分支由一组 n 个 PSABlock(位置敏感注意力)模块构成: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)融合主干网络的 P3/P4/P5 特征图,再通过自底向上的路径聚合网络(PAN)进行融合。在 YAML 的 head 部分,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 head 没有步长为 2 的下采样),不包含 YOLOv5 引入的自底向上 PAN 路径。

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

检测头将三个融合后的特征图转换为目标检测任务的预测结果。它的设计历经多个版本,从基于锚框到无锚框,再到无需 NMS。

无锚框、解耦的 Detect#

原始的 YOLOv3 和 YOLOv5 使用基于锚框的耦合检测头:使用预定义锚框,并通过共享分支预测边界框和类别。独立的 ultralytics/yolov3 和 ultralytics/yolov5 仓库保留了这种基于锚框的设计。主 ultralytics 软件包则提供无锚框的 YOLOv3u 和 YOLOv5u 变体:它们采用相同的 Darknet-53 和 C3 主干网络,并搭配 YOLOv8 的无锚框 Detect 检测头;此处介绍的 yolov3.yaml 和 yolov5.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),使其学会为每个目标生成单个预测。此 YAML 设置会创建两个训练检测头;运行时,nms=False 会选择一对一检测头,并移除非极大值抑制(NMS)后处理步骤。推理和导出详情请参阅端到端检测指南。
  • reg_max: 1 — 当区间数为 1 时,self.dfl 会变为 nn.Identity() 和 no = nc + 4;检测头直接回归坐标,导出的 ONNX 图中不会出现 DFL 操作。

在五种模型尺寸(n/s/m/l/x)下,根据 YOLO26 论文报告,YOLO26 在 COCO 上的 mAP 为 40.9-57.5,T4 上 TensorRT 延迟为 1.7-11.8 ms。

各版本摘要#

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

各模型的详细信息、性能表格和使用示例,请参阅 YOLOv3、YOLOv5、YOLOv8、YOLO11 和 YOLO26 的独立页面。

亲自检查架构#

model.info() 方法会打印层、参数和 FLOPs 摘要,解析后的模块列表可通过 model.model.model 查看。

检查 YOLO 模型的架构
from ultralytics import YOLO

# 加载预训练模型
model = YOLO("yolo11n.pt")

# 融合 Conv + BatchNorm 层,使计数与已发布的规格一致
model.fuse()

# 打印摘要:层、参数、梯度、GFLOPs
model.info()

# 检查检测头(网络中的最后一个模块)
head = model.model.model[-1]
print(type(head).__name__, "| reg_max:", head.reg_max, "| DFL layer:", type(head.dfl).__name__)

在三个不同代际的模型上运行这段代码,可以从数值上看出变化。这些是 ultralytics 软件包生成的真实融合模型输出,与各模型页面公布的参数量和 FLOPs 数量一致:

模型层数参数量GFLOPsreg_maxDFL 层
YOLOv8n723,151,9048.716DFL
YOLO11n1002,616,2486.516DFL
YOLO26n1202,408,9325.51Identity

YOLO26n 报告的 reg_max=1,以及一个 Identity DFL 层。默认情况下,预测和验证使用带 NMS 的一对多模式;设置 nms=False 可进行无 NMS 推理。两个检测头都会参与训练。

融合与未融合模型的计数

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

结论#

在不同版本中,YOLO 架构逐步调整各个阶段:backbone 从 Darknet-53 演进为基于 CSP 的 C3、C2f 和 C3k2 模块,并加入 C2PSA 注意力机制;neck 保留了 FPN + PAN 结构,同时 SPP 演进为 SPPF;head 则从基于锚框转为无锚框,最终演进为 YOLO26 不使用 DFL 的设计,并配备可选的无 NMS 端到端 head。

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

常见问题#

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

  • C2f(YOLOv8)是一个 CSP 模块,会在融合卷积之前拼接每个内部 Bottleneck(即 n + 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 提供的是 YOLOv3u 和 YOLOv5u 变体,其配置使用与 YOLOv8 相同的无锚框检测头。

  • 是的——YOLO26 包含一个一对一检测头,支持使用 nms=False 进行无 NMS 推理。默认的一对多推理路径使用 NMS,并且两个检测头在训练期间都会接受监督。详情请参阅端到端检测指南。

  • 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_max 和 dfl 等属性。完整架构定义在模型的 YAML 配置文件中。

评论