YOLO 系列:统一实时目标检测(YOLOv1 → YOLOv2 → YOLOv3)

Task: 2D 目标检测
Method: 单阶段检测 / 网格回归 / 多尺度预测
Venue: CVPR 2016 / CVPR 2017 / arXiv 2018
Year: 2016 → 2017 → 2018
Paper: YOLOv1 / YOLOv2 / YOLOv3
Code: pjreddie/darknet

1. 摘要

YOLOv1(CVPR 2016)开创性地将目标检测重新定义为 单一回归问题:一个神经网络直接从完整图像预测边界框和类别概率,端到端优化。基础 YOLO 模型达到 45 FPS,Fast YOLO 达到 155 FPS,同时在泛化性上大幅超越 DPM 和 R-CNN(从自然图像迁移到艺术作品)。代价是定位精度不及两阶段检测器。

YOLOv2(CVPR 2017,又称 YOLO9000)系统性提升了 YOLO 的精度和速度:引入 Batch Normalization、锚框机制、维度聚类、多尺度训练等改进。使用全新的 Darknet-19 骨干网络,YOLOv2 在 VOC 2007 上达到 78.6 mAP(40 FPS),超越 Faster R-CNN 和 SSD 且速度更快。同时提出联合训练检测与分类的方法,使 YOLO9000 能检测超过 9000 个类别。

YOLOv3(arXiv 2018)引入残差网络 Darknet-53 和类 FPN 的多尺度预测:在 3 个不同分辨率上检测,配合 9 组锚框先验,大幅改善小目标检测。在 COCO test-dev 上,YOLOv3-608 达到 57.9 AP50(20 FPS),精度与 RetinaNet 相当但快 3.8 倍。

核心论点:目标检测可以被重构为”一次看完”的统一回归问题,通过骨干网络升级(GoogLeNet → Darknet-19 → Darknet-53)和多尺度检测机制的引入,单阶段检测器在保持实时速度的同时逼近两阶段检测器的精度。

2. 问题与动机

传统目标检测的流程冗长且速度受限:

检测范式 代表方法 核心思路 核心问题
滑动窗口 DPM(2010) 扫描全图的子窗口送入分类器 计算量巨大,速度极慢
两阶段 R-CNN 系列 先提候选区域,再分类回归 需多次前向传播(R-CNN 2000+次),流程复杂
快速两阶段 Faster R-CNN RPN 生成候选框 + Fast R-CNN 7 FPS,仍不满足实时需求
单阶段回归 YOLO 系列 一次前向直接输出检测结果 v1 定位精度不足,小目标差

核心痛点:两阶段检测器精度高但实时性不足(<10 FPS);现有快速方法(如 DPM 等)精度太低。如何在保持实时速度(>30 FPS)的前提下达到有竞争力的检测精度?

3. 核心洞察

洞察 1:检测即回归——“一次看完”的统一框架

传统方法将检测分解为”提候选框→分类→回归→NMS”多个独立步骤。YOLO 的核心突破:将检测视为从图像像素到边界框坐标和类别概率的 单一回归问题

具体机制(YOLOv1):将图像划分为 $S \times S$ 网格($S=7$),每个网格单元预测 $B$ 个边界框($B=2$)和 $C$ 个类别概率。输出张量维度:

$$S \times S \times (B \times 5 + C) = 7 \times 7 \times 30 \quad \text{(VOC,}C=20\text{)}$$

每个边界框包含 5 个值:$(x, y, w, h, \text{confidence})$,其中 $\text{confidence} = \Pr(\text{Object}) \times \text{IOU}_{\text{pred}}^{\text{truth}}$。

关键优势:全局上下文——网络”看到”整张图像,不像滑动窗口只看局部,因此背景误检率(false positive)显著低于 R-CNN。

洞察 2:锚框 + 维度聚类——从手工设计到数据驱动的先验

