犀牛鸟 2026 研究笔记 estelledc.github.io

第 4 章 · YOLO 家族演进——从 v1 到 v10 的革命之路

开场:智能手机的进化启示

智能手机从 2007 年初代 iPhone 到今天,核心体验(打电话、上网、拍照)没有变,但每一代都在某个关键点上做出突破:iPhone 4 引入视网膜屏幕,iPhone 5s 引入指纹识别,iPhone X 引入 Face ID……每一代的改进看似增量,但叠加起来就是革命。

YOLO 家族的演进和智能手机一样。从 2016 年的 YOLOv1 到 2024 年的 YOLOv10 再到 2026 年的 YOLO-Master,核心任务没变——”在一次前向传播中检测图中所有物体”——但每一代都在某个关键维度上做出突破。理解这条演进路线,你就能理解当前检测领域的技术格局。


YOLOv1(2016):一切的起点——”你只需要看一次”

革命性的想法

在 YOLOv1 之前,所有高精度检测方法都是两阶段的:先提出候选区域,再逐个分类。这就像安检时先让每个旅客单独过一遍 X 光机,效率极低。

Joseph Redmon 的洞察是:为什么不一次看完? 把整张图分成 S×S 的网格(默认 7×7 = 49 个格子),每个格子直接预测 B 个边界框和 C 个类别概率。一次前向传播,所有预测同时输出。

输入图像 (448×448)
    │
    ▼
CNN (类似 GoogLeNet 的 24 层卷积)
    │
    ▼
全连接层
    │
    ▼
输出张量: 7 × 7 × 30
  每个格子输出:
    2 个框 × (x, y, w, h, confidence) = 10 个值
    + 20 个类别概率(VOC 数据集 20 类)
    = 30 个值

关键设计决策

网格分配:每个格子最多预测 B=2 个框,且只能预测一个类别。这意味着如果两个不同类别的小目标中心落在同一个格子里,模型只能检测到一个——这是 v1 的重大局限。

端到端训练:整个网络一起训练,从像素到检测结果都是可微的。loss = 分类损失 + 定位损失 + 置信度损失。

历史意义

YOLOv1 在 PASCAL VOC 上达到 63.4 mAP @ 45 FPS,比 Faster R-CNN(73.2 mAP @ 7 FPS)精度低但速度快 6 倍以上。它证明了一阶段检测是可行的,开创了”实时检测”这个赛道。


YOLOv2 / YOLO9000(2017):引入 Anchor 和多尺度

核心改进

YOLOv1 的框是直接回归的,不够稳定。YOLOv2 引入了 anchor box 的概念——预先通过 K-Means 聚类确定 5 种常见的框形状(宽高比),模型改为预测相对于 anchor 的偏移量。这让回归更稳定、收敛更快。

YOLOv1: 直接预测 (x, y, w, h)              → 回归范围无界,训练不稳定
YOLOv2: 预测 (dx, dy, dw, dh) 相对于 anchor → 回归范围有限,训练更稳定

其他改进包括:用 BatchNorm 替代 Dropout、使用更高分辨率训练(416×416 → 544×544)、引入 passthrough 层融合浅层特征(多尺度的萌芽)。

YOLO9000

同一篇论文还展示了一个有趣的实验:通过联合训练检测数据集(COCO,80 类)和分类数据集(ImageNet,9000+ 类),实现了能检测 9000+ 类的模型。虽然这个方向后来没有成为主流,但展示了 YOLO 框架的扩展性。


YOLOv3(2018):多尺度检测的里程碑

核心改进——FPN 式多尺度预测

YOLOv3 最重要的贡献是引入了多尺度检测。v1 和 v2 只在一个尺度上做预测,这对小目标极不友好(小目标在低分辨率特征图上可能只有一两个像素)。

v3 在三个不同尺度的特征图上分别做预测:

Backbone (Darknet-53) 输出:
  13×13 (stride=32) ─── 检测大目标
  26×26 (stride=16) ─── 检测中目标
  52×52 (stride=8)  ─── 检测小目标

每个尺度 × 3 个 anchor = 总共 9 种预设框

日常类比:这就像值班安保用三种不同焦距的摄像头监控同一个区域——广角(stride=32)看大范围粗略轮廓,标准(stride=16)看中等细节,长焦(stride=8)看小目标的精细特征。三个”镜头”各司其职,合起来才能覆盖所有大小的目标。

Darknet-53 骨干网络

v3 使用了 53 层的 Darknet-53 作为 Backbone,引入了残差连接(skip connection)。这是当时 YOLO 系列中最深的网络——更深的网络能提取更丰富的特征。

