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) 上就能实时跑。
十、优缺点分析
优点 ✅
- 三段式架构标准化: Backbone → Neck → Head 成为后续所有 YOLO 的模板
- 系统化的 trick 筛选: BoF/BoS 方法论让后来者知道”什么时候用什么”
- CIoU Loss: 综合重叠度/中心距离/长宽比,定位更准
- Mosaic 增强: 小目标检测能力质的飞跃,成为标配
- CSPDarknet53: 更少计算、更好性能
- PANet 双向融合: FPN+PAN 双向金字塔,特征流动更充分
- 单 GPU 友好: CmBN 让普通玩家也能训
局限 ❌
- 技术创新不多: 本质上是一次系统性的 trick 消融 + 组合,没有提出全新的架构(论文自己就是”炼丹手册”)
- Anchor-based 的固有缺陷: 仍然需要手工设定 Anchor 数量和聚类
- CSPDarknet53 不是最强 Backbone: 后续 EfficientNet/CSPResNeXt 等有更强的,作者在论文里也做了对比
- 没有解决 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 概述