【散装论文】DETR3D:将DETR用于3D目标检测

前几天被导师扔了一篇DETR3D,让我看一下transformer能否应用在这个领域(凡事与transformer挂钩了他就很激动)。作为鲜有的在3D目标检测中应用transformer的文章,于是决定还是来写一写吧。

我也不知道写散装论文总结要花多少的精力,索性先来试一试,不一定长期更单篇。【毕竟,简单写几句躺在我的文献管理excel里不香吗】【嗯!但发出来可以知识共享,让更多的人获得快乐QAQ】

基本信息

论文题目:DETR3D: 3D Object Detection from Multi-view Images via 3D-to-2D Queries

论文链接https://arxiv.org/abs/2110.06922

代码链接https://github.com/wangyueft/detr3d

一段话概述论文

这是一篇多视角(多目)3D目标检测的工作,非LiDAR,也非单目,而且纯粹地基于nuScenes数据集。本质上,这就是一篇将DETR拓展到3D检测中的工作,所以重点在于,如何将DETR中bipartite loss的思想应用在3D任务上。DETR的大致过程是提取图像特征→编码辅助输入→结合queries获得values→得到queries的检测结果,并做损失。DETR3D在此基础上,除了将bipartite loss拓展到了三维空间中,还另外引入了Deformable DETR的iterative bounding box refinement模块,即构建多层layer对query进行解码。


通过DETR和DETR3D的网络结构对比,我们就可以简要领略这种改进是如何完成的:

DETR
DETR3D

注:如果你对DETR的结构不熟悉,或是想简单回顾一下DETR的思想,请参见附录:DETR部分。

疑惑

按照李沐老师读论文的方式,首先先问一下自己,如果是你来做,会怎样实现这一思想?或者说,看完论文的Abstract之后,我思考一番产生了怎样的疑惑?

我的想法是,

  • 在3D上做bipartite loss应该不难。
  • 如何借鉴deformable DETR,对特征不经编码得到key,却又能辅助decode部分的设计可能比较棘手(这事实上也是本文的重点部分)
  • multi-view又是怎么体现的?DETR是完全无关联的图像作为输入的
  • 最后,跳脱出论文,这种套用是否合理,是否真的发挥了transformer,或者说自注意力机制的优势?

带着以上疑惑,我们来逐渐拆解DETR3D的网络结构。

set-to-set loss

我们先来看最简单的部分,作者是如何把bipartite loss拓展到3D空间的。在文中,这个loss被称作是set-to-set loss,对于loss的研究,其实我们只要搞清楚预测与GT就可以了。

预测与GT

这里的pred是prediction set $(\hat {\mathcal B}_\ell,\hat {\mathcal C}_\ell)$,GT则称作GT set $({\mathcal B},{\mathcal C})$。

$\mathcal B$的含义取自bounding box,$\mathcal C$的含义取自class,如果你熟悉传统的目标检测,对这种$(b,c)$的形式应该是不陌生的。帽子(尖尖)代表是预测,角标$\ell$则表示layer。

这个layer的含义不明白没有关系,你可以先大致理解为有许多个layer,而每一个layer,都对应着一个pred出来的prediction set,而他们都会和同一个GT产生一个set-to-set loss。

为了使中间层也获得较好的学习效果,作者这里使用了一个常用的coarse2fine的手段,即在training阶段每层的loss都会被计算,但是在inference时只取最后一层作为输出。

一些细节

更进一步地考察loss的具体形式,论文中说$\hat{\mathcal{B}}{\ell}=\left{\hat{\boldsymbol{b}}{\ell 1}, \ldots, \hat{\boldsymbol{b}}{\ell j}, \ldots, \hat{\boldsymbol{b}}{\ell M^{}}\right} \subset \mathbb{R}^{9}$,$\hat{\mathcal{C}}{\ell}=\left{\hat{\ell 1}, \ldots, \hat{\ell j}, \ldots, \hat{\ell M}\right} \subset \mathbb{Z}$,这里预测输出的每一个$\hat{\boldsymbol{b}}_{\ell i}$是3D的bounding box参数(位置、大小、heading angle和BEV视角中的速度),$M^{}$是预先设定好的预测数量;每一个$\hat_{\ell i}$则对应category的类别(注意这里没有加粗,不是向量,因为只有1维),$M$是ground truth的数量。

看到这里,有两个问题:

  1. $\hat{\mathcal{C}}_{\ell}$里面最后应该也是到$M^*$吧,不应该是每一个预测对应一个category吗?这应该是个谬误。

  2. $\hat{\boldsymbol{b}}_{\ell i}$这里为什么是9个维度我不是很懂,我虽然没有使用过nuScenes,但粗略看了下,rotation是用四元数表示的,速度如果是一个张量的话,那么heading angle莫非也像kitti一样是$\alpha$和$r_y$?这算是个疑惑,毕竟没有细看代码不敢断言。