多标签分类

v3 将分类从 softmax(互斥的单标签)改为 sigmoid(独立的多标签)。这意味着一个目标可以同时属于多个类别——比如在某些数据集中,”女人”和”人”不是互斥的。

历史意义

YOLOv3 是工业界使用最广泛的 YOLO 版本之一,今天仍然在很多场景中运行。它奠定了”多尺度预测 + anchor + 残差网络”的 YOLO 标准范式,后续的 v4、v5、v7 都在这个框架上迭代。


YOLOv4 和 YOLOv5(2020):工程化的极致

YOLOv4——”Bag of Tricks”

YOLOv4 (Bochkovskiy et al.) 不是一个全新架构,而是一次系统性的工程优化——把当时最好的训练技巧(Bag of Specials / Bag of Freebies)全部集成到一个模型里:

训练技巧(Bag of Freebies,只影响训练不影响推理速度):
  Mosaic 数据增强(4 张图拼一张)
  CutMix / MixUp
  DropBlock 正则化
  余弦学习率退火

推理增强(Bag of Specials,提升精度但增加少量推理时间):
  Mish 激活函数
  CSP(Cross Stage Partial)结构
  SPP(Spatial Pyramid Pooling)
  PAN(Path Aggregation Network)

核心洞察:检测模型的最终表现不仅取决于架构设计,还极大地受到训练策略的影响。v4 证明了”把已知的好技巧系统性地组合在一起”本身就是一种创新。

YOLOv5——工业化的起点

YOLOv5 (Glenn Jocher / Ultralytics) 的贡献不在算法层面,而在工程层面:

YOLOv5 的工程创新:
  ✓ PyTorch 原生实现(之前的 YOLO 用 Darknet/C 框架)
  ✓ 一行命令训练/推理/导出
  ✓ 自动 anchor 聚类
  ✓ 多格式导出(ONNX/TRT/CoreML/TFLite)
  ✓ 完善的文档和社区支持

这是 YOLO 从”学术项目”到”工业产品”的转折点。 在 v5 之前,使用 YOLO 需要编译 Darknet(C 语言)、手动配置各种参数,门槛很高。v5 之后,任何会 Python 的人都可以 pip install ultralytics 然后 yolo detect train data=coco.yaml 开始训练。这种易用性直接催生了 Ultralytics 成为检测领域 star 数最高的项目。


YOLOv7(2022):重参数化

核心创新——结构重参数化

YOLOv7 引入了 RepConv(重参数化卷积)的思想:训练时用一个复杂的多分支结构(3×3 conv + 1×1 conv + identity),推理时融合为一个等价的单个 3×3 卷积——训练时复杂(学得好),推理时简单(跑得快)

训练时(多分支结构):           推理时(融合后):
  ┌── 3×3 Conv ──┐                   │
  ├── 1×1 Conv ──┼── Add ──→         3×3 Conv ──→
  └── Identity ──┘                    │
    (参数更多,拟合能力强)      (等价但更快)

日常类比:就像备考时你用三种方法解同一道题(多角度理解),考试时只用最快的那种方法答题。训练时的多分支给了模型更多”学习角度”,推理时融合为单分支提速。

E-ELAN(Extended Efficient Layer Aggregation Network)

v7 还提出了 E-ELAN 结构,通过精心设计的特征聚合路径,在不增加推理成本的情况下提升特征表达能力。


YOLOv8(2023):Anchor-Free 转型——现代 YOLO 的起点

三大关键转变

YOLOv8 是 YOLO 家族的一次重要转型,由 Ultralytics 发布。它做了三个关键的设计决策,直接影响了后续的 YOLOv10 和 YOLO-Master:

转变一:从 Anchor-based 到 Anchor-free

YOLOv5 (Anchor-based):
  每个位置预设 3 个 anchor → 预测偏移量 (dx, dy, dw, dh)
  需要手动或自动确定 anchor 的大小和宽高比

YOLOv8 (Anchor-free):
  每个位置直接预测 4 个距离值 (l, t, r, b)
  l = 目标左边缘到格子中心的距离
  t = 目标上边缘到格子中心的距离
  r = 目标右边缘到格子中心的距离
  b = 目标下边缘到格子中心的距离

去掉 anchor 意味着更少的超参数、更简洁的代码、更好的泛化性。你不再需要为不同的数据集重新设计 anchor 尺寸。

转变二:DFL(Distribution Focal Loss)

如第 3 章所述,YOLOv8 将边界框回归从”预测一个点值”变成了”预测一个概率分布”。每条边用 16 个 bin 的离散分布表示,模型输出的是”每个 bin 的概率”,最终取期望得到距离值。这使得回归更稳定,尤其是在模糊边界(如被遮挡的物体边缘)的场景下。