YOLOv1 直接回归绝对坐标,导致训练不稳定且定位精度差。YOLOv2 引入两个关键改进:

  1. 锚框(Anchor Boxes):借鉴 Faster R-CNN 的思路,不再直接预测边界框,而是预测相对于预定义锚框的偏移量
  2. 维度聚类:不使用手工选择的锚框尺寸,而是在训练集上用 k-means 聚类($k=5$)自动确定最优锚框尺寸,距离度量为 $d(\text{box}, \text{centroid}) = 1 - \text{IOU}(\text{box}, \text{centroid})$

YOLOv2 的直接位置预测——用 sigmoid 约束偏移在网格单元内:

$$b_x = \sigma(t_x) + c_x, \quad b_y = \sigma(t_y) + c_y, \quad b_w = p_w e^{t_w}, \quad b_h = p_h e^{t_h}$$

其中 $(c_x, c_y)$ 是网格单元左上角坐标,$(p_w, p_h)$ 是锚框的宽高。

洞察 3:多尺度预测 + 残差骨干——解锁小目标检测

YOLOv1/v2 只在单一特征图上检测,对小目标效果差。YOLOv3 引入类 FPN 的多尺度机制:

  1. Darknet-53 骨干:53 层卷积 + 残差连接(参考 ResNet),精度接近 ResNet-152 但速度快 2 倍
  2. 3 尺度预测:在 $13 \times 13$、$26 \times 26$、$52 \times 52$ 三个分辨率上分别预测(以 416×416 输入为例),每个尺度分配 3 个锚框,共 9 个锚框
  3. 多标签分类:用 binary cross-entropy 替代 softmax,支持多标签(一个物体可属于多个类别)

YOLOv3 每个检测头输出 $N \times N \times [3 \times (4 + 1 + C)]$:

  • 4:边界框偏移 $(t_x, t_y, t_w, t_h)$
  • 1:objectness 分数
  • $C$:每类 binary 分类分数

要记住的 3 个数字

  • 57.9 AP50:YOLOv3-608 在 COCO test-dev 上的精度,与 RetinaNet 相当但快 3.8 倍
  • 45 FPS → 40 FPS → 20 FPS:YOLOv1/v2/v3 在 Titan X 上的实时帧率(精度逐代提升)
  • 78.6 mAP:YOLOv2 在 VOC 2007 上的精度(40 FPS),超越当时所有实时检测器

4. 方法设计

4.1 整体架构

YOLO 系列的核心流程:

$$\text{Image} \xrightarrow{\text{Backbone}} \text{Feature Maps} \xrightarrow{\text{Detection Head}} S \times S \times [B \times (5 + C)] \xrightarrow{\text{NMS}} \text{Detections}$$
┌──────────────────────────────────────────────────────────────────┐
│                    YOLOv3 架构(416×416 输入)                     │
├──────────────────────────────────────────────────────────────────┤
│                                                                  │
│  Input: 416×416×3                                                │
│  │                                                               │
│  ▼                                                               │
│  ┌────────────────────────────────────────────────────────┐      │
│  │ Darknet-53 Backbone(53 conv + 残差连接)                │      │
│  │                                                        │      │
│  │  Conv 3×3/32 → [1×,2×,8×,8×,4×] 残差块                  │      │
│  │                                                        │      │
│  │  输出 3 个尺度的特征图:                                  │      │
│  │  ├─ Scale 1: 13×13×1024 ──▶ 检测大目标                   │      │
│  │  ├─ Scale 2: 26×26×512  ──▶ 检测中目标(上采样+拼接)      │      │
│  │  └─ Scale 3: 52×52×256  ──▶ 检测小目标(上采样+拼接)      │      │
│  └────────────────────────────────────────────────────────┘      │
│  │             │            │                                    │
│  ▼             ▼            ▼                                    │
│  ┌──────┐  ┌──────┐  ┌──────┐                                    │
│  │ Head │  │ Head │  │ Head │  每个 Head:                         │
│  │13×13 │  │26×26 │  │52×52 │  Conv 1×1 → N×N×[3×(4+1+80)]       │
│  │×255  │  │×255  │  │×255  │  3 anchors × (4 bbox+1 obj+80 cls) │
│  └──────┘  └──────┘  └──────┘                                    │
│         │         │         │                                    │
│         └─────────┼─────────┘                                    │
│                   ▼                                              │
│              NMS 后处理                                           │
│                   ▼                                              │
│              最终检测结果                                          │
└──────────────────────────────────────────────────────────────────┘