我们现在姑且假设$\hat{\mathcal{C}}_{\ell}$最后也是$M^*$的长度,接下来就像DETR一样,我们将这些pred对应的GT补以$\varnothing$的类别,然后做匈牙利算法排序就可以了,也即是说,我们要找到一种排列的方式,使得这种匹配的代价最小,具体地有:

知道各位看到长串数学公式会头疼,这里做了详细的解释,结合下图的匹配过程食用更加。

总而言之,这里的argmin鼓励我们找到一种预测的排列,使得anchor的顺序尽可能与GT匹配,当GT类别非空时寻找预测类标置信度最大者,当GT类别为空时寻找bbox最接近的。

这里又有问题了:

  1. GT类别非空时,单纯看寻找预测概率最大似乎是不合理的吧。比如预测有两个同类bbox,如何确定谁排在前面、后面?这样就会出现bbox错位匹配的情况吧。我们看DETR里是怎么写的:$\hat{\sigma}=\underset{\sigma \in \mathfrak{S}{N}}{\arg \min } \sum{i}^{N} -\mathbb{1}{\left{c{i} \neq \varnothing\right}} \hat{p}{\sigma(i)}\left(c{i}\right)+\mathbb{1}{\left{c{i} \neq \varnothing\right}} \mathcal{L}{\text {box }}\left(b{i}, \hat{b}_{\sigma(i)}\right)$,DETR这里的matching loss,两个示性函数都是非空的啊喂,必须要在非空的时候加以bbox的约束才能避免出现错位的情况(即又要匹配的类别对,又要匹配的类别好),并且空集的时候在这里其实是不关注的。

  2. 也正是因为他把后面那个项的示性函数改成等于了,这就引申出一个问题,在padding空集的时候,你这里也需要padding bounding box了,而这怎么padding呢?在DETR当中是不必为补充的空集也补充一个bounding box,因为你无论怎么补充,你都无法指望预测的空bounding box匹配上你的补充,所以这一点也是比较令人迷惑的。

如果以上你听得一知半解,我们再来看找到排列之后的损失计算,就更能理解这种诡谲了:

$\mathcal{L}{\text {sup }}=\sum{j=1}^{N}-\log \hat{p}{\sigma^{*}(j)}\left(c{j}\right)+1_{\left{c_{j}=\varnothing\right}} \mathcal{L}{\mathrm{box}}\left(\boldsymbol{b}{j}, \hat{\boldsymbol{b}}_{\sigma^{*}(j)}\right)$

这里也基本是和DETR类似的,不考虑符号上使用上的区别,就只有示性函数中把不等号变成了等号这样严肃的区别,于是这就造成了:当类别非空时,你不做bounding box上的loss,而现在类别空了你反而来做bounding box的loss。所以我强烈怀疑应该是论文中两处都打错了,否则结果应该不会还能排到SOTA。不知道是不是因为arxiv版本挂错了,还是真的审稿人粗心不看公式。

讨论

如果以上推断成立,那么就算我们脑补修改一下这个loss,其实也有值得商榷的地方:我本来期待着他的loss至少是什么IoU loss之类的,结果就是简简单单的L1。在KITTI-object那边的工作中,其实涌现了很多类似mIoU loss等创新性的工作。这样不考虑parameters在3D空间中的实际的bounding box意义,而直接做L1 loss,这样的学习效果是否会好、是否合理?

2D-to-3D 特征变换

解决了loss如何计算的问题,然后我们就来正序地研究一下,网络结构中这几条虚线的具体含义。

前边的特征提取就不再赘述了,类似DETR,也是使用了ResNet+FPN的结构,得到4个level、不同尺度的特征。

重点便在于如何解读这里的几条虚线了。起初,我是按照图例中给出的红色在最上、黄色在最下的顺序来解读的,以为是要先对特征进行操作,然后对query再加工提取,在feature space中去做loss……我还纳闷呢,明明人家说是在3D空间中做loss,这咋回事呢,而且transformer的黑色框框里,向右的黑色箭头也对不上啊……

纠结了好久才明白正确的理解方式是从蓝色开始看到红色,实际上所有虚线加起来的操作就是向右黑线……由于文中图例文字太小,这里按照虚线的顺序依次解读下以上的操作:

  1. 首先明确,object queries是类似DETR那样,即先随机生成$M^*$个bounding box,类似先生成一堆anchor box,只不过这里的box是会被最后的loss梯度回传的。
  2. (蓝线)然后通过一个子网络,来对query预测一个三维空间中的参考点$\boldsymbol{c}_{\ell i}$(实际上就是3D bbox的中心)。通过角标我们可以看出,这个操作是layer-wise、query-wise的。这两个wise的概念参见下文的讨论。
  3. (绿线)利用相机参数,将这个3D参考点反投影回图像中,找到其在原始图像中对应的位置。
  4. (黄线)从图像中的位置出发,找到其在每个layer中对应的特征映射中的部分。
  5. (红线)利用多头注意力机制,将找出的特征映射部分对queries进行refine。这种refine过程是逐层进行的,理论上,更靠后的layer应该会吸纳更多的特征信息。
  6. (黑色虚线框之后)得到新的queries之后,再通过两个子网络分别预测bounding box和类别,然后就进入我们之前讨论的loss部分了。