转变三:TaskAlignedAssigner(TAL)

正样本分配从静态的 IoU 匹配变成了动态的”任务对齐”分配。TAL 同时考虑分类得分和 IoU,用 metric = cls_score^α × IoU^β 选出”分得准又框得好”的样本作为正样本。这个设计我们在第 5 章会深入讲解。

解耦头(Decoupled Head)

v8 把检测头拆成独立的分类分支和回归分支,各自有独立的卷积层。这基于一个洞察:分类任务需要的特征(语义信息)和回归任务需要的特征(空间精度信息)是不同的,强行共享参数反而互相干扰。

# YOLOv8 的 Detect Head 简化版
class Detect(nn.Module):
    def __init__(self, nc=80, ch=(256, 512, 1024)):
        super().__init__()
        self.nc = nc
        self.reg_max = 16
        # 分类分支:独立的卷积层
        self.cv3 = nn.ModuleList(
            nn.Sequential(Conv(c, c, 3), Conv(c, c, 3), nn.Conv2d(c, nc, 1))
            for c in ch
        )
        # 回归分支:独立的卷积层
        self.cv2 = nn.ModuleList(
            nn.Sequential(Conv(c, c, 3), Conv(c, c, 3), nn.Conv2d(c, 4*self.reg_max, 1))
            for c in ch
        )

YAML 驱动的模型定义

v8 延续了 v5 的 YAML 配置风格,整个模型结构定义在一个 YAML 文件中:

# YOLOv8n 配置(简化版)
backbone:
  - [-1, 1, Conv, [64, 3, 2]]        # P1/2:  Conv 3×3, stride=2
  - [-1, 1, Conv, [128, 3, 2]]       # P2/4
  - [-1, 3, C2f, [128, True]]        # C2f 模块, 3 个 Bottleneck
  - [-1, 1, Conv, [256, 3, 2]]       # P3/8
  - [-1, 6, C2f, [256, True]]        # C2f 模块, 6 个 Bottleneck
  # ...

head:
  - [-1, 1, nn.Upsample, [None, 2, "nearest"]]  # 上采样
  - [[-1, 6], 1, Concat, [1]]                    # 和 backbone 特征 concat
  - [-1, 3, C2f, [256]]                          # C2f 融合
  # ...
  - [[15, 18, 21], 1, Detect, [nc]]              # 检测头

tasks.py 会解析这个 YAML,按顺序构建 PyTorch 模块。这让实验变得极其方便——改一行 YAML 就能换一个模块。YOLO-Master 正是利用这个机制,用一行 ES_MOE 就能在任意位置注入 MoE 模块。


YOLOv10(2024):NMS-Free——消除最后的后处理

核心创新——一致性双分配策略

YOLOv10 的核心贡献是彻底消除 NMS 后处理。它的思路是在检测头中引入两个分支:

                              ┌─── one2many 分支 ───→ TAL 分配(多正样本)
特征图 ─→ v10Detect Head ───┤                         用于训练,提供丰富梯度
                              └─── one2one 分支 ────→ 匈牙利匹配(每目标一个预测)
                                   .detach()            用于推理,天然无重复

关键细节:detach()。one2one 分支的输入做了梯度截断——这意味着 one2one 分支的训练不会影响特征提取器的参数,两个分支的训练目标不冲突。

class v10Detect(Detect):
    def forward(self, x):
        # one2one: 输入 detach,梯度不回传到 backbone
        one2one = self.forward_feat(
            [xi.detach() for xi in x],    # ← 关键:detach
            self.one2one_cv2,
            self.one2one_cv3
        )
        # one2many: 标准 YOLO 检测
        one2many = super().forward(x)
        return {"one2many": one2many, "one2one": one2one}

效率创新

除了双分配策略,v10 还做了一系列轻量化设计:

技术 作用 效果
SCDown 空间-通道解耦下采样 减少下采样层 FLOPs
PSA 部分自注意力 只对部分通道做 Attention
C2fCIB 紧凑倒残差块 减少 Bottleneck 参数

结果:YOLOv10-S 仅 7.2M 参数、21.6G FLOPs,是同精度级别最轻量的 YOLO。


YOLO-Master(2026):MoE 进入 YOLO——自适应计算的新维度

和之前所有 YOLO 的根本区别

之前的 YOLO 演进都在同一个维度上做文章:”怎么在固定计算预算下最大化精度”——更好的网络结构、更好的训练策略、更好的后处理。每一个目标不管难易,都走完全相同的计算路径。

