YOLOv4: Optimal Speed and Accuracy

论文: YOLOv4: Optimal Speed and Accuracy of Object Detection (2020)
作者: Alexey Bochkovskiy, Chien-Yao Wang, Hong-Yuan Mark Liao
代码: github.com/AlexeyAB/darknet


一、核心思想 —— “炼丹手册”的系统化

YOLOv4 的本质:以 YOLOv3 为基础,筛选了近几年在各种检测器上被验证有效的 tricks,做了一次系统性的消融实验。论文读起来像一本”目标检测炼丹手册”。

最大贡献:三段式架构 + BoF/BoS 方法论

1
2
3
4
5
6
7
YOLOv4 确立的黄金架构:

输入 ──→ Backbone ──→ Neck ──→ Head ──→ 输出
特征提取 特征融合 预测头

此前 v3 已有这三部分的雏形,但 v4 第一次把它们作为明确的架构范式提出来,
后续 v5/v7/v8 都沿用了这个框架。

v3 → v4 改动速览

组件 YOLOv3 YOLOv4
Backbone Darknet-53 CSPDarknet53
Neck FPN (单向) SPP + PANet (双向)
Head YOLOv3 Head YOLOv3 Head (不变)
激活函数 LeakyReLU Mish (Backbone) + LeakyReLU (其它)
BBox 损失 MSE CIoU Loss
数据增强 基础增强 Mosaic + SAT + CutMix
归一化 BN CmBN (跨迭代小批量)
正则化 DropBlock
分类器 Sigmoid Sigmoid (不变)
Anchor 9 个 (K-means) 9 个 (不变)

检测头、Anchor 数量、多尺度预测这三项完全继承 v3。v4 的精力集中在更好的特征提取 + 更好的特征融合 + 更好的损失函数


二、Backbone: CSPDarknet53

2.1 CSP (Cross Stage Partial) 跨阶段部分连接

核心思想:把输入特征图劈成两半,一半走残差块,一半直接短路,最后拼接。

1
2
3
4
5
6
7
8
9
10
11
12
13
传统 ResBlock:                     CSP 结构:
输入 输入
│ ├──→ Part1 (直通) ──────┐
├──→ Conv(1×1) │ ├──→ Concat → 输出
├──→ Conv(3×3) └──→ Part2 (ResBlock) ──┘
└──→ add(输入) ← skip

输出

好处:
① 计算量减少 ~20% —— 只对一半通道做变换
② 梯度流翻倍 —— 两条路径各有独立梯度
③ 特征更丰富 —— 拼接保留了原始 + 变换后两种特征

2.2 CSPDarknet53 vs Darknet-53

维度 Darknet-53 (v3) CSPDarknet53 (v4)
残差单元 标准 ResBlock CSP-ResBlock
激活函数 LeakyReLU Mish
下采样 Conv stride=2 Conv stride=2 (不变)
5 组 ResBlock [1, 2, 8, 8, 4] [1, 2, 8, 8, 4] (不变)
计算量 基准 ~80% (CSP 节省)
ImageNet Top-1 77.2% ~79%+

为什么选 CSPDarknet53 而不是 CSPResNeXt50?作者实验表明:ImageNet 分类上 CSPResNeXt50 更好,但 COCO 检测上 CSPDarknet53 反超。分类强 ≠ 检测强,感受野和特征粒度更重要。

2.3 Mish 激活函数

$$f(x) = x \cdot \tanh(\ln(1+e^x)) = x \cdot \tanh(\text{softplus}(x))$$

1
2
3
4
5
6
7
Mish vs ReLU 对比:

ReLU: f(x)=max(0,x) → 负半轴彻底截断,"神经元死亡"风险
Mish: f(x)=x·tanh(softplus(x)) → 负半轴允许小幅负值流动

Mish 只在 Backbone 中使用,
Neck 和 Head 仍用 LeakyReLU —— 因为 Mish 计算略重,只在最关键的地方用。

三、Neck: SPP + PANet

v3 的 Neck 是单向 FPN(深层→浅层上采样融合)。v4 升级为 SPP + PANet(双向金字塔 + 多尺度池化)。

3.1 SPP (Spatial Pyramid Pooling)

1
2
3
4
5
6
7
8
9
10
作用: 极大增加感受野,分离最重要的上下文特征

输入特征 (13×13×512)
├──→ 5×5 MaxPool ──┐
├──→ 9×9 MaxPool ──┤
├──→ 13×13 MaxPool ─┼──→ Concat → 1×1 Conv → 输出
└──→ 直通 ──────────┘

四个尺度的池化结果拼接 → 感受野从局部到全局全覆盖
注意: 池化层 padding='same', 尺寸不变, 仅增加感受野!

3.2 PANet (Path Aggregation Network)

1
2
3
4
5
6
7
8
9
10
11
FPN (v3):
深层特征 ──上采样──→ 中层 ──上采样──→ 浅层
语义信息自上而下传递 ✓
但: 浅层的位置信息无法传递给深层 ✗

PANet (v4):
FPN (自上而下): 深层语义 → 上采样 → 注入浅层
+
PAN (自下而上): 浅层位置 → 下采样 → 增强深层