4.2 关键组件

骨干网络演进

版本 Backbone 层数 Top-1 (ImageNet) FLOPs 关键创新
v1 GoogLeNet-like 24 conv + 2 FC 8.52B 首个端到端检测网络
v2 Darknet-19 19 conv + 5 maxpool 91.2% (top-5) 5.58B BN + 全卷积
v3 Darknet-53 53 conv + 残差连接 77.2% (top-1) 18.7B 残差学习 + 多尺度特征

YOLOv1 损失函数——多任务加权 MSE:

$$\mathcal{L} = \lambda_{\text{coord}} \sum_{i=0}^{S^2} \sum_{j=0}^{B} \mathbb{1}_{ij}^{\text{obj}} [(x_i - \hat{x}_i)^2 + (y_i - \hat{y}_i)^2 + (\sqrt{w_i} - \sqrt{\hat{w}_i})^2 + (\sqrt{h_i} - \sqrt{\hat{h}_i})^2]$$ $$+ \sum_{i=0}^{S^2} \sum_{j=0}^{B} \mathbb{1}_{ij}^{\text{obj}} (C_i - \hat{C}_i)^2 + \lambda_{\text{noobj}} \sum_{i=0}^{S^2} \sum_{j=0}^{B} \mathbb{1}_{ij}^{\text{noobj}} (C_i - \hat{C}_i)^2 + \sum_{i=0}^{S^2} \mathbb{1}_{i}^{\text{obj}} \sum_{c \in \text{classes}} (p_i(c) - \hat{p}_i(c))^2$$

其中 $\lambda_{\text{coord}} = 5$(加大坐标权重),$\lambda_{\text{noobj}} = 0.5$(降低无目标框的权重)。对 $w, h$ 取平方根以缓解大小目标的尺度不平衡。

YOLOv2 的系统性改进

改进项 具体做法 效果
Batch Normalization 所有卷积层后加 BN +2% mAP
高分辨率分类器 ImageNet 预训练从 224 提升至 448 +4% mAP
锚框 + 维度聚类 k-means 聚类 k=5 个先验框 召回率提升(81% → 88%)
直接位置预测 sigmoid 约束偏移在网格内 稳定训练
细粒度特征 Passthrough 层(26×26 → 13×13 拼接) 改善小目标
多尺度训练 每 10 batch 随机调整输入尺寸(320~608) 灵活速度-精度权衡

4.3 关键代码

文件 功能
cfg/yolov3.cfg YOLOv3 网络架构定义(Darknet 格式)
src/yolo_layer.c YOLO 检测层前向/反向传播
📄 点击展开 YOLOv3 Darknet-53 骨干配置(关键片段)