YOLO-Master 开辟了一个全新维度:计算量本身是动态的。它在网络中嵌入 MoE(Mixture of Experts)层,用一个轻量路由网络判断”这块区域需要多少计算”,然后只激活 Top-K 个专家来处理。

传统 YOLO:所有区域 → 固定的卷积流水线 → 固定计算量
YOLO-Master:
  简单区域(清晰背景)→ 路由器 → 激活 1 个轻量专家 → 少量计算
  困难区域(遮挡目标)→ 路由器 → 激活 3 个专家 → 更多计算

日常类比:传统 YOLO 像一条固定速度的流水线,不管是组装一个简单螺丝还是一个精密仪器,流水线速度一样。YOLO-Master 像一个智能工厂,简单零件走快速通道,精密零件走精工通道——总产出更高,资源浪费更少。

在 YOLO 演进中的位置

检测范式演进:

Anchor-Based + NMS           Anchor-Free + NMS          Anchor-Free + NMS-Free
(YOLOv3, v4, v5)       →    (YOLOv8)              →    (YOLOv10, RT-DETR)
                                    │
                                    └──── MoE 自适应计算 ────→  YOLO-Master
                                             (新维度:动态算力分配)

YOLO-Master 和 YOLOv10 不在同一条路线上竞争——v10 解决的是”后处理效率”(去 NMS),YOLO-Master 解决的是”计算效率”(自适应 MoE)。理论上两者可以结合。


YOLO 演进总结表

版本 年份 核心贡献 关键技术 范式
v1 2016 一阶段检测的诞生 网格预测 Anchor-free (原始)
v2 2017 引入 Anchor K-Means anchor + BN Anchor-based
v3 2018 多尺度检测 FPN + Darknet-53 Anchor-based
v4 2020 工程化集成 Mosaic + CSP + PAN + SPP Anchor-based
v5 2020 工业化产品 PyTorch + 一键导出 Anchor-based
v7 2022 重参数化 RepConv + E-ELAN Anchor-based
v8 2023 Anchor-free 转型 DFL + TAL + 解耦头 Anchor-free
v10 2024 NMS-free 双分配策略 + SCDown Anchor-free, NMS-free
Master 2026 MoE 自适应计算 ES-MoE + 路由 + 专家池 Anchor-free, MoE

演进的底层逻辑

如果退一步看 YOLO 家族的整个演进,会发现一个清晰的模式——每一代的核心贡献都是消除某个人工设计的组件

v1-v2: 引入了 anchor(人工设计)
v8:    消除了 anchor(anchor-free)
v1-v8: 依赖 NMS 后处理(手动阈值)
v10:   消除了 NMS(端到端)
v1-v10: 固定计算路径(所有输入同样处理)
Master: 消除了固定计算(自适应 MoE)

这个模式和深度学习的大趋势一致:让模型自己学会做决策,减少人工干预。从手工设计 anchor → 模型自己学偏移量 → 模型自己决定”检测什么” → 模型自己决定”花多少算力”。YOLO-Master 是这条路线上的最新一步。


初学者常见误区

误区一:”版本号越大的 YOLO 就越好”

→ 正确理解:YOLO 的版本号不是由同一个团队连续发布的。v1-v3 是 Joseph Redmon 的工作,v4 是 Bochkovskiy 的,v5 和 v8 是 Ultralytics 的,v7 是 WongKinYiu 的,v10 是清华的,Master 是腾讯的。不同版本之间没有严格的”继承”关系。v10 不是 v8 的”升级版”,而是一个独立团队的独立工作。

误区二:”YOLOv8 的 anchor-free 是全新发明”

→ 正确理解:anchor-free 检测在 FCOS(2019)、CenterNet(2019)等工作中已经被充分验证。YOLOv8 的贡献是把 anchor-free 和 DFL、TAL 等技术组合在一起,集成到 Ultralytics 的工程框架中——它的价值在于”集成和打磨”而非”从零发明”。

误区三:”YOLO 家族只做目标检测”

→ 正确理解:从 YOLOv5 开始(尤其是 YOLOv8),YOLO 已经扩展到实例分割、语义分割、姿态估计、图像分类、旋转目标检测(OBB)等多个任务。Ultralytics 的定位是”统一视觉 AI 平台”,不仅仅是检测器。


读完本章你能做什么

读完这一章,你应该能够:

接下来,我们深入 YOLO 训练中最关键也最容易被忽略的环节——正样本分配。


导读目录:README.md 上一章:第 3 章 · 目标检测基础 下一章:第 5 章 · 正样本分配