= 双向特征金字塔: 语义往下走, 位置往上走, 信息全面流动

PAN 的额外好处:YOLOv4 的 PAN 用 Concat 而非 Add,保留了更多原始信息。

3.3 Neck 完整结构示意

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Backbone 三尺度输出:
C3 (52×52) C4 (26×26) C5 (13×13)
│ │ │
│ │ ┌─ SPP ─┐
│ │ │ 多尺度 │
│ │ │ 池化 │
│ │ └───┬────┘
│ │ │ P5 (13×13) ────→ YOLO Head 1 (大目标)
│ │ │
│ │ 上采样(×2) + Concat
│ │ │
│ ┌────┴─────────────┘
│ │ P4 (26×26) ────→ YOLO Head 2 (中目标)
│ │
│ 下采样(×2) + Concat ← PAN 自下而上! ← v3 没有这步
│ │
└──────────┼────┘
P3 (52×52) ────→ YOLO Head 3 (小目标)

四、Head —— 继承 YOLOv3

检测头完全沿用 YOLOv3:3 个尺度,每个尺度 3 个 Anchor,输出 N×N×[3×(4+1+C)]。唯一变化是 BBox 回归损失 换成了 CIoU。


五、CIoU Loss —— v4 最重要的损失函数升级 🔥

v4 之前的 YOLO 系列一直用 MSE 回归 BBox 坐标。v4 引入 CIoU Loss,综合考虑了重叠度、中心距离和长宽比三个因素。

5.1 IoU Loss 的进化史

损失函数 公式 解决的问题 遗留问题
MSE (v1~v3) $(x-\hat{x})^2 + \dots$ 最基础 坐标各维度独立优化,与 IoU 不一致
IoU Loss $1 - \text{IoU}$ 直接优化 IoU 不相交时梯度为 0
GIoU Loss $1 - \text{IoU} + \frac{ C - (A \cup B) }{ C }$ 不相交也有梯度 收敛慢,先扩后收
DIoU Loss $1 - \text{IoU} + \frac{\rho^2(b, b^{gt})}{c^2}$ 中心距离直接回归 长宽比未考虑
CIoU Loss $1 - \text{IoU} + \frac{\rho^2}{c^2} + \alpha v$ 全部三个因素 当前最优

5.2 CIoU 完整公式

$$\mathcal{L}_{CIoU} = 1 - \text{IoU} + \frac{\rho^2(b, b^{gt})}{c^2} + \alpha v$$

含义 解决的问题
$1 - \text{IoU}$ 基础重叠度 框重叠越好,损失越小
$\frac{\rho^2}{c^2}$ 中心点距离 / 对角线距离 即使不重叠,也能往对的方向拉
$\alpha v$ $\alpha \times$ 长宽比一致性 预测框和 GT 框形状越像,惩罚越小

其中:

  • $\rho(b, b^{gt})$ = 预测框中心与 GT 框中心的欧氏距离
  • $c$ = 包围两个框的最小矩形的对角线长度
  • $v = \frac{4}{\pi^2}(\arctan\frac{w^{gt}}{h^{gt}} - \arctan\frac{w}{h})^2$ = 长宽比差异
  • $\alpha = \frac{v}{(1-\text{IoU})+v}$ = 动态权重(IoU 高时更关注长宽比)

5.3 为什么 CIoU 更好?

1
2
3
4
5
6
7
8
9
场景: 预测框和 GT 框完全重叠, 但长宽比不同

GT: 宽100, 高50 (长宽比 2:1)
Pred: 宽70, 高70 (长宽比 1:1)

IoU = 1.0 ← MSE/IoU/GIoU 都认为完美!
但实际: 长宽比完全不同, 框得不准!

CIoU: αv 项惩罚长宽比不一致 → 继续优化 ✅

六、BoF vs BoS —— 方法论贡献

YOLOv4 论文最有影响力的贡献之二:把各种改进技巧按”是否增加推理成本”分成两大类。

6.1 BoF (Bag of Freebies, 免费包)

只影响训练,推理时零额外开销。

技巧 描述 v3 有没有
Mosaic 数据增强 4 张图拼接为 1 张,丰富小目标上下文
SAT 自对抗训练 网络先欺骗自己修改图像,再在扰动图上训练
CmBN 跨迭代小批量归一化,适合单 GPU 训练
CIoU Loss 综合 IoU + 中心距离 + 长宽比
标签平滑 软化 one-hot 标签,防止过拟合
余弦学习率衰减 代替阶梯衰减,更平滑

6.2 BoS (Bag of Specials, 特殊包)

略微增加推理成本,但大幅提升性能。

技巧 位置 作用
Mish 激活 Backbone 平滑非单调,精度 +1%
CSP 连接 Backbone 减计算、增梯度
SPP 块 Neck 多尺度感受野
PANet Neck 双向特征融合
SAM Neck 空间注意力(逐点版)
DIoU-NMS 后处理 考虑中心距离的 NMS
DropBlock 正则化 丢弃连续区域,比 Dropout 更适合卷积

