作者 | 慕弋云子@知乎(已授权)
原文 | https://zhuanlan.zhihu.com/p/430198800
编辑 | 南山
本文仅用于学术讨论。转载时联系原作者。
几天前,我被导师扔掉了DETR3D,让我看一下transformer能否应用于这个领域(一切和一切)transformer挂钩的时候他很激动)。作为少有的,D应用于目标检测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请参见本文附录。
疑惑
按照李木先生读论文的方式,首先问问自己,如果你这样做,你会如何实现这个想法?或者,读完论文后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
这里的pred是prediction set,GT则称作GT set。
的含义取自bounding box,的含义取自class,如果你熟悉传统的目标测试,对此 ()形式应该并不陌生。帽子(尖尖)代表预测,角标则表示layer。
这个layer不懂意思也没关系。你可以大致理解有很多layer,而每一个layer,都对应一个pred出来的prediction set,他们都会和产生一个set-to-set loss。
为了使中间层获得更好的学习效果,作者在这里使用了一种常用的方法coarse2fine手段,即在training阶段每层的loss但是在inference时只取最后一层作为输出。
一些细节
进一步调查loss论文中的具体形式,,在这里预测每个输出是3D的bounding box参数(位置、大小、heading angle和BEV视角中的速度),是预先设定的预测量;每个则对应category类别(注意这里没有加粗,不是向量,因为只有1维),是ground truth的数量。
这里有两个问题:
里面最后也应该到嗯,不应该每个预测对应一个category这应该是谬误。
为什么我不太了解这里的九个维度?虽然我没用过nuScenes,但粗略看了一下,rotation它以四元数表示。如果速度是张量,那么heading angle莫非也像kitti一样是和?这是个疑惑,毕竟不仔细看代码就不敢断言。
现在让我们假设一下最后也是长度,接下来就像DETR同样,我们也会这样做pred对应的GT补以然后对匈牙利算法进行分类,也就是说,我们需要找到一种排列方法,使匹配成本最低,具体如下:
我知道你看到长串数学公式会头疼。这里有一个详细的解释,结合下面的匹配过程吃得更多。
总之,这里的argmin鼓励我们找到一个预测的排列,使之anchor尽可能和GT匹配,当GT当类别非空时寻找预测类标信度最大的时候GT空时搜索类别bbox最接近的。
这里又有问题:
GT当类别不是空的时候,单纯看最大的预测概率似乎是不合理的。例如,有两个类似的预测bbox,如何确定谁在前面和后面?这样就会出现bbox错位匹配。我们看DETR里面是怎么写的:,DETR这里的matching loss,两个示性函数都是非空喂养,必须在非空喂养时进行bbox限制可以避免错位(即匹配的类别是对的,匹配的类别是好的),空的时候不注意。
正是因为他把后一项的示性函数改成了等于,这就引申出了一个问题padding空集的时候,你也需要在这里padding bounding box嗯,怎么了padding呢?在DETR当中是不必为补充的空集也补充一个bounding box,因为无论你如何补充,你都不能指望预测空bounding box与你的补充相匹配,所以这也更令人困惑。
假如以上你听得一知半解,我们再来看看排列后的损失计算,就能更好地理解这种诡异:这里也基本和谐DETR类似地,如果不考虑符号上使用的差异,只有在示性函数中将不等号变成等号之间的严重差异,这就导致了当类别不是空的时候,你这样做bounding box上的loss,现在类别是空的,你反而来做bounding box的loss。。不知道是不是因为arxiv版本挂错了,或者真的审稿人粗心大意不看公式。
讨论
如果建立了上述推断,即使我们修改了这个大脑loss,其实也有值得商榷的地方:我期待着他loss至少是什么IoU loss等等,结果很简单L1。在KITTI-object在那边的工作中,其实有很多类似的东西mIoU loss等待创新工作。这样不考虑parameters在3D实际的空间bounding box直接做意义L1 loss,这种学习效果会好还是合理?
2D-to-3D 特征变换
解决了loss如何计算问题,然后我们将有序地研究网络结构中这些虚线的具体含义。
前面的特征提取不再重复,类似DETR,也是使用了ResNet FPN四个结构level、不同尺度的特征。
重点是如何解读这里的几条虚线。起初,我是按照图例中给出的红色在最上、黄色在最下的顺序来解读的,以为是要先对特征进行操作,然后对query再加工提取,在feature space中去做loss……我还在想,很明显人家说是3。D空间中做loss,这是怎么回事,而且transformer在黑框中,右边的黑色箭头也不对……
纠结了很久才明白正确。解方式是从蓝色开始看到红色,实际上所有虚线加起来的操作就是向右黑线……由于文中图例文字太小,这里按照虚线的顺序依次解读下以上的操作:
首先明确,object queries是类似DETR那样,即先随机生成 个bounding box,类似先生成一堆anchor box,只不过这里的box是会被最后的loss梯度回传的。
(蓝线)然后通过一个子网络,来对query预测一个三维空间中的参考点 (实际上就是3D bbox的中心)。通过角标我们可以看出,这个操作是layer-wise、query-wise的。这两个wise的概念参见下文的讨论。
(绿线)利用相机参数,将这个3D参考点反投影回图像中,找到其在原始图像中对应的位置。
(黄线)从图像中的位置出发,找到其在每个layer中对应的特征映射中的部分。
(红线)利用多头注意力机制,将找出的特征映射部分对queries进行refine。这种refine过程是逐层进行的,理论上,更靠后的layer应该会吸纳更多的特征信息。
(黑色虚线框之后)得到新的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个输入(当然实际运算要更复杂一些)。
一些细节
了解了大致流程后,如果你关注具体的操作细节,那么可以继续看这个部分:
query在输入时的形式应该就已经经过了编码?不管此时query是什么形式,蓝线就是一个预测中心点的过程,根据文中所述这是由一个neural network完成的,也没有说是什么、也没有说体量;但在黑色虚线框之后,得到新的query之后又要完成解码预测bbox和类别,而预测bbox之后意味着中心点求个平均就出来了,那么这两个网络是否可以共享参数?(或者说是否应该共享参数?)
绿线的过程就是一个使用 的齐次坐标形式 ,左乘相机投影矩阵完成的,是一个非常纯粹的数学过程,对应文章中公式(2)。但是这里注意,nuScenes数据集是有六个相机同时运作的,所以这里实际上会得到6x个中心点数量。到这里,应该是 个投影后的中心点,根据代码 。
然后就涉及到这些投影后的中心点如何映射到每个level的FPN当中,因为每个level的feature尺寸不一样,所以这里是通过比较常规的、torch默认的双线性插值完成的。到此,我们的输入又增加了 ,因为前文说过,FPN最后得到4个level。
承接第2条,因为nuScenes的六个图像视角覆盖了整个全景,那么显然中心点投影并不会出现在某些视角的图像当中,这时找到的图像特征什么的显然是不合理的,应该去除。虽然应该在2之后就做这件事了,但可能是为了运算方便,作者放在了这里:可以添加一个布尔变量 来指示投影点是否valid,再对level和camera求平均,我们就可以得到一份只关于layer、query数量的feature,这部分feature是十分有价值的,我们可以将其Add在本layer的query中、向后传递成为下一层的refined query。
我的理解是,2、3的部分其实就是类似transformer中FFN的设计(只是这里没有简单地用MLP),而3的部分应该对应Add & Norm的部分。不过transformer变种如此之多,可能也不必这样生搬硬套,了解流程就好。
其他细节
训练是AdamW,weight decay=1e-4,训练12 eps,8块3090,每个GPU batchsize=1。初始lr=1e-4,8th为1e-5,11th为1e-6。
文中主要对标的是FCOS3D和CenterNet,在leaderboard上对标DD3D,虽然DD3D使用了额外的深度数据集,但最终得益于mAVEF方面的大幅度碾压才得以使最终的NDS略高于DD3D(+0.002)。吹毛求疵的话,其实在其他指标方面都不如DD3D。
得益于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: Postprocessing-free Detector
DETR讲解视频链接:https://www.bilibili.com/video/BV1Qg4y1B7rL?from=search&seid=14490952690367264450&spm_id_from=333.337.0.0
本文仅做学术分享,如有侵权,请联系删文。
1.面向自动驾驶领域的多传感器数据融合技术
2.面向自动驾驶领域的3D点云目标检测全栈学习路线!(单模态+多模态/数据+代码)3.彻底搞透视觉三维重建:原理剖析、代码讲解、及优化改进4.国内首个面向工业级实战的点云处理课程5.激光-视觉-IMU-GPS融合SLAM算法梳理和代码讲解6.彻底搞懂视觉-惯性SLAM:基于VINS-Fusion正式开课啦7.彻底搞懂基于LOAM框架的3D激光SLAM: 源码剖析到算法优化8.彻底剖析室内、室外激光SLAM关键算法原理、代码和实战(cartographer+LOAM +LIO-SAM)
9.从零搭建一套结构光3D重建系统[理论+源码+实践]
10.单目深度估计方法:算法梳理与代码实现
扫码添加小助手微信,可
也可申请加入我们的细分方向交流群,目前主要有、、、、、等微信群。
一定要备注:
▲长按加微信群或投稿
▲长按关注公众号
学习3D视觉核心技术,扫描查看介绍,3天内无条件退款
圈里有高质量教程资料、答疑解惑、助你高效解决问题