4.6 DETR用Transformer做端到端检测

1.检测里那些人工搭的脚手架

说起来,我们在前面4.3 节讲目标检测的时候,已经聊过R-CNN家族和YOLO那一套了。这一类检测器要工作起来,离不开工匠事先搭好的几件零件,其中最显眼的两件,一件叫anchor,一件叫NMS。anchor中文常译成先验框,说的是在图像的每个位置预先摆放的一大堆形状大小各异的参考框,模型做的事其实是在这些参考框的基础上做微调,预测每个框里有没有物体、物体的类别是什么,再把框的坐标往更准的位置挪一挪。NMS是非极大值抑制的缩写,意思是同一物体常常被好几个位置上的anchor同时预测到,于是会画出好几个重叠的框,NMS负责把那些和最高分框重叠得太多的多余框删掉,只留下一个最像样的。

这几件零件用起来确实管用,工业界跑了很多年都很稳。可它们也带着一些麻烦。anchor的数量、形状、大小都得人来定,定得好不好直接关系到最终精度。NMS里那个判断框是否重叠的阈值,也得靠人去调。说穿了,检测流程里有不少环节是工程师凭经验拍板的,并不是从数据里直接学出来的。

到了2020年,Meta(当时还叫Facebook)的一群研究者就想,能不能把这一摊子手工零件全部拿掉,做一个干干净净的端到端检测器。端到端的意思是,模型从输入图像直接给出最终的检测框,中间不再插进任何人设计的后处理环节。这篇论文就是DETR,全称DEtection TRansformer,名字本身就把它要做的事说清楚了,把检测和Transformer接到一块儿。

2.DETR的结构:从一张图到一组框

DETR的结构其实挺清爽,主要分成三段。

第一段是一个CNN(卷积神经网络)做骨干网络,负责从输入图像里提特征。我们在3.3 节细讲过CNN,它一层一层地把图像压缩成一张更小但更厚的特征图。骨干网络常常直接拿ImageNet上预训练过的ResNet-50来用。一张 H0×W0H_0\times W_0 的输入图像经过骨干之后,会得到一张空间分辨率大为缩小、通道数很多的特征图,我们把这张特征图的高记作 HH ,宽记作 WW ,通道数记作 CCCC 表示每个空间位置上特征向量的维度。

第二段是Transformer的编码器和解码器。Transformer我们在3.8 节细聊过,它最擅长处理一串向量。可骨干出来的特征图是二维的,得先把它展平成一串向量才行。DETR的做法是把特征图按空间位置一个一个摊开,每个空间位置上的特征向量当成一个token,一共 HWH\cdot W 个token,再给每个token加上一个位置编码,告诉模型这个token原本在图上的什么位置。位置编码之所以必要,是因为Transformer自身的注意力运算是没有顺序概念的,哪先哪后它分不出来,得额外把位置信息补回去。这里 \cdot 就是普通的乘法, HWH\cdot W 表示高和宽相乘之后token的总个数。展平之后的这串token送进Transformer编码器,编码器用一个自注意力让这些token彼此互相看一眼,把全局关系建起来,再交给解码器。

第三段是解码器输出固定数量的预测框。这里是DETR和以往检测器最不一样的地方。它直接输出固定数量的预测,不再依赖anchor,也不在图的每个位置逐个画框,论文里这个数量记作 NN ,常常取 N=100N=100 或者 N=300N=300 。每一个预测都对应一个框的坐标和一个类别的概率分布。打个比方,这有点像一个工厂里固定安排了一百个工位,每个工位都得汇报自己看见的东西,要么报某一种类别的物体加上框的坐标,要么报这一格什么都没有。什么都没有这一类,专门起个名字叫背景类,记作 \varnothing\varnothing 是空集的符号,在这里表示这个工位没有认领任何物体。

3.匈牙利匹配:一对一配对才能逼出不重复