6.3 SAM (改进版空间注意力)

1
2
3
4
5
原始 SAM: 通道注意力 + 空间注意力 (CBAM 风格)
YOLOv4 SAM: 直接用卷积对特征图做空间注意力
→ 不降通道数
→ 计算更轻
→ 对 PANet 输出做逐点加权

七、Mosaic 数据增强 —— 最亮眼的 BoF 🔥

7.1 怎么做?

1
2
3
4
5
6
7
8
9
10
11
取 4 张不同的训练图 → 各自随机裁剪 → 拼接成 1 张图

┌─────────┬──────────┐
│ 图1 │ 图2 │
│ (天空) │ (街道) │
├─────────┼──────────┤
│ 图3 │ 图4 │
│ (室内) │ (草地) │
└─────────┴──────────┘

一张包含 4 种背景的混合图

7.2 为什么好?

1
2
3
4
5
6
7
8
① 丰富小目标: 4 张图缩小拼接 → 单图物体密度翻 4 倍
→ 小目标样本量暴增 → 小目标检测能力 ↑↑↑

② 混合背景: 天空+街道+室内+草地混在一张图
→ 模型不再依赖"特定背景",泛化更强

③ BN 受益: 每张图 4 种场景 → batch 统计更丰富
→ 单 GPU 训练也能有好的 BN 效果

Mosaic 增强后来被 v5/v7/v8 全部继承,是 YOLOv4 最具影响力的单个 trick。


八、训练策略

8.1 完整训练流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
═══════════════════════════════════
Step 1: ImageNet 预训练 CSPDarknet53
═══════════════════════════════════
(分类版本, 含全连接 + Softmax)



═══════════════════════════════════
Step 2: 修改为检测网络
═══════════════════════════════════
- 去掉分类头
- 添加 SPP + PANet Neck
- 添加 YOLOv3 检测头



═══════════════════════════════════
Step 3: COCO 检测训练
═══════════════════════════════════
数据增强: Mosaic + CutMix + 传统增强
损失: CIoU Loss (定位) + BCE (置信度) + BCE (类别)
优化器: SGD + Momentum
归一化: CmBN
正则化: DropBlock

8.2 关键训练参数

参数 说明
输入尺寸 608×608 (训练) 最大精度配置
Batch Size 64 多 GPU
优化器 SGD + Momentum 0.949
初始学习率 0.001 余弦衰减
权重衰减 0.0005
Warmup 1000 iter 逐步增大 lr
Anchor 数 9 同 v3
ignore_thresh 0.5 同 v3
框分配 1 GT → 1 Anchor 同 v3

九、性能表现

模型 mAP@0.5 (COCO) FPS (V100) Backbone
YOLOv3 33.0% Darknet-53
YOLOv3-SPP 36.2% Darknet-53 + SPP
YOLOv4 43.5% ~65 CSPDarknet53
EfficientDet-D0 33.8% 98 EfficientNet
EfficientDet-D3 45.8% 25 EfficientNet

YOLOv4 在同等精度下比 EfficientDet 快约 2 倍,普通 GPU (如 1080Ti) 上就能实时跑。


十、优缺点分析

优点 ✅

  1. 三段式架构标准化: Backbone → Neck → Head 成为后续所有 YOLO 的模板
  2. 系统化的 trick 筛选: BoF/BoS 方法论让后来者知道”什么时候用什么”
  3. CIoU Loss: 综合重叠度/中心距离/长宽比,定位更准
  4. Mosaic 增强: 小目标检测能力质的飞跃,成为标配
  5. CSPDarknet53: 更少计算、更好性能
  6. PANet 双向融合: FPN+PAN 双向金字塔,特征流动更充分
  7. 单 GPU 友好: CmBN 让普通玩家也能训

局限 ❌

  1. 技术创新不多: 本质上是一次系统性的 trick 消融 + 组合,没有提出全新的架构(论文自己就是”炼丹手册”)
  2. Anchor-based 的固有缺陷: 仍然需要手工设定 Anchor 数量和聚类
  3. CSPDarknet53 不是最强 Backbone: 后续 EfficientNet/CSPResNeXt 等有更强的,作者在论文里也做了对比
  4. 没有解决 NMS 问题: 仍需要 NMS 后处理,不是端到端(v8/v10 改进)

十一、相关链接

  • 📝 [[YOLO 系列总览]] — 版本对比总览
  • 📝 [[YOLO 核心概念]] — Grid/Anchor/IoU/NMS 详解
  • 📝 [[YOLOv3 详解]] — v3 基础
  • 📝 [[YOLOv5 详解]] — v5 接棒
  • 📋 [[10.clippings/感知算法/2D检测/单阶段/YOLO/【万字长文】看完这篇yolov4详解,那算是真会了-阿里云开发者社区]]
  • 📋 [[10.clippings/感知算法/2D检测/单阶段/YOLO/YOLO V4 — 网络结构和损失函数解析(超级详细!)]] — 知乎 (周威)
  • 📋 [[10.clippings/感知算法/2D检测/单阶段/YOLO/YOLO 详解:从 v1 到 v11]] — v4 概述