这里一定要注意,从蓝线开始,就像deformable DETR一样,queries是划分为了多个layer输入的(去查了一下代码,这里应该是6个layer),这个layer和FPN得到的feature layer是不同的(所以为免歧义,我在前后文都称之为feature level了),feature的level是四层,所以总结一下是:每一个level的feature都应该对应输入每个layer的queries,所以实际上应该会有4*6=24个输入(当然实际运算要更复杂一些)。

一些细节

了解了大致流程后,如果你关注具体的操作细节,那么可以继续看这个部分:

  1. query在输入时的形式应该就已经经过了编码?不管此时query是什么形式,蓝线就是一个预测中心点的过程,根据文中所述这是由一个neural network完成的,也没有说是什么、也没有说体量;但在黑色虚线框之后,得到新的query之后又要完成解码预测bbox和类别,而预测bbox之后意味着中心点求个平均就出来了,那么这两个网络是否可以共享参数?(或者说是否应该共享参数?)

  2. 绿线的过程就是一个使用$\boldsymbol{c}{\ell i}$的齐次坐标形式$\boldsymbol{c}{\ell i}^{}$,左乘相机投影矩阵完成的,是一个非常纯粹的数学过程,对应文章中公式(2)。但是这里注意,nuScenes数据集是有六个相机同时运作的,所以这里实际上会得到$6\times$个中心点数量。到这里,应该是$M^\times L \times 6$个投影后的中心点,根据代码$M^{*}=900, L=6$。

  3. 然后就涉及到这些投影后的中心点如何映射到每个level的FPN当中,因为每个level的feature尺寸不一样,所以这里是通过比较常规的、torch默认的双线性插值完成的。到此,我们的输入**又增加了$4 \times $**,因为前文说过,FPN最后得到4个level。

  4. 承接第2条,因为nuScenes的六个图像视角覆盖了整个全景,那么显然中心点投影并不会出现在某些视角的图像当中,这时找到的图像特征什么的显然是不合理的,应该去除。虽然应该在2之后就做这件事了,但可能是为了运算方便,作者放在了这里:可以添加一个布尔变量$\sigma_{\ell kmi}$来指示投影点是否valid,再对level和camera求平均,我们就可以得到一份只关于layer、query数量的feature,这部分feature是十分有价值的,我们可以将其Add在本layer的query中、向后传递成为下一层的refined query。

  5. 我的理解是,2、3的部分其实就是类似transformer中FFN的设计(只是这里没有简单地用MLP),而3的部分应该对应Add & Norm的部分。不过transformer变种如此之多,可能也不必这样生搬硬套,了解流程就好。

其他细节

  1. 训练是AdamW,weight decay=1e-4,训练12 eps,8块3090,每个GPU batchsize=1。初始lr=1e-4,8th为1e-5,11th为1e-6。

  2. 文中主要对标的是FCOS3D和CenterNet,在leaderboard上对标DD3D,虽然DD3D使用了额外的深度数据集,但最终得益于mAVEF方面的大幅度碾压才得以使最终的NDS略高于DD3D(+0.002)。吹毛求疵的话,其实在其他指标方面都不如DD3D。

  3. 得益于DETR,在inference time没有NMS确实看起来是一个优势,不过似乎也没有给出更多的训练和inference时间方面的对比。

总结

最后来总结,回答一下一开始提出的几个疑惑。

  • 关于bipartite loss和使用特征的方式,在此就不再赘述了,诸多细节与疑惑均已在讨论中提出。
  • multi-view体现在query对同一时刻的六张图像同时进行了学习,单就这一点而言其思路就是比较超前的。传统的Monocular方法都是单张图像输入输出、multiview方法大家考虑的也是时间序列上的长序列,而并没有拓展到多视角上。
  • 关于注意力机制的问题,我们可以回忆一下,DETR令人震撼的地方其实是在于decoder attention可以关注到bounding box中的特征:

而在这里,文中其实是没有给出什么可视化的效果,或者类似“all box predictions”这种grid可视化图。强行分析的话,我认为亮点反而可能在于,这种多目图像之间特征的求和(简单的1x1conv)并对query的refine,其实是替代了传统的多目匹配工作,使得这种3D-to-2D Queries可以有效跨越多目图像,更应该是本文的落脚点和关注之处。

总的来讲,还有很多疑惑,也还有很多可发展的地方。

不过最后的最后,还是要说一句,本人水平有限,还希望各位能带着批判的眼光审阅和讨论。

附录:DETR

关于DETR的解读全网应该比较多了,我也就不过多展开了。在此我主要参考的是b站的这两个视频:

  1. [论文简析]DETR: End-to-End Object Detection with Transfromers[2005.12872]_哔哩哔哩_bilibili
  2. 【中文字幕】DETR 论文解读_哔哩哔哩_bilibili

如果你只是想大致了解DETR思想,那么建议着重关注bipartite loss的设计,DETR3D在此部分上的设计与DETR非常相似。