输出固定数量的框听起来痛快,可麻烦立刻来了。我们手里一共有 NN 个预测框,但一张图里真正有的物体(真实框)通常只有几个,比方说三个。我们怎么知道这 NN 个预测框里,哪三个该去对那三个真实框负责,剩下的该去报背景类呢。更要紧的是,模型得被教会一件规矩,就是一个物体只能被一个预测框认领,绝不能好几个预测框都去抢同一个物体,否则最后画出来还是一堆重叠的框,NMS就又得请回来了。

DETR的解法是借来一个图论里的老算法,叫匈牙利算法,做的事情叫二分图匹配。二分图的意思是,左边的点只能和右边的点配对,左边内部、右边内部都不配。这里左边我们放上 NN 个预测框,右边放上 MM 个真实框( MM 表示图里真实物体的个数,通常 MNM\ll N\ll 表示远小于),再往右边补上一些空位(就是 \varnothing )凑够 NN 个,让左右两边一对一地配起来。配对的成本怎么衡量呢,模型给每一对可能的配对算一个代价,代价综合了框之间位置重合的程度(用4.3 节讲过的IoU来算)和类别预测的对错,配得越准代价越小。匈牙利算法做的事,就是在所有可能的一对一配对方案里,找出总代价最小的那一种。我们把这种使总代价最小的配对方案,叫作最优匹配。

只对那些被匹配到真实框的预测框算损失,剩下的预测框就只算它们预测背景类这一项的损失。这样一来,模型就被迫学会一件事,就是每一个真实物体只让一个预测框去认领,因为配对是一对一的,多抢一个就把别的物体挤掉了,代价立刻变大。如此一来,重复框就从根本上没了生存空间,NMS也就不必再请回来了。说起来这个设计真的挺巧妙,把以往要靠后处理做的事,挪到了训练目标里去解决。

4.收敛慢和小物体:DETR的难处

干净是要付代价的,DETR付的代价主要有两点。

第一点是收敛特别慢。论文里报告,DETR在COCO数据集上要训到500个epoch才能追上Faster R-CNN的精度,而Faster R-CNN只要训一百来个epoch就够了。epoch的意思是把整个训练集完整过一遍,我们前面讲优化时提过。原因大概有这么两个。一是Transformer特别想吃数据,吃大数据集才学得稳,可在COCO这种规模上还是觉得不够饱。二是注意力运算一开始要从全局开始学,每个token都得在整张特征图上四处张望,找出到底哪些位置和自己相关,这个搜索过程没什么先验,得靠梯度一点点磨出来。我记得有个做自动驾驶的同学小明跟我抱怨过,他第一次试DETR去做行人检测,训了三天损失还在那儿慢悠悠地晃,差点以为显卡坏了,跑去查了半天温度才放心。

第二点是小物体不太灵。这一点其实和收敛慢是同一个根。骨干网络把图像压缩了好几遍,到特征图的时候空间分辨率已经很小了,小物体在特征图上可能就占那么一两个像素,注意力再怎么去看也看不清楚。所以在COCO这种数据集上,DETR在大物体上的表现相当不错,甚至超过了Faster R-CNN,可在小物体上反而落后一些。

后来学界把这两点都大大改善了,最有名的一篇叫Deformable DETR。它的核心思想是把全局的普通注意力,换成了一种叫可变形注意力的新机制。可变形注意力的做法是,每个token不再去和整张特征图上的所有token打交道,而是只挑出很少的几个(论文里是四个)关键采样点,让模型自己学着把采样点放到该看的位置上去。这就像一个会看人的老中医,不必把全院的病人都看一遍,眼睛一扫就知道该往哪几个关键位置上搭脉。这样一来,注意力的计算量大大下降,收敛速度也提了上来,原本500个epoch的活,Deformable DETR大约50个epoch就能干完。再后来还有DINO、RT-DETR这些后续工作继续打磨,DETR这一脉也就慢慢成了检测领域里的一支主力。

5.一点意义

