TT Lab
博客

한국어 English 日本語 中文

开始
博客

博客

DETR: 将检测视为集合预测,匈牙利匹配与无锚框检测

状态:草稿 (2026-10-13),部分实测。 匈牙利与 GIoU 示例是在笔记本电脑 CPU 上直接运行的值(code/08_hungarian.py, 1秒以内)。论文数值采用原文数据并连同条件一并搬运,硬件则按级别记录。 写作规则:以实测数据为基础,未能测出的标记为“未实测”。

目录

1. 人工设计的组件

在第 5、6 篇的检测器中,有许多人工设定的组件。包括锚框的大小和比例、为锚框附加正负样本标签的 IoU 阈值、用于消除重复的 NMS 及其阈值。这些组件如果设定得好就能运作,但如果数据发生变化就得重新设定,如果设定错误就会悄悄产生漏洞(第 5 篇的“0 个正样本”、“删除了选手 B 的 NMS”)。

Carion 等人的 DETR (DEtection TRansformer) 改变了问题。检测的正确答案是 边界框的集合。它没有顺序,也没有重复。既然如此,如果模型从一开始就 输出集合 进行训练,是不是就不需要锚框和 NMS 了呢?

2. 架构:N 个查询槽

DETR: 질의 N개가 상자를 내고, 정답과 1:1 로 짝짓는다 CNN 몸통 특징 지도 트랜스포머 인코더 · 디코더 질의 슬롯 N=100개 슬롯 0: 선수 슬롯 1: 없음 슬롯 2: 공 슬롯 3: 없음 슬롯 4: 선수 슬롯 5: 없음 선수 A 선수 B 공 짝이 없는 슬롯(1·3·5)은 「물체 없음」을 배운다. 짝짓기: 비용(클래스 확률 + L1 + GIoU)의 합이 가장 작게(헝가리안). 짝이 하나뿐이라 NMS 가 필요 없다. → 학습 때만 정답과 짝짓기, 추론 때는 「없음」이 아닌 슬롯을 그대로 출력
图:经过 CNN 主干网络和 Transformer 的查询槽各自输出边界框,并在训练时与正确答案进行 1:1 配对的 DETR
  1. CNN 主干网络(如 ResNet-50 等)生成特征图。
  2. Transformer 编码器通过自注意力机制混合特征图各个位置之间的关系(第 7 篇)。
  3. Transformer 解码器输入了参与训练的 N=100 个查询槽。每个槽通过交叉注意力机制查看编码器输出,并通过自注意力机制查看彼此。
  4. 每个槽上的小型 MLP 输出 类别(包含“无物体”)和一个边界框。

槽与槽之间能够互相查看这一点很重要。由于可以在网络内部学习到“那个物体由相邻的槽负责了,所以我来负责别的”,因此消除了消除重复所需的 NMS。实际上,论文报告称如果在最后一层输出上应用 NMS,AP 反而会稍微下降。

3. 训练:1:1 配对

输出有 100 个,正确答案通常有几个。应该将哪个输出与哪个正确答案进行比较来计算损失呢?DETR 寻找的是 成本最小的 1:1 配对。

짝 비용(정답 i, 슬롯 j) = −p_j(정답 i 의 클래스) + 5 · L1(상자) + 2 · (1 − GIoU(상자))

(权重 λ_L1 = 5, λ_iou = 2 为论文中的值。)一旦配对确定,配对的槽学习正确的类别和边界框,未配对的槽学习“无物体”。由于“无物体”对应绝大多数槽,因此将其损失减少到十分之一(与第 4 篇 focal loss 相同的不平衡问题)。解码器的所有层输出也都应用了相同的配对损失,并设置了辅助损失。

这种配对是经典的 分配问题,通过库恩(Kuhn)于 1955 年提出的 匈牙利算法来解决。

GIoU:不重叠也能告知距离

如果两个边界框不重叠,IoU 无论多远都是 0。如果用作损失,则没有梯度。 GIoU(广义交并比,Generalized IoU)使用包围两个边界框的最小框 C,减去“C 内的空白空间”部分。

GIoU = IoU − |C 에서 두 상자의 합집합을 뺀 넓이| / |C|      (−1 ~ 1)

手算结果如下(实测)。

正确答案 (0,0,10,10) 对比 IoU GIoU
(0,0,10,10) 相同 1.000 +1.000
(5,0,15,10) 半重叠 0.333 +0.333
(12,0,22,10) 相隔 2 格 0.000 −0.091
(30,0,40,10) 相隔 20 格 0.000 −0.500

