目标检测算法详解
一、问题定义与评价指标
1.1 问题定义
输入: 图像 I ∈ ℝ^{H×W×C}
输出: 物体包围框 B = {bbox₁, …, bboxₙ},每个 bbox = (x, y, w, h, class, confidence)
1.2 评价指标
| 指标 | 含义 | 公式/说明 |
|---|---|---|
| IoU | 交并比 | area(∩)/area(∪) |
| AP | Average Precision | Precision-Recall曲线下面积 |
| mAP ⭐ | 所有类别AP平均 | 常用的标准指标 |
| mAP@0.5 | IoU>0.5时的mAP | COCO标准评估 |
| mAP@[0.5:0.95] | 10个IoU阈值平均 | COCO主要指标 |
| AR | Average Recall | 平均召回率 |
| FPS | Frames Per Second | 推理速度 |
1.3 非极大值抑制 (NMS)
def nms(bboxes, scores, iou_threshold=0.5):
"""经典的贪心NMS"""
order = scores.argsort(descending=True)
keep = []
while order.numel() > 0:
i = order[0]
keep.append(i)
if order.numel() == 1: break
ious = compute_iou(bboxes[i], bboxes[order[1:]])
mask = ious < iou_threshold
order = order[1:][mask]
return keep
NMS变体: Soft-NMS (IOU加权), DIoU-NMS, Softer-NMS, Cluster NMS
二、两阶段检测器 ⭐
2.1 R-CNN (2014) - 开山之作
输入图像 → Selective Search(~2K候选) → 裁剪缩放 → CNN特征 → SVM分类 + 回归微调
问题: 重复计算,推理慢(47s/图)
2.2 Fast R-CNN (2015)
输入图像 → CNN → 特征图 → RoI Pooling(固定尺寸) → FC → 分类+回归
↑
Selective Search候选框
改进: 整图只过1次CNN,RoI Pooling裁剪特征图
2.3 Faster R-CNN (2015) ⭐ - 里程碑
输入图像 → CNN(backbone) → 特征图
↓
RPN(区域建议网络)
┌───┴───┐
anchors 分类/回归
↓ ↓
RoI Align → FC → 分类+回归
RPN核心:
- 在特征图的每个位置放置k个anchor(3尺×3比=9)
- 每个anchor预测: 目标分数(二分类) + 4个微调偏移
- 训练时正负样本配比 1:1
Faster R-CNN变体:
| 变体 | 改进 | 年份 |
|---|---|---|
| Mask R-CNN | +分割分支(Head) | 2017 |
| Cascade R-CNN | 级联多级检测器 | 2018 |
| TridentNet | 多分支感受野 | 2019 |
| Libra R-CNN | 平衡采样 | 2019 |
| DetectoRS | 递归特征金字塔 | 2020 |
三、单阶段检测器 ⭐
3.1 YOLO系列 ⭐⭐⭐(最受关注)
| 版本 | 年份 | 作者 | 特点 |
|---|---|---|---|
| YOLOv1 | 2016 | Joseph Redmon | 将检测作为回归问题,直接预测网格 |
| YOLOv2 (YOLO9000) | 2016 | Joseph Redmon | 锚框+批归一化+9000类联合训练 |
| YOLOv3 | 2018 | Joseph Redmon | FPN+多尺度+Logistic分类 |
| YOLOv4 | 2020 | Alexey Bochkovskiy | CSPDarknet+Mish+CIoU+大量trick |
| YOLOv5 | 2020 | Ultralytics | PyTorch实现,生态最好 |
| YOLOX | 2021 | Megvii | 无锚框+解耦头+SimOTA |
| YOLOv6 | 2022 | 美团 | 硬件友好 |
| YOLOv7 | 2022 | 台湾中央 | E-ELAN结构,速度精度均衡 |
| YOLOv8 ⭐ | 2023 | Ultralytics | 多功能框架(检测/分割/姿态) |
| YOLOv9 | 2024 | 王昌硕 | PGI+GBELU,解决信息丢失 |
| YOLOv10 | 2024 | 清华 | NMS-free训练,端到端 |
| YOLO11 | 2024 | Ultralytics | 最新版,架构升级 |
| YOLO12 | 2025 | 注意力机制 | 关注效率,NMS-free优化 |
| YOLO13 | 2025 | Ultralytics | 最新版,架构升级 |
YOLOv3原理:
┌─────────────────┐
输入(416×416) → Darknet-53 backbone → FPN Neck → 3个尺度检测头
(带CSP结构) └─────────────────┘ │
├─ 13×13 (大物体)
├─ 26×26 (中物体)
└─ 52×52 (小物体)
每个网格预测: t_x, t_y, t_w, t_h, objectness, class_probs → 共 (4+1+C)个值
# YOLOv8推理 (Ultralytics官方库)
from ultralytics import YOLO
model = YOLO('yolov8n.pt') # n/s/m/l/x
results = model('image.jpg')
results[0].show()
results[0].save('output.jpg')
# 训练
model = YOLO('yolov8n.pt')
model.train(data='coco.yaml', epochs=100, imgsz=640)
3.2 SSD (2016)
| 特点 | 说明 |
|---|---|
| 多尺度检测 | 6个不同尺度的特征图 |
| 锚框 | 每个像素多个固定锚框 |
| VGG16 backbone | 替换FC→卷积 |
| 简单高效 | 速度与YOLOv1相当,精度更高 |
3.3 RetinaNet (2017) - Focal Loss
核心: Focal Loss解决类别不平衡(正负样本极端不平衡)
FL(p_t) = -α_t(1-p_t)^γ · log(p_t)
正样本: p_t→1 → 权重趋近0(容易样本不重要)
负样本: p_t→0.1 → 权重保持 (γ=2时, 权重=0.81倍FL)
γ=0 → Cross Entropy
γ=2 → 标准Focal Loss
3.4 单阶段vs两阶段对比
| 方面 | 两阶段(Faster R-CNN) | 单阶段(YOLO/SSD) |
|---|---|---|
| 速度 | 慢(5-10 FPS) | 快(30-200 FPS) |
| 精度 | 较高(AP~42) | 较高(AP~45+) |
| 小物体 | 更好 | 需要多尺度 |
| 正负平衡 | RPN预筛≈1:1 | 极端(1:1000+) |
| 复杂度 | 高(多组件) | 低(单网络) |
| 部署 | 复杂 | 方便 |
四、Anchor-Free检测器
4.1 CornerNet (2018)
- 检测左上角和右下角的关键点
- 配对corner embedding
4.2 CenterNet (2019)
- 关键点中心 + 尺寸回归
- 热力图预测物体中心
- 简单高效
4.3 FCOS (2019)
- 每个位置直接分类+回归4D向量(l, t, r, b)
- Center-ness分支抑制低质量检测
五、DETR与Transformer检测器 ⭐
5.1 DETR (2020) - 变革
核心创新:
- 检测=集合预测问题
- Transformer Encoder-Decoder架构
- Object Queries(可学习的100个向量)
- 匈牙利匹配算法做标签分配
- 去掉了NMS和锚框!
CNN Backbone → Transformer Encoder → Transformer Decoder → FFN → 100个预测
↑ ↑
位置编码 100× Object Queries
匈牙利匹配损失: L_match = L_cls + λ·L_box
5.2 DETR改进
| 模型 | 改进 | 年份 |
|---|---|---|
| Deformable DETR | 可变形注意力→更快收敛 | 2021 |
| DINO DETR | 对比去噪训练 | 2022 |
| RT-DETR | 实时DETR(YOLO级别速度) | 2023 |
| DDQ DETR | 密集查询 | 2023 |
六、开放词汇/零样本检测
| 模型 | 说明 | 链接 |
|---|---|---|
| GLIP | 将检测转化为短语定位 | Microsoft |
| Grounding DINO | 语言引导的检测 | IDEA |
| OWL-ViT | 开放词汇分类 | |
| YOLO-World | 开放词汇YOLO | Tencent |
七、实用框架对比
| 框架 | 语言 | 支持 | 特点 |
|---|---|---|---|
| Detectron2 | PyTorch | 主流模型 | Meta官方,API优雅 |
| MMDetection | PyTorch | 300+模型 | 最全,OpenMMLab |
| Ultralytics | PyTorch | YOLO全系 | 最简单易用 |
| Hugging Face | PyTorch/TF | Transformers | 检测+多模态 |
| MegEngine | MegEngine | YOLOX | 旷视自研 |
📺 推荐视频
| 内容 | 链接/搜索 |
|---|---|
| CS231n Lecture 10: Object Detection | CS231n Playlist |
| YOLO系列全解读 | B站搜 “YOLO 论文精读” |
| DETR论文精讲 (李沐) | B站搜 “DETR” |
| R-CNN家族史 | YouTube/B站 |
📚 论文必读清单
| 论文 | 年份 | 必读度 |
|---|---|---|
| Rich feature hierarchies for accurate object detection (R-CNN) | 2014 | ⭐⭐⭐⭐⭐ |
| Fast R-CNN | 2015 | ⭐⭐⭐⭐ |
| Faster R-CNN: Towards Real-Time Object Detection | 2015 | ⭐⭐⭐⭐⭐ |
| You Only Look Once (YOLOv1) | 2016 | ⭐⭐⭐⭐⭐ |
| SSD: Single Shot MultiBox Detector | 2016 | ⭐⭐⭐⭐ |
| Focal Loss for Dense Object Detection (RetinaNet) | 2017 | ⭐⭐⭐⭐ |
| Mask R-CNN | 2017 | ⭐⭐⭐⭐ |
| YOLOv3: An Incremental Improvement | 2018 | ⭐⭐⭐⭐⭐ |
| End-to-End Object Detection with Transformers (DETR) | 2020 | ⭐⭐⭐⭐⭐ |
| YOLOv4 | 2020 | ⭐⭐⭐⭐ |
| DINO: DETR with Improved DeNoising Anchor Boxes | 2022 | ⭐⭐⭐⭐ |
| YOLOv9: Learning What You Want to Learn | 2024 | ⭐⭐⭐⭐ |
🔗 最新进展关注 Papers With Code: https://paperswithcode.com/task/object-detection
3.5 检测器训练最新 Trick
1. DINO 的对比去噪训练(Denoising Training)
DINO(2022)将去噪训练引入 DETR 框架:
- 在训练时向 GT bbox 添加随机噪声生成 corrupted GT
- Decoder 需要从 corrupted 信号中恢复原始 GT,类似扩散模型
- 显著加速 DETR 收敛(从 300+ epochs → 12 epochs)
- 结合 Contrastive DeNoising(CDN)提高匹配质量
2. 多尺度特征对齐(Multi-Scale Feature Alignment)
现代检测器通过 FPN+PAN 的多尺度特征融合已成为标配,但不同尺度之间存在语义鸿沟:
- NAS-FPN:神经架构搜索最优拓扑
- BiFPN(EfficientDet):加权双向跨尺度连接
- GFPN(YOLOv9):跨尺度梯度路径更短
3. 端到端检测的新范式
自 DETR 以来,端到端(无需 NMS)成为趋势:
- RT-DETR(Baidu, 2023):实时 DETR,YOLO 级别速度
- YOLOv10(清华, 2024):Dual Label Assignment + Consistent Matching
- YOLO12(2025):Attention-based NMS-free
端到端优势:1) 推理管线简化 2) 无 NMS 超参 3) 密集场景更稳定
附录:深层补充
一、YOLO系列完整演进
YOLOv1(2016)— 开山之作
YOLOv1 将检测视为回归问题:将输入图像划分为 S × S S \times S S×S( S = 7 S=7 S=7)的 grid cell,每个 cell 预测 B B B 个 bbox( B = 2 B=2 B=2)和类别概率。
每个 bbox 预测: ( t x , t y , t w , t h , confidence ) (t_x, t_y, t_w, t_h, \text{confidence}) (tx,ty,tw,th,confidence),其中 confidence = P(obj) × IoU p r e d t r u t h \text{P(obj)} \times \text{IoU}_{pred}^{truth} P(obj)×IoUpredtruth。每个 grid cell 只预测 C C C 个类别概率。
损失函数:
L = λ coord ∑ i = 0 S 2 ∑ j = 0 B 1 i j obj [ ( x i − x ^ i ) 2 + ( y i − y ^ i ) 2 ] + λ coord ∑ i = 0 S 2 ∑ j = 0 B 1 i j obj [ ( w i − w ^ i ) 2 + ( h i − h ^ i ) 2 ] + ∑ i = 0 S 2 ∑ j = 0 B 1 i j obj ( C i − C ^ i ) 2 + λ noobj ∑ i = 0 S 2 ∑ j = 0 B 1 i j noobj ( C i − C ^ i ) 2 + ∑ i = 0 S 2 1 i obj ∑ c ∈ classes ( p i ( c ) − p ^ i ( c ) ) 2 \mathcal{L} = \lambda_{\text{coord}} \sum_{i=0}^{S^2} \sum_{j=0}^B \mathbb{1}_{ij}^{\text{obj}} \left[(x_i-\hat{x}_i)^2 + (y_i-\hat{y}_i)^2 \right] + \lambda_{\text{coord}} \sum_{i=0}^{S^2} \sum_{j=0}^B \mathbb{1}_{ij}^{\text{obj}} \left[(\sqrt{w_i}-\sqrt{\hat{w}_i})^2 + (\sqrt{h_i}-\sqrt{\hat{h}_i})^2 \right] + \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 L=λcoordi=0∑S2j=0∑B1ijobj[(xi−x^i)2+(yi−y^i)2]+λcoordi=0∑S2j=0∑B1ijobj[(wi−w^i)2+(hi−h^i)2]+i=0∑S2j=0∑B1ijobj(Ci−C^i)2+λnoobji=0∑S2j=0∑B1ijnoobj(Ci−C^i)2+i=0∑S21iobjc∈classes∑(pi(c)−p^i(c))2
局限: 每个 grid cell 只能检测一个物体;小物体检测差(7×7 grid 对细节不敏感);对遮挡和群体检测弱。
YOLOv2 / YOLO9000(2016)
关键创新:
- Anchor Box: 引入 anchor( k = 5 k=5 k=5),每个 cell 预测 5 个 anchor 的偏移
- 先验聚类(Dimension Priors): 用 K-means 从训练集中聚类 bbox 尺寸,距离度量用 d ( box , centroid ) = 1 − IoU ( box , centroid ) d(\text{box}, \text{centroid}) = 1 - \text{IoU}(\text{box}, \text{centroid}) d(box,centroid)=1−IoU(box,centroid),得到最适合当前数据集的 anchor
- Batch Normalization: 在所有卷积层后加 BN,mAP +2%
- High Resolution Classifier: 先用 448×448 微调分类网络(10 epoch),再在 448×448 上训练检测
- PassThrough 层: 将 26×26×512 的特征重新排列为 13×13×2048,保留细粒度信息
- Darknet-19 backbone
YOLOv3(2018)
创新:
- FPN 多尺度预测: 3 个检测头(13×13, 26×26, 52×52),分别负责大/中/小物体
- 多标签分类: 用 Logistic Regression 替代 Softmax,支持多标签(如 “woman” + “person”)
- Darknet-53 backbone: 受 ResNet 启发引入残差连接,相比 Darknet-19 更深
- 9 个 anchor 的先验: 每个尺度 3 个 anchor(通过 K-means 在 COCO 上聚类)
mAP 提升: 在 COCO 上 mAP@0.5 达到 57.9%,速度 20 FPS(Titan X)。
YOLOv4(2020)
两大部分:
Bag of Freebies(免费提升,不增加推理成本):
- Mosaic 数据增强(4 张图拼接)
- CutMix + MixUp
- Label Smoothing
- CIoU Loss + DIoU NMS
- DropBlock 正则化
Bag of Specials(增加少量推理成本,换大幅提升):
- Mish 激活函数
- CSPDarknet53 backbone(Cross Stage Partial,减少冗余梯度计算)
- SPP(Spatial Pyramid Pooling)模块
- PANet(Path Aggregation Network)neck
- SAM(Spatial Attention Module)
mAP: COCO AP 43.5%(YOLOv3 的 33%),速度 65 FPS。
YOLOv5 / v8 / v10 的差异
| 版本 | 核心差异 | 关键特性 |
|---|---|---|
| YOLOv5(Ultralytics, 2020) | Focus 层 + GIOU Loss + PyTorch 生态 | 首创 n/s/m/l/x 多尺度;自动锚框学习;易于部署 |
| YOLOv8(Ultralytics, 2023) | 解耦头 + Anchor-Free | 每个位置直接回归 w, h 替代 anchor;C2f 模块替代 C3;分类/回归/分割共享 backbone 但独立 head |
| YOLOv10(清华, 2024) | NMS-free | 使用 Dual Label Assignment + Consistent Matching 实现端到端检测,推理时无需 NMS |
| YOLOv11(Ultralytics, 2024) | 架构升级 | C2f 改进,更高效 backbone,多任务统一框架 |
| YOLOv12(2025) | Attention-based | 引入注意力机制的核心改进,NMS-free 持续优化 |
| YOLOv13(Ultralytics, 2025) | 最新版 | 进一步精简架构,训练加速,强数据增强集成 |
二、Faster R-CNN 详解
2.1 RPN 的 Anchor 机制
RPN(Region Proposal Network)在特征图的每个位置放置 k k k 个 anchor( k = 9 k=9 k=9:3 种 scale( 128 2 , 256 2 , 512 2 128^2, 256^2, 512^2 1282,2562,5122) × 3 种 ratio( 1 : 1 , 1 : 2 , 2 : 1 1:1, 1:2, 2:1 1:1,1:2,2:1))。
对于 H × W H \times W H×W 的特征图,共 H × W × k H \times W \times k H×W×k 个 anchor。每个 anchor 对应:
- 二分类分支: 2 个输出(前景/背景概率)→ 共 k × 2 k \times 2 k×2 个输出
- 回归分支: 4 个偏移量 ( t x , t y , t w , t h ) (t_x, t_y, t_w, t_h) (tx,ty,tw,th) → 共 k × 4 k \times 4 k×4 个输出
回归目标编码:
t x = ( x − x a ) / w a , t y = ( y − y a ) / h a t_x = (x - x_a) / w_a, \quad t_y = (y - y_a) / h_a tx=(x−xa)/wa,ty=(y−ya)/ha
t w = log ( w / w a ) , t h = log ( h / h a ) t_w = \log(w / w_a), \quad t_h = \log(h / h_a) tw=log(w/wa),th=log(h/ha)
解码(推理时):
x = t x ⋅ w a + x a , y = t y ⋅ h a + y a x = t_x \cdot w_a + x_a, \quad y = t_y \cdot h_a + y_a x=tx⋅wa+xa,y=ty⋅ha+ya
w = w a ⋅ exp ( t w ) , h = h a ⋅ exp ( t h ) w = w_a \cdot \exp(t_w), \quad h = h_a \cdot \exp(t_h) w=wa⋅exp(tw),h=ha⋅exp(th)
2.2 RPN 损失函数
L R P N = 1 N c l s ∑ i L c l s ( p i , p i ∗ ) + λ 1 N r e g ∑ i p i ∗ ⋅ L r e g ( t i , t i ∗ ) \mathcal{L}_{RPN} = \frac{1}{N_{cls}} \sum_i \mathcal{L}_{cls}(p_i, p_i^*) + \lambda \frac{1}{N_{reg}} \sum_i p_i^* \cdot \mathcal{L}_{reg}(t_i, t_i^*) LRPN=Ncls1i∑Lcls(pi,pi∗)+λNreg1i∑pi∗⋅Lreg(ti,ti∗)
- 分类损失: 二分类交叉熵 L c l s ( p i , p i ∗ ) = − [ p i ∗ log p i + ( 1 − p i ∗ ) log ( 1 − p i ) ] \mathcal{L}_{cls}(p_i, p_i^*) = -[p_i^* \log p_i + (1-p_i^*) \log(1-p_i)] Lcls(pi,pi∗)=−[pi∗logpi+(1−pi∗)log(1−pi)]
- 回归损失: Smooth L1 Loss
Smooth L 1 ( x ) = { 0.5 x 2 if ∣ x ∣ < 1 ∣ x ∣ − 0.5 otherwise \text{Smooth}_{L1}(x) = \begin{cases} 0.5x^2 & \text{if } |x| < 1 \\ |x| - 0.5 & \text{otherwise} \end{cases} SmoothL1(x)={0.5x2∣x∣−0.5if ∣x∣<1otherwise
Smooth L1 相比 L2 Loss 对大误差的梯度更温和(线性而非平方),训练更稳定。
Anchor 的正负样本分配:
- 正样本: 与任意 GT bbox 的 IoU > 0.7,或与 GT 的 IoU 最大(即使 < 0.7)
- 负样本: 与所有 GT bbox 的 IoU < 0.3
- 无关:IoU 在 [0.3, 0.7] 之间,不参与训练
- 每张图采样 256 个 anchor,正负样本比例 1:1
2.3 RoI Pooling vs RoI Align
RoI Pooling(Fast R-CNN): 将任意大小的 RoI 区域量化为固定尺寸(如 7×7)的特征
- 将 RoI 坐标量化到整数(浮点数→取整)
- 将量化后的区域均匀分成 k × k k \times k k×k 个 bin
- 每个 bin 做 Max Pooling
问题: 两次量化误差(坐标取整 + bin 划分取整),累计可达 10+ 像素,对小物体和像素级分割任务(Mask R-CNN)伤害极大。
RoI Align(Mask R-CNN): 用双线性插值避免量化
- 不量化坐标:保持浮点数精度
- 将 RoI 均匀分成 k × k k \times k k×k 个 bin
- 在每个 bin 中取 4 个均匀采样点( 2 × 2 2 \times 2 2×2),对每个采样点用双线性插值计算特征值
- 对每个 bin 的 4 个采样点做 Max(或 Average)Pooling
双线性插值公式:
给定四个角点 Q 11 , Q 12 , Q 21 , Q 22 Q_{11}, Q_{12}, Q_{21}, Q_{22} Q11,Q12,Q21,Q22,在点 ( x , y ) (x, y) (x,y) 处的特征值:
f ( x , y ) ≈ ( x 2 − x ) ( y 2 − y ) ( x 2 − x 1 ) ( y 2 − y 1 ) f ( Q 11 ) + ( x − x 1 ) ( y 2 − y ) ( x 2 − x 1 ) ( y 2 − y 1 ) f ( Q 12 ) + ( x 2 − x ) ( y − y 1 ) ( x 2 − x 1 ) ( y 2 − y 1 ) f ( Q 21 ) + ( x − x 1 ) ( y − y 1 ) ( x 2 − x 1 ) ( y 2 − y 1 ) f ( Q 22 ) f(x,y) \approx \frac{(x_2-x)(y_2-y)}{(x_2-x_1)(y_2-y_1)} f(Q_{11}) + \frac{(x-x_1)(y_2-y)}{(x_2-x_1)(y_2-y_1)} f(Q_{12}) + \frac{(x_2-x)(y-y_1)}{(x_2-x_1)(y_2-y_1)} f(Q_{21}) + \frac{(x-x_1)(y-y_1)}{(x_2-x_1)(y_2-y_1)} f(Q_{22}) f(x,y)≈(x2−x1)(y2−y1)(x2−x)(y2−y)f(Q11)+(x2−x1)(y2−y1)(x−x1)(y2−y)f(Q12)+(x2−x1)(y2−y1)(x2−x)(y−y1)f(Q21)+(x2−x1)(y2−y1)(x−x1)(y−y1)f(Q22)
RoI Align 对实例分割的 mAP 提升约 2-3 个点。
三、DETR 与 Transformer 检测
3.1 匈牙利算法匹配原理
DETR 的核心是将检测建模为集合预测问题,预测一个固定大小( N = 100 N=100 N=100)的无序集合,通过二分图匹配(匈牙利算法)与 GT 进行最优匹配。
Hungarian Algorithm(也称 Kuhn-Munkres 算法)用于求解二分图的最小代价匹配:
- 构造代价矩阵 C ∈ R N × M C \in \mathbb{R}^{N \times M} C∈RN×M( N N N 个预测, M M M 个 GT, M ≤ N M \leq N M≤N)
- 对每个 GT,在 N N N 个预测中找到唯一匹配,使得总匹配代价最小
- 时间复杂度 O ( N 3 ) O(N^3) O(N3),但 DETR 的 N = 100 N=100 N=100,可接受
匹配代价:
L m a t c h ( y i , y ^ σ ( i ) ) = − 1 { c i ≠ ∅ } p ^ σ ( i ) ( c i ) + 1 { c i ≠ ∅ } L box ( b i , b ^ σ ( i ) ) \mathcal{L}_{match}(y_i, \hat{y}_{\sigma(i)}) = -\mathbb{1}_{\{c_i \neq \varnothing\}} \hat{p}_{\sigma(i)}(c_i) + \mathbb{1}_{\{c_i \neq \varnothing\}} \mathcal{L}_\text{box}(b_i, \hat{b}_{\sigma(i)}) Lmatch(yi,y^σ(i))=−1{ci=∅}p^σ(i)(ci)+1{ci=∅}Lbox(bi,b^σ(i))
其中负对数分类概率 − p ^ ( c ) -\hat{p}(c) −p^(c) 代表分类代价, L box \mathcal{L}_\text{box} Lbox 是回归代价(L1 + GIoU 的组合)。
3.2 DETR 的 Set Prediction Loss
找到最优匹配 σ ∗ = arg min σ ∑ i L m a t c h \sigma^* = \arg\min_\sigma \sum_i \mathcal{L}_{match} σ∗=argminσ∑iLmatch 后,训练损失为:
L H u n g a r i a n ( y , y ^ ) = ∑ i = 1 N [ − log p ^ σ ∗ ( i ) ( c i ) + 1 { c i ≠ ∅ } L b o x ( b i , b ^ σ ∗ ( i ) ) ] \mathcal{L}_{Hungarian}(y, \hat{y}) = \sum_{i=1}^N \left[-\log \hat{p}_{\sigma^*(i)}(c_i) + \mathbb{1}_{\{c_i \neq \varnothing\}} \mathcal{L}_{box}(b_i, \hat{b}_{\sigma^*(i)})\right] LHungarian(y,y^)=i=1∑N[−logp^σ∗(i)(ci)+1{ci=∅}Lbox(bi,b^σ∗(i))]
类别不平衡处理: 对 ∅ \varnothing ∅(无物体)的损失做 10 倍降权( 1 10 \frac{1}{10} 101)。
Box Loss: L box ( b i , b ^ σ ( i ) ) = λ L1 ∣ ∣ b i − b ^ σ ( i ) ∣ ∣ 1 + λ GIoU L GIoU ( b i , b ^ σ ( i ) ) \mathcal{L}_\text{box}(b_i, \hat{b}_{\sigma(i)}) = \lambda_{\text{L1}} ||b_i - \hat{b}_{\sigma(i)}||_1 + \lambda_{\text{GIoU}} \mathcal{L}_{\text{GIoU}}(b_i, \hat{b}_{\sigma(i)}) Lbox(bi,b^σ(i))=λL1∣∣bi−b^σ(i)∣∣1+λGIoULGIoU(bi,b^σ(i))
GIoU 损失(Generalized IoU):
L G I o U = 1 − IoU + ∣ C \ ( A ∪ B ) ∣ ∣ C ∣ \mathcal{L}_{GIoU} = 1 - \text{IoU} + \frac{|C \backslash (A \cup B)|}{|C|} LGIoU=1−IoU+∣C∣∣C\(A∪B)∣
其中 C C C 是 A A A 和 B B B 的最小外接矩形。GIoU 解决了 IoU 在无重叠区域梯度为 0 的问题。
3.3 为什么 DETR 收敛慢
DETR 在 COCO 上需要 300~500 epochs 才能收敛,比 Faster R-CNN(~12 epochs)慢 25 倍以上。原因:
- Cross-Attention 从头学习: 200 万的 ImageNet 预训练只训练了 CNN backbone,Encoder 和 Decoder 的 Transformer 是从随机初始化的,需要大量 epoch 来学习注意力的空间对应关系
- 匈牙利匹配不稳定: 训练初期匹配的对象频繁切换(匹配不稳定问题),导致梯度方向波动
- Object Queries 学习慢: 100 个 object queries 需要学习到不同位置和尺度的先验,这需要长时间的自注意力交互
- 对小物体不友好: 标准多头注意力的全局感受野对小物体的响应较弱,需要更多 epoch 学习细粒度特征
Deformable DETR 的改进:将 Cross-Attention 替换为 Deformable Attention(只关注每个 query 的 K = 4 K=4 K=4 个参考点的 N k = 4 N_k=4 Nk=4 个采样点,共 4 × 4 = 16 4\times4=16 4×4=16 个点),从 O ( H W ) O(HW) O(HW) 降低到 O ( 1 ) O(1) O(1),收敛速度提升 10 倍。
四、检测中的 Trick 大合集
4.1 多尺度训练 / 测试
多尺度训练(MST): 每个 epoch 随机从预定义的尺度池中选一个尺度缩放输入图像。如 [480, 512, 544, 576, 608, 640, 672, 704, 736, 768, 800]。
多尺度测试(MSTest): 推理时对图像做多个尺度的缩放,分别推理后合并结果。
- 合并方式:将所有尺度的检测结果进行 NMS 融合
- 约提升 1-3% mAP,代价是推理速度倍数增加
4.2 Soft-NMS
Greedy NMS 直接将 IoU > 阈值 N t N_t Nt 的框分数置零(粗暴丢弃)。Soft-NMS 改为对相邻框的分数做衰减:
线性加权:
s i = s i ⋅ ( 1 − IoU ( M , b i ) ) if IoU ( M , b i ) ≥ N t s_i = s_i \cdot (1 - \text{IoU}(M, b_i)) \quad \text{if } \text{IoU}(M, b_i) \geq N_t si=si⋅(1−IoU(M,bi))if IoU(M,bi)≥Nt
高斯加权:
s i = s i ⋅ e − IoU ( M , b i ) 2 σ σ 通常取 0.5 s_i = s_i \cdot e^{-\frac{\text{IoU}(M, b_i)^2}{\sigma}} \quad \sigma \text{ 通常取 } 0.5 si=si⋅e−σIoU(M,bi)2σ 通常取 0.5
Soft-NMS 的改进:NMS 暴力移除相邻框的问题在于——相邻的框可能属于真实的不同物体(如人群密集场景)。Soft-NMS 让被重叠框的分数平滑衰减,相邻的真实正例仍有机会被保留。mAP@0.5 提升约 1-2%。
4.3 DIoU / CIoU Loss
DIoU Loss: 在 IoU 基础上加入中心点距离:
L D I o U = 1 − IoU + ρ 2 ( b , b g t ) c 2 \mathcal{L}_{DIoU} = 1 - \text{IoU} + \frac{\rho^2(b, b^{gt})}{c^2} LDIoU=1−IoU+c2ρ2(b,bgt)
其中 ρ ( ⋅ ) \rho(\cdot) ρ(⋅) 是欧氏距离, c c c 是两个 bbox 最小外接矩形的对角线长度。
为什么 DIoU 优于 IoU?
- IoU 在两个框不重叠时梯度为 0(无回传信号)
- DIoU 的中心点距离项提供梯度信号,即使不重叠也能向 GT 靠拢
- DIoU 直接优化 bbox 中心点对齐,回归更精确
CIoU Loss: 在 DIoU 基础上增加宽高比惩罚:
L C I o U = 1 − IoU + ρ 2 ( b , b g t ) c 2 + α v \mathcal{L}_{CIoU} = 1 - \text{IoU} + \frac{\rho^2(b, b^{gt})}{c^2} + \alpha v LCIoU=1−IoU+c2ρ2(b,bgt)+αv
其中 v = 4 π 2 ( arctan w g t h g t − arctan w h ) 2 v = \frac{4}{\pi^2}\left(\arctan\frac{w^{gt}}{h^{gt}} - \arctan\frac{w}{h}\right)^2 v=π24(arctanhgtwgt−arctanhw)2 衡量宽高比一致性, α = v ( 1 − IoU ) + v \alpha = \frac{v}{(1-\text{IoU}) + v} α=(1−IoU)+vv 是平衡系数。
CIoU 是目前 YOLOv4+ 的主流回归损失。
4.4 Label Assignment
标签分配策略决定了哪些 anchor/query 作为正样本,哪些作为负样本。
| 方法 | 原理 | 特点 |
|---|---|---|
| ATSS(Adaptive Training Sample Selection, 2020) | 对每个 GT,选择 k 个与它 IoU 最大的 anchor 作为候选正样本;计算这些候选的 IoU 均值和标准差,IoU > 均值+标准差 的为正样本。每个 GT 的阈值是自适应的 | 无需手动设置阈值;比 RetinaNet 的固定 IoU 阈值好 |
| OTA(Optimal Transport Assignment, 2021) | 将标签分配建模为最优传输问题(Sinkhorn-Knopp 算法):supply = 每个 GT 需要多少正样本(动态确定),demand = 每个 anchor 的有用程度。最小化传输代价 | 全局最优分配,效果最好但计算量大 |
| SimOTA(YOLOX, 2021) | OTA 的简化版:近似 OTA 的求解过程,Top-K 挑选策略替代 Sinkhorn 迭代 | OTA 精度 × YOLO 速度,YOLOX 的核心技术之一 |
4.5 Focal Loss 推导
正负样本极端不平衡(RetinaNet 场景): 一张图中负样本(背景)往往占 99.9% 以上。标准交叉熵让大量容易的负样本主导梯度。
Focal Loss 通过降低易分类样本的损失权重来解决:
F L ( p t ) = − ( 1 − p t ) γ log ( p t ) FL(p_t) = -(1 - p_t)^\gamma \log(p_t) FL(pt)=−(1−pt)γlog(pt)
其中 p t p_t pt 定义为:
- p t = p p_t = p pt=p 当 y = 1 y=1 y=1(正样本)
- p t = 1 − p p_t = 1-p pt=1−p 当 y = 0 y=0 y=0(负样本)
推导:
标准交叉熵: C E ( p t ) = − log ( p t ) CE(p_t) = -\log(p_t) CE(pt)=−log(pt)
加上调制因子 ( 1 − p t ) γ (1-p_t)^\gamma (1−pt)γ:
- 当 p t → 1 p_t \to 1 pt→1(易分类样本), ( 1 − p t ) γ → 0 (1-p_t)^\gamma \to 0 (1−pt)γ→0,损失几乎为 0
- 当 p t → 0 p_t \to 0 pt→0(难分类样本), ( 1 − p t ) γ → 1 (1-p_t)^\gamma \to 1 (1−pt)γ→1,损失几乎不变
加上类别平衡权重 α t \alpha_t αt:
F L ( p t ) = − α t ( 1 − p t ) γ log ( p t ) FL(p_t) = -\alpha_t (1-p_t)^\gamma \log(p_t) FL(pt)=−αt(1−pt)γlog(pt)
常用配置: γ = 2 \gamma=2 γ=2, α = 0.25 \alpha=0.25 α=0.25(负样本权重降低到正样本的 0.75 0.25 = 3 \frac{0.75}{0.25}=3 0.250.75=3 倍而非极端不平衡)。
五、非极大值抑制(NMS)的各种变体
| NMS 变体 | 核心思想 | 公式/伪码 | 特点 |
|---|---|---|---|
| Greedy NMS | 选最高分框,删除与其 IoU > 阈值的框 | if IoU > thresh → discard \text{if IoU > thresh} \to \text{discard} if IoU > thresh→discard | 简单粗暴,相邻同类物体被误删 |
| Soft NMS | 不删除,只降分 | s i = s i ⋅ e − IoU ( M , b i ) 2 / σ s_i = s_i \cdot e^{-\text{IoU}(M,b_i)^2/\sigma} si=si⋅e−IoU(M,bi)2/σ | 保留相邻真例,mAP +1-2% |
| Softer NMS | 加权平均融合框 | x ^ = ∑ i x i / σ i 2 ∑ i 1 / σ i 2 \hat{x} = \frac{\sum_i x_i / \sigma_i^2}{\sum_i 1/\sigma_i^2} x^=∑i1/σi2∑ixi/σi2 | 利用定位标准差信息融合,定位更准 |
| IoU-guided NMS | 用 IoU 分数替代分类分数排序 | order = IoU score.argsort() \text{order} = \text{IoU}\text{ score.argsort()} order=IoU score.argsort() | 避免分类分数高但定位差的框主导 |
| Weighted NMS | 对重叠框的坐标加权平均 | x = ∑ s i ⋅ x i ∑ s i x = \frac{\sum s_i \cdot x_i}{\sum s_i} x=∑si∑si⋅xi | 融合而非选择,密度高时效果好 |
| DIoU NMS | NMS 标准加入中心点距离惩罚 | s i = s i ⋅ f ( DIoU ( M , b i ) − N t ) s_i = s_i \cdot f(\text{DIoU}(M,b_i) - N_t) si=si⋅f(DIoU(M,bi)−Nt) | DIoU 距离更合理,相邻物体保留好 |
| Matrix NMS | 矩阵操作并行化 | 所有框对的 IoU 矩阵 + 递降公式 | 可 GPU 并行,速度提升 |
| Cluster NMS | 聚类的启发式合并 | 图论中连通分量 | 无超参,自动聚类 |
| NMS-free(YOLOv10/OneNet) | 不需要后处理 | Dual Label Assignment / One-to-One matching | 端到端,推理时无需 NMS,速度大提升 |
NMS 计算量对比:
对于 n n n 个检测框:
- Greedy NMS: O ( n 2 ) O(n^2) O(n2)(每轮计算所有框对 IoU)
- Soft NMS: O ( n 2 ) O(n^2) O(n2) 同上
- Matrix NMS: O ( n log n ) O(n \log n) O(nlogn) 矩阵并行
- NMS-free: O ( 1 ) O(1) O(1) 无后处理
更多推荐




所有评论(0)