(来源:cfg/yolov3.cfg

[net]
batch=64
subdivisions=16
width=416
height=416
channels=3
momentum=0.9
decay=0.0005
learning_rate=0.001

# Darknet-53 骨干(前 75 层)
# 第一个残差组:1× residual block
[convolutional]
batch_normalize=1
filters=32
size=3
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=64
size=3
stride=2 # 下采样
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=32
size=1
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=64
size=3
stride=1
pad=1
activation=leaky

[shortcut] # 残差连接
from=-3
activation=linear

# ... 后续 2×, 8×, 8×, 4× 残差块 ...

# 第一个检测头(13×13,检测大目标)
[convolutional]
batch_normalize=1
size=1
stride=1
pad=1
filters=255 # 3 × (4 + 1 + 80) = 255

[yolo]
mask = 6,7,8 # 使用第 6/7/8 号锚框(大锚框)
anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326
classes=80
num=9 # 共 9 个锚框,每个尺度用 3 个

# 上采样 + 拼接 → 第二个检测头(26×26,检测中目标)
[route]
layers = -4

[convolutional]
batch_normalize=1
filters=256
size=1
stride=1
pad=1
activation=leaky

[upsample]
stride=2

[route]
layers = -1, 61 # 拼接上采样特征与骨干浅层特征

# ... 第二个 [yolo] 层,mask = 3,4,5 ...
# ... 第三个 [yolo] 层(52×52),mask = 0,1,2 ...
📄 点击展开 YOLOv3 的 9 组锚框先验(COCO)

(来源:cfg/yolov3.cfg

# 通过 k-means 聚类在 COCO 训练集上得到的 9 组锚框(宽,高)
# 按面积从小到大排列:

# 小目标锚框(52×52 特征图使用,mask=0,1,2):
# (10, 13) (16, 30) (33, 23)

# 中目标锚框(26×26 特征图使用,mask=3,4,5):
# (30, 61) (62, 45) (59, 119)

# 大目标锚框(13×13 特征图使用,mask=6,7,8):
# (116, 90) (156, 198) (373, 326)

5. 实验与分析

5.1 主要结果

COCO test-dev 性能对比(mAP@50 指标):

方法 Backbone 输入尺寸 AP50 FPS (Titan X) FLOPs
SSD300 VGG-16 300×300 41.2 46
SSD512 VGG-16 512×512 46.5 19
RetinaNet-101 ResNet-101 800 57.5 5
FPN FRCN ResNet-101 59.1 6
YOLOv2 Darknet-19 608×608 48.1 40 62.94B
YOLOv3 Darknet-53 320×320 51.5 45 38.97B
YOLOv3 Darknet-53 416×416 55.3 35 65.86B
YOLOv3 Darknet-53 608×608 57.9 20 140.69B
YOLOv3-SPP Darknet-53 608×608 60.6 20 141.45B

VOC 2007 性能演进

方法 年份 mAP FPS
Faster R-CNN 2015 73.2 ~7
YOLOv1 2016 63.4 45
Fast YOLO 2016 52.7 155
YOLOv2 (高分辨率) 2017 78.6 40

关键发现

  1. YOLOv3 在 AP50 指标上与 RetinaNet 相当(57.9 vs 57.5),但速度快 3.8 倍(20 FPS vs 5 FPS)
  2. 从 v1 到 v3,VOC mAP 从 63.4 提升至远超 78.6,COCO AP50 从约 48 提升至 57.9,每一代均有显著提升
  3. 多尺度输入使推理灵活——同一模型从 320(45 FPS)到 608(20 FPS)自由切换精度与速度

5.2 消融实验:验证三个洞察

YOLOv2 改进项逐步叠加(洞察 1、2)

改进项 VOC 2007 mAP 验证洞察
YOLOv1 baseline 63.4
+ Batch Normalization 65.8 洞察 2
+ High Res Classifier 69.5 洞察 2
+ Convolutional (anchor boxes) 69.2(召回 81%→88%) 洞察 2
+ Dimension Clusters ✓(更优先验) 洞察 2
+ Direct Location Prediction ✓(训练稳定) 洞察 2
+ Passthrough ✓(细粒度特征) 洞察 2
+ Multi-Scale Training ✓(灵活输入) 洞察 2
YOLOv2 最终 78.6 洞察 1+2

注:部分中间步骤的具体独立 mAP 未在论文中完整给出,以上标注 ✓ 表示该改进被验证为有正面贡献。

Darknet-53 vs 其他骨干(洞察 3)——ImageNet Top-1 / FPS 对比:

Backbone Top-1 Top-5 BFLOP/s FPS
Darknet-19 74.1 91.8 7.29
ResNet-101 77.1 93.7 19.7
ResNet-152 77.6 93.8 29.4
Darknet-53 77.2 93.8 18.7 2× faster than ResNet-152

5.3 性能瓶颈分析

  • COCO AP(严格 IOU 指标)较低:YOLOv3 的 AP@[.5:.95] 仅约 33.0,远低于 AP50 的 57.9,说明边界框回归精度在高 IOU 阈值下不足
  • 定位误差仍是主要来源:相比两阶段检测器,YOLO 的定位误差占总误差比例更高(YOLOv1 论文 Fig.4 对比分析)
  • 每个网格单元的检测容量有限:YOLOv1 每格仅 B=2 个框,YOLOv3 每格 3 个锚框,对密集重叠场景不利

5.4 失效场景分析

  • 密集小目标群:一个网格单元只能负责一个目标(v1)或有限锚框(v3),成群出现的小目标容易漏检
  • 极端宽高比物体:锚框聚类覆盖的宽高比有限,细长物体(如栏杆、电线)预测不准
  • 高 IOU 精度要求场景:YOLO 的粗粒度网格限制了像素级精确定位能力

6. 工程实践

6.1 训练配置

Backbone:       Darknet-53(ImageNet 预训练,top-1 77.2%)
Input: 416×416(多尺度训练随机切换 320~608,步长 32)
Batch: 64(subdivisions=16)
Optimizer: SGD, lr=0.001, momentum=0.9, weight_decay=0.0005
Augmentation: 随机裁剪、颜色扰动、水平翻转
Training: VOC: ~80 epochs; COCO: ~500k iterations
Hardware: Titan X GPU

6.2 复现要点

  1. 多尺度训练不可省略:每 10 个 batch 随机调整输入分辨率(320/352/384/…/608),使同一模型适应不同尺度的目标
  2. 锚框聚类必须在目标数据集上执行:COCO 和 VOC 的最优锚框尺寸不同,直接套用会损失精度
  3. sigmoid 约束位置预测:YOLOv2/v3 对 $(t_x, t_y)$ 用 sigmoid,将偏移约束在 [0,1] 内(相对于网格单元),是训练稳定的关键
  4. 损失权重平衡:坐标损失权重($\lambda_{\text{coord}}=5$)需远大于无目标置信度损失权重($\lambda_{\text{noobj}}=0.5$),否则大量负样本梯度会主导训练
  5. NMS 阈值调优:默认 IOU 阈值 0.45,对密集场景可适当降低

6.3 性能优化方向

精度提升

  • 引入 FPN 的完整特征金字塔(YOLOv3 仅用单向上采样拼接,未有自底向上的重聚合)
  • 采用更先进的标签分配策略(如 SimOTA、Task-Aligned Assignment),替代简单的网格分配

速度优化

  • Tiny YOLO(9 层卷积)在 COCO 上达 33.1 AP50 / 220 FPS,适合嵌入式部署
  • 模型量化(INT8)和剪枝可进一步加速推理

7. 研究启示

7.1 可迁移的思想

  • “检测即回归”的范式统一:YOLO 证明复杂的多阶段检测流程可被单网络回归替代,这一思想影响了后续所有 anchor-free 检测器(CenterNet、FCOS 等)
  • 维度聚类替代手工先验:用 k-means 从数据中学习锚框尺寸,比手动设定更优,这一方法在 3D 检测中同样适用
  • 多尺度训练的灵活性:单一模型通过调整输入分辨率即可在不同速度-精度点间切换,无需重训练
  • 骨干网络与检测器的松耦合:YOLO 系列通过独立升级骨干(GoogLeNet→Darknet-19→Darknet-53)持续提升性能,是模块化设计的典范

7.2 方法局限

  • 定位精度(尤其高 IOU 阈值下)始终弱于两阶段检测器(如 Faster R-CNN / Cascade R-CNN)
  • 网格机制限制了密集场景检测能力,每个位置的检测容量有限
  • 作者 Joseph Redmon 于 2020 年退出 CV 研究,官方 YOLO 系列止步于 v3

7.3 技术影响

  • 开创单阶段检测器浪潮:YOLO 与 SSD 共同证明单阶段检测可行,催生了 RetinaNet、CornerNet、CenterNet、FCOS 等大量后续工作
  • 工业部署的首选框架:YOLO 系列因速度优势成为自动驾驶、视频监控、移动端检测等实时场景的主流方案
  • 社区传承:YOLOv4(Bochkovskiy)、YOLOv5/v8(Ultralytics)、YOLOX(旷视)等延续了 YOLO 的设计哲学,持续刷新速度-精度权衡的帕累托前沿
  • Darknet 框架:YOLO 催生的轻量级 C 语言深度学习框架,成为嵌入式视觉算法部署的重要工具