IoU 均为 0,但 GIoU 越远越小。从而产生了将边界框拉向正确答案方向的梯度。

4. 亲自尝试:匈牙利算法

贪心法不行的原因

这是两名选手重叠站立场景中三个槽的成本。槽 0 跨在两名选手之间,与两者都算契合;槽 1 仅与选手 A 契合;槽 2 与选手 B 相当契合。

          슬롯 0   슬롯 1   슬롯 2
선수 A     0.9      1.0      6.0
선수 B     0.8      6.0      3.0

如果“按顺序从剩余槽中选择对每个正确答案最便宜的”,A 先拿走槽 0 (0.9),B 接受槽 2 (3.0),总成本为 3.9 。匈牙利算法找到的是 A–槽 1、B–槽 0,总成本为 1.8 (实测)。先选择的一方获胜的方式从整体来看可能会吃亏。如果在训练中使用贪心配对,槽 2 就会错误地学习选手 B,而槽 1 会学习“无物体”。

实现与验证

我们用 numpy 直接编写了使用势能(对偶变量)的 O(n²m) 版本(正确答案 n ≤ 槽 m)。核心在于“逐个增加配对,但如果存在能通过改变现有配对来降低成本的更便宜路径(增广路径),则沿着该路径反转配对”。

确认 结果(实测)
在 200 个随机 4×7 问题中,总成本与排列组合穷举完全一致 200/200
正确答案 10 × 槽 100 0.2ms
正确答案 50 × 槽 100 1.4ms
正确答案 100 × 槽 100 8.1ms
正确答案 300 × 槽 300 67.6ms

如果用排列组合全部看一遍,仅正确答案 10 × 槽 100 的组合数就达到 6.3×10¹⁹。匈牙利系列算法在多项式时间内(呈 n³ 形式)求解。DETR 的一张图(几十个正确答案 × 100 个槽)在毫秒级,因此不会成为训练的瓶颈。在实际业务中,经常使用 SciPy 的 linear_sum_assignment(修改后的 Jonker–Volgenant 算法)。

使用 DETR 的公式成本(类别概率 + 5·L1 + 2·(1−GIoU))将 3 个正确答案(两名选手、球)与 6 个槽进行配对时,每个正确答案都会附加到最合理的槽上,其余 3 个槽则分配为“无物体”(code/08_hungarian.out.txt).

5. 论文数值

模型(COCO 验证) AP 小物体 AP_S 大物体 AP_L 参数量 GFLOPs FPS
Faster R-CNN-FPN+(R50) 42.0 26.6 53.4 4,200万 180 26
DETR(R50) 42.0 20.5 61.1 4,100万 86 28

(论文表 1。Faster R-CNN 侧是带有 GIoU 损失、随机裁剪增强、约 109 个 epoch 的强化版。速度通过 TorchScript 模型测得,未明确指定 GPU。)

6. 后续研究:减少弱点

模型 改动之处 数值(论文,COCO)
Deformable DETR(2021) 用只看基准点周围 几个采样点 (K=4) 的注意力代替全局注意力。使用多种分辨率 50 epoch 43.8 AP,AP_S 26.4(DETR 500 epoch 20.5)。训练 GPU 时间 325 对 2,000
DN-DETR(2022) 向正确答案边界框加入噪声并输入解码器,使其恢复原始边界框的 去噪训练 — 绕过不稳定的配对 在相同设置下 +1.9 AP,以一半的 epoch 获得相近的准确率
DINO(2023) 强化去噪训练 + 改进查询初始化 ResNet-50 12 epoch 49.4 AP,24 epoch 51.3 AP。Swin-L + Objects365 预训练达到 test-dev 63.3 AP
RT-DETR(2024) 面向实时的混合编码器 R50 53.1 AP,108fps(推理用数据中心 GPU,TensorRT FP16,640×640)。Apache-2.0

DETR 的“集合预测 + 1:1 配对”成为了后来检测的标准工具。第 6 篇中 YOLOv10 去除 NMS 的方法(一对一检测头)以及第 11 篇中 SAM 3 的检测器(DETR 系列)也都是基于这一思想。

7. 局限性与我们的项目

从下一篇文章开始是分割。这是只需点击一下即可涂抹任何内容的 Segment Anything (SAM)。

Titi 小贴士。 依次选择最便宜的是 3.9,而匈牙利算法是 1.8。先选的人拿走所有东西的方式在团体赛中是吃亏的。

参考文献

登录后即可点赞

评论

还没有评论。

登录后即可发表评论