按时间看,DETR是2020年发表的,那时候Transformer在自然语言处理里已经火了好几年,可在视觉里大家多半还拿它当辅助。DETR第一次把Transformer当作检测的主干,端到端地做完了原本要靠好几样手工零件才能拼起来的活,开了把Transformer搬进检测的先河。说穿了,它之后检测领域里的各种Transformer工作,从Deformable DETR到DINO、RT-DETR,多多少少都受了它的启发。至于把Transformer当作视觉主干网络这条路(ViT、Swin那一脉),是另一条独立的线索,主要受自然语言处理里BERT、GPT那种做大模型的思路启发,和DETR的关系没那么直接。

我自己看DETR,觉得它最大的贡献是把检测这个问题重新表述了一遍。从前的检测是在像素空间里堆零件,DETR把它变成了一个集合预测问题,给定一张图,直接预测一组框,每一组里每个框都有自己的角色。这种视角上的转换,比单纯涨几个点精度要重要得多。记得我之前翻过一本讲城市规划的书,里面提到过一句话,大意是一座城市的格局,往往取决于最早那条主干道画在了哪里,后头的支路再怎么修,都得顺着这条主干走。DETR大概就是检测这条街上,最早把方向拧到Transformer上去的那一条主干道吧。

今天就先到这儿,下一章我们聊分割里的Mask R-CNN和SAM,再见。

练习

Q1. 传统检测器离不开 anchor 和 NMS 这两件"手工零件",DETR 为什么能把它们都拿掉?

因为 DETR 直接输出固定数量 NN(常取 100 或 300)个预测框,每个对应一个框坐标和一个类别概率分布,不再依赖预设的 anchor 在每个位置画参考框。又因为训练时用匈牙利算法做一对一的二分图匹配,逼着每个真实物体只被一个预测框认领,重复框从根本上没了生存空间,NMS 也就不必再请回来。它把原本要靠后处理做的事挪进了训练目标里。

Q2. 一张图里真实物体有 3 个,DETR 要输出 N=100N=100 个预测框,怎么把 100 个预测框和 3 个真实框配对起来算损失?

把 100 个预测框放左边、3 个真实框放右边,再往右边补背景类(空集 \varnothing)凑够 100 个,构成二分图。模型给每一对可能的配对算一个代价(综合了框的 IoU 重合度和类别对错),匈牙利算法在所有一对一配对方案里找出总代价最小的那种(最优匹配)。只对匹配到真实框的预测框算损失,剩下的预测框只算它们预测背景类的损失。这样配对是一对一的,多抢一个就把别的物体挤掉、代价立刻变大,模型被迫不重复预测。

Q3. DETR 在 COCO 上要训 500 个 epoch 才追上 Faster R-CNN,小物体上还偏弱,为什么?

收敛慢主要有两个原因:一是 Transformer 特别想吃数据,COCO 这个规模它还觉得不够饱;二是注意力一开始要从全局学,每个 token 都得在整张特征图上四处张望找出相关位置,这个搜索没什么先验,得靠梯度一点点磨出来。小物体弱是同一个根:骨干网络把图像压缩了好几遍,到特征图时空间分辨率很小,小物体可能就占一两个像素,注意力再怎么看也看不清。

Q4.(面试题) DETR 的结构分哪三段?匈牙利匹配解决的核心问题是什么?Deformable DETR 又做了什么关键改进?

三段是:CNN 骨干网络(常取 ResNet-50)提特征图;Transformer 编码器(把特征图展平成 token 加位置编码,自注意力建全局关系)加解码器;解码器输出固定数量的预测框。匈牙利匹配解决的核心是"一对一配对",逼着每个物体只被一个预测框认领,从而根本消除重复框、免去 NMS。Deformable DETR 把全局普通注意力换成可变形注意力:每个 token 不再和整张特征图所有 token 打交道,只挑很少几个关键采样点(论文里四个)让模型自己学着放到该看的位置,计算量大降、收敛速度提上来,原本 500 个 epoch 的活大约 50 个 epoch 就能干完。

相关标签
深度学习目标检测DETRTransformer