ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

DETR核心机制与3D目标检测:Transformer如何重塑检测范式

DETR核心机制与3D目标检测:Transformer如何重塑检测范式 1. 2D目标检测的老问题DETR出现前我们到底在折腾什么在聊DETR之前有必要先搞清楚一个事情为什么Transformer进入目标检测领域会被视为一次革新想回答这个问题得先看看DETR诞生之前2D目标检测的主流玩法卡在哪儿了。传统的目标检测框架不管是两阶段的Faster R-CNN、一阶段的YOLO系列还是后来各种魔改的变体本质上都绕不开两个核心组件锚框anchor和后处理NMS。锚框这套设计说直白点就是在图像上预先铺满密密麻麻大小不一、长宽比各异的矩形框然后让网络去判断这个框里有没有物体以及这个框离真实的物体还差多远。训练的时候几十万个候选框要和标注的真实框做匹配匹配上的负责学分类和回归匹配不上的就是负样本。这种思路经过了多年迭代确实非常成熟工程上也足够鲁棒但它有一个天生的毛病——超参数特别多。锚框的尺寸怎么设、长宽比怎么设、正负样本的IoU阈值定多少、匹配策略怎么定这些都直接影响最终精度。换个数据集、换个任务很可能就要重新调一轮。再说NMS。因为锚框是密集铺的同一个物体周围会有大量高度重叠的预测框必须用一个叫非极大值抑制的算法去把这些重复框合并掉只留下置信度最高的那个。NMS本身逻辑不复杂但在实际场景里是个挺脆弱的环节——如果两个物体离得特别近NMS可能会把本该保留的框误删掉如果参数设置不当漏检和误检之间很难平衡。DETR出现之前业内其实已经有一批人在尝试各种去锚框的方案比如FCOS、CenterNet这类anchor-free的检测器。它们取消了对锚框的依赖但仍然需要靠中心点预测、距离回归这种方式来产生检测结果最终依然要走到NMS那一步。也就是说无论如何绕**用卷积网络产生一堆冗余候选再用后处理去重**这个基本范式没有变。这也是DETR一出来就让很多人眼前一亮的根本原因它把整个检测问题重新定义为一次性集合预测——输入一张图输出一组长度为N的预测类别框坐标不做密集采样、不做NMS、不设计任何锚框。这种范式的转变不是单纯换个backbone或者换个loss能比的。注意现在回过头看DETR的意义不只是检测结果好了一点而是把目标检测从一个需要大量手工设计和工程调参的任务变成了一个端到端可微分的结构建模任务。这个思路的转变直接为后面的3D检测铺了路。关于目标检测训练过程中的评价标准也简单补一句DETR论文里用的还是经典的mAP体系在不同IoU阈值下统计精度。这套指标和DETR的集合预测之间其实存在一个微妙的错配——匈牙利匹配给每个预测分配GT的时候用的是二分图最优匹配而mAP算的是逐类别、逐个GT匹配。但这个错配并不影响模型训练只是在分析结果时要注意区分训练时的匹配和评测时的匹配。2. DETR的核心机制拆解集合预测、匈牙利匹配和可学习queryDETR的整套架构说穿了有三块CNN骨干提取特征、Transformer编码器-解码器做全局建模、FFN头输出最终预测。但其中真正革新的机制是下面这三件事。2.1 集合预测把检测从稠密回归变成稀疏set传统检测器输出的是一堆叠加在锚框上的修正量而DETR直接输出一个固定大小的集合比如默认预测100个物体。每个预测是一个三元组物体的类别包括一个特殊的无物体类别、框的中心坐标、框的宽高。这个100是怎么定的说白了就是保证图像里最多同时出现100个目标这个假设在绝大多数场景下都成立。COCO数据集里一张图平均出现7个目标左右100个预测名额足够用了。多的那些预测就统统被分到无物体类相当于在训练过程中自动被惩罚。这里有个看起来反直觉的点**为什么用固定长度的集合而不是像检测那种不定长输出**原因在于训练效率。定长集合可以和GT集合做稳定的二分图匹配如果不定长匹配过程会变得非常复杂。实际训练中100这个数字不会卡得那么死推理时如果某个预测被分到无物体就直接丢弃。2.2 匈牙利匹配训练时谁负责谁的分配策略集合预测的训练绕不开一个问题模型输出了100个预测框训练数据里只有几个GT框到底哪个预测框该去学哪个GT框直接全部学肯定不行因为大部分预测都对应无物体。DETR的答案是用匈牙利算法做最优二分匹配。每次迭代把100个预测和所有GT加上一大堆空集做一个全局匹配目标是让整体的匹配代价最小。匹配代价由三部分构成分类代价预测类别是否正确、L1框回归代价中心点距离、广义IoU代价框重叠程度。这套机制最妙的地方在于匹配过程本身是动态的。同一个GT框可能在这轮迭代里匹配给第35个预测下一轮就变成了第77个预测。不同的预测头在不同的训练阶段负责不同的目标整个系统是协作式的。这和传统锚框固定框负责固定位置的思路截然不同。匈牙利匹配在工程上有现成的库可以用比如scipy的linear_sum_assignment实现起来不会太麻烦。但要注意的是匹配结果直接决定梯度回传到哪个分支所以如果匹配不稳定训练很容易震荡。这也是DETR在早期版本里训练非常慢的原因之一。2.3 可学习的object query让模型自己长出检测槽位DETR的decoder输入很特殊——一组长度固定、维度固定、内容初始化为全零或随机初始化的查询向量。论文里叫object queries翻译过来就是物体查询。它不是从图像里提的特征而是一组随训练不断更新的参数。怎么理解这个东西我更喜欢用一个生活化的类比想象你有一个团队叫100个新员工每个员工入职时都拿着一张空白需求单但慢慢地第1个员工学会了专门找猫中间偏左的位置第2个员工学会了专门找车下半部分第3个员工学会了专门找人……训练充分之后每个query就变成了一个擅长检测特定位置、特定大小、特定类别目标的专家槽位。有意思的是从DETR论文里可视化的结果可以看出最后学习出来的100个query确实体现出了一种空间分布倾向——有些query集中在中上区域有些集中在左下这和目标在图像中的位置先验分布是对应的。但没有任何人显式告诉模型你应该这么分配完全是数据驱动出来的。这三个机制叠加在一起构成了DETR的完整逻辑CNN提出高维特征Transformer做全局推理100个可学习query通过交叉注意力机制自己去查找要检测的目标最后FFN输出类别和框。整个过程不需要锚框、不需要NMS干净利落。3. 为什么训练难收敛、小目标拉胯DETR早期版本的关键问题DETR在2020年5月挂在arXiv上的时候效果其实已经做得挺惊艳了——在COCO上直接超越了许多Faster R-CNN的变体而且整个架构极其简洁。但真正用过或复现过原始DETR的人应该都有体会训练收敛太慢了特别吃GPU。原始DETR在COCO上训练需要大概500个epoch才能完全收敛而当时主流的Faster R-CNN训练12~36个epoch就够了。这个差距在当时几乎算得上劝退级别。为什么会这么慢探下去有三个核心原因。第一是Transformer里的自注意力层收敛慢。自注意力的梯度传播路径非常深而且注意力权重的分布初始时是近乎均匀的也就是什么都看但什么都没看仔细。要让注意力矩阵逐渐学会集中于特定区域需要大量迭代。这个问题其实在NLP领域的老Transformer上也存在只不过在图像任务上由于像素空间的信息密度远低于语义空间收敛会更慢。第二是匈牙利匹配的不稳定性。训练初期模型输出的框质量很差匈牙利匹配的结果几乎相当于随机匹配。匹配结果一变梯度方向就变模型在不同任务之间反复横跳前期学习效率自然很低。很多复现DETR的人应该都有这种体验前几十个epoch loss基本不怎么降然后某一个瞬间开始突然加速这就是匹配逐渐变得稳定了。第三是小目标检测效果差。DETR默认的Transformer编码器特征分辨率是1/32或者1/16小目标在经过多次下采样之后特征图上的信息已经非常稀薄。而对小目标敏感的细节特征恰恰是自注意力机制最不擅长处理的——注意力天生偏好全局关系对小尺度局部细节的捕捉远不如卷积核直接。所以早期DETR在COCO小目标类别上的AP特别低甚至低于Faster R-CNN。这三个短板后来分别由Deformable DETR、DN-DETR、DINO这些后续工作逐一改善。Deformable DETR用多尺度特征加可变形注意力替代了全局自注意力直接把收敛epoch降到了50左右DN-DETR用去噪训练解决了匹配不稳定的问题DINO在两者基础上把query初始化和对比去噪一起做了把小目标效果也拉了上来。小提示如果你正在拿DETR做自己的数据训练建议不要直接用原始DETR权重做初始化之后再在自己数据上跑。原始DETR在COCO上学到的query分布和你的数据分布可能差别很大这种情况直接从头训练反而更快。我踩过这个坑头铁跑了几百个epoch才反应过来。4. 从2D到3DTransformer怎样改变三维目标检测的思路DETR在2D检测上的成功让研究者们开始思考一个问题既然检测本质上是一种基于上下文关系的结构化预测那三维空间里的目标检测是不是也能用类似的范式做这个问题的背景是3D目标检测的数据表示和2D完全不一样。2D检测输入的是规则的像素网格而3D检测的输入五花八门——有可能是激光雷达采集的点云有可能是双目或者多相机生成的深度图有可能是纯视觉的图像序列更常见的是点云图像的融合数据。三维空间的目标没有统一的像素概念物体是用一组稀疏、无序、密度不均的点来表示的。在这种数据形态下传统卷积不太好用锚框需要从2D扩展到3D体素空间NMS的复杂度也会变高。Transformer在这里的价值体现在它天然能处理无序集合这一点上。卷积假设输入是一个有规则的网格而自注意力机制对输入的顺序不敏感它只关注元素之间的关系。这恰好和点云这种无序数据的特性完全吻合。于是一系列基于Transformer的3D目标检测方法开始出现我把它们大致归成三类。4.1 体素化方案把3D问题压回2D流程代表方法是VoxelSet TransformerVoxSet。思路很简单把三维空间划分成规则的体素网格每个体素里聚合若干点云特征把非空体素视为token然后在体素空间里做自注意力。这等于是在3D坐标系里复刻了DETR的流程生成的3D候选框最终回归出中心点、尺寸、朝向角和类别。这类方法的好处是工程上改动最小能复用大量2D检测的成熟组件缺点是体素分辨率受限于显存小目标依然棘手。4.2 点集方案直接吃原生点云代表是Pointformer这类方法不体素化直接在原始点云集合上做局部和全局自注意力。每个点被映射成一个高维特征向量通过多头注意力学习点和点之间的关系。这套逻辑天然适合做室内场景的三维检测比如ScanNet、SUN RGB-D因为室内点云规模相对可控。但室外场景就有些吃力——路测点云动不动几十万甚至上百万个点全局自注意力根本跑不动所以一般还得配一个点云下采样的前置模块。4.3 多模态与鸟瞰图方案让Transformer做融合和预测这是目前工业界比较主流的方向。核心思想是把所有传感器数据相机图像、激光雷达点云通过映射关系投影到BEV鸟瞰图视角下形成一个统一的空间表示再在这个BEV特征图上用Transformer做特征融合和目标预测。代表工作包括BEVFormer、PETR这些。这么做的好处是所有模态的数据都对齐到了同一个3D坐标系里Transformer的注意力机制能在不同模态之间建立关系比如让视觉特征去关注点云所在的区域。这种方案在自动驾驶场景里尤其吃香因为BEV表示对下游的规划控制更友好而且能和occupancy网络无缝衔接。PETR系列特别值得一提——它把3D坐标编码成位置引导的query直接在Transformer解码器里输出3D框整条pipeline非常干净几乎就是DETR在3D场景下的直接延伸。从2D到3DTransformer带来的核心改变可以归纳成一句话目标检测从一个在稠密网格上做分类回归的任务变成了一个在无序集合上做关系建模与结构预测的任务。只要你把输入数据变成一组token不管这个token是像素块、体素还是点Transformer就能帮你做全局推理。这个范式的普适性是它在3D领域迅速落地的最主要原因。5. 实操过程中的障碍和解决办法以DETR训练自己的2D数据为例理论聊了不少但我觉得最有价值的部分还是实际跑起来踩过的坑。这里就以DETR训练自己的数据为例给大家整理一份可以直接参考的实操经验。虽然主题是3D但2D的DETR流程是最容易上手的把2D跑通再去看3D方法会容易很多。5.1 数据集格式转换DETR官方代码用的是COCO格式的数据集。如果你自己的数据是VOC格式的xml标注或者LabelMe生成的json先别急着跑代码第一步要做的就是格式转换。VOC转COCO的脚本在Detectron2仓库里可以找到LabelMe的json也可以通过labelme2coco这个工具直接转换。转换的时候有几个容易忽略的细节类别ID必须从1开始0保留给背景无物体类别。COCO格式里的bbox是[x, y, width, height]格式VOC里是[xmin, ymin, xmax, ymax]别搞混。annotations里的iscrowd字段如果设成1训练时该目标会被忽略如果误标了可能导致某些目标学的不好。5.2 超参调整DETR的超参里最值得调的是这几个训练epoch数小规模自定义数据集一般不需要500个epoch通常100~300个epoch就够收敛关键看验证集mAP是否还在涨。学习率官方默认是1e-4但如果你用更大的batch size比如单卡显存不够用梯度累积可以适当降到5e-5。预测框数量默认num_queries100。如果你的业务场景中单张图的目标数量极少比如每张图只有1~2个目标可以减到30训练速度会快不少。反之如果场景密集比如密集人群建议增加到300。5.3 数据增强的影响DETR官方训练时用了RandomCrop和RandomFlip这俩增强对DETR特别重要。因为DETR是全局建模随机裁剪能迫使模型不依赖于固定位置的信息而是真正学习目标本身。如果直接不做增强就开训模型很容易在验证集上表现很差却找不到原因。另外复制粘贴增强CopyPaste对DETR的提升很大很多复现实验都验证了这一点建议优先尝试。5.4 一个值得注意的工程细节batch size和显存DETR的显存占用比同尺寸的CNN检测器明显更高因为Transformer的注意力矩阵是NxN的特征图分辨率越高显存开销越大。我当时用一张24G的3090batch size只能开到4左右。如果显存不够可以按这个优先级处理优先降特征图分辨率backbone的stride从32改为16其次是降低num_queries最后才考虑梯度累积。直接开梯度累积会明显拖慢收敛速度因为BN的统计量会变得不那么稳定。6. 3D检测实战前的准备点云表示和坐标变换想真正跑3D目标检测还得再往下走一层——理解3D数据本身。很多从2D转3D的同学第一个卡住的地方就是点云到底长什么样以及坐标怎么变换。6.1 点云的三种基本表示原起点云raw point cloud就是一组x, y, z, intensity的四维向量激光雷达扫描一圈出来可能有十几万个点。这种表示最完整但直接扔给神经网络是不现实的因为点数是动态的、顺序是未知的且计算量巨大。体素表示voxel把3D空间切成规则小块每个块里统计点的数量或者特征值。这是目前工业界用得最多的表示方式因为它能把点数打碎成规则网格方便用3D卷积或者Transformer处理。缺点是分辨率受限制体素设大了丢失细节设小了显存爆炸。BEV表示birds eye view是一种2.5D表示把3D点云沿着高度方向压缩成一张俯视图每个像素记录这一列上的最大/平均高度或者强度值。虽然丢失了高度信息可以通过多通道弥补但计算量比前两种小了一个数量级所以在自动驾驶感知模块里特别流行。6.2 坐标变换是3D检测的命门2D目标检测的ground truth是图像坐标系的2D框而3D目标检测的ground truth是3D坐标系下的中心点、长宽高、朝向角。涉及到的坐标系一般有四个相机坐标系、激光雷达坐标系、自车坐标系、图像像素坐标系。不同传感器数据在融合之前必须做外参标定把各坐标系统一到同一个参考系下。坐标变换这件事在别人写好的代码里往往只有几行矩阵乘法但出了问题很难排查。我的经验是拿到一个新数据集先可视化几个关键样本把3D框投影到2D图像上看对不对齐。如果投影出来的框和图像上的物体轮廓有系统性偏移大概率是外参矩阵搞错了或者坐标系顺序不对。很多模型训练不收敛的问题根源其实在这。6.3 实操建议用OpenPCDet跑通一个baseline如果你现在是第一次接触3D目标检测我强烈建议不要自己从头写架构直接用OpenPCDet这个开源框架跑一个现成的baseline。OpenPCDet支持PointPillars、SECOND、Voxel-RCNN等经典模型也支持加载KITTI、nuScenes、Waymo数据集。具体流程大概是这么几步安装环境PyTorch CUDA spconv体素化卷积的高效库。spconv的编译在某些CUDA版本下比较折腾建议直接用官方提供的Docker镜像。下载KITTI数据集按官方文档整理目录结构。训练PointPillars这个模型最早逻辑简单单卡能跑适合理解整个流程。用TensorBoard观察loss和mAP曲线再换Voxel-RCNN看效果差异。等你把OpenPCDet的流程跑通一遍再回头看那些基于Transformer的3D检测代码很多概念就能对上了——backbone负责特征提取neck负责多尺度融合head负责输出3D框Transformer方法和CNN方法的区别主要体现在neck和head部分的结构上。7. 如何选型什么场景该用DETR什么场景该继续用YOLO说句实在话DETR虽然革新了目标检测的范式但如果你只是在一个计算资源有限的落地场景里做推理YOLO依然是更务实的选择。选型这件事一定要结合自己的实际场景来。先给一个简单的对比表格维度DETR系列YOLO系列端到端是无需NMS否需要NMS训练成本高需更多epoch和显存低推理速度中等极快小目标性能早期孱弱DINO后改善YOLOv8小目标头处理后也不错长尾/遮挡场景全局推理有优势依赖训练数据的采样工程成熟度中低极高部署工具链完善我的建议是追求极致推理速度、部署在边缘设备上优先YOLOv8/YOLOv9这类成熟一阶段模型TensorRT/OpenVINO工具链完整踩坑成本低。检测目标密集、重叠严重、需要计数或精细位置可以考虑DETR系列因为不需要NMS可以避免密集场景下NMS误杀的问题。做自动驾驶/机器人等3D感知任务3D场景下DETR范式中的query设计对多模态融合特别友好比如PETR系列在BEV感知任务里的表现就很不错。做research或者探索性项目DETR的架构可塑性更强比较容易在上面加各种新模块比如引入额外的模态输入、加入时序信息等而YOLO的改动空间相对受限。另外补充一个重要观点DETR并不是要取代YOLO而是提供了一种新的思考目标检测的方式。两者的核心差异不在精度差别多少而在于要不要手工设计密集采样和后处理这个方法论层面。哪怕你不亲自用DETR理解它背后的集合预测思路也有助于你理解YOLO里那些超参数为什么存在、为什么是这么设定的。8. 从DETR到3D的应用前景一些现实落地的思考聊到最后说说我对DETR从2D走向3D这个趋势的判断以及在实际落地时要注意的几件事。Transformer进军3D目标检测目前最活跃的应用场景是自动驾驶。自动驾驶感知需要处理的正是多模态、无序、大范围、遮挡严重的数据——这些全都撞在了Transformer的强项上。BEVFormer在nuScenes榜单一度霸榜PETRv2也展现了极强的视觉3D检测能力这些都是实打实的效果验证。但落地的时候有几个实际问题不是论文里会告诉你的第一Transformer 3D检测的推理延迟普遍偏高。点云数据本身量大再加上自注意力计算一张3090跑BEVFormer的实时推理压力都不小。如果要做量产量化剪枝和TensorRT优化几乎是必修课。第二数据规模和数据质量要求更高。Transformer是数据饥渴型模型3D标注又比2D贵得多。很多团队一开始数据量不够发现训出来的Transformer检测器还不如自己之前的CNN方案就放弃了。这个挺可惜的——解决方向其实可以考虑预训练比如在Waymo这种大数据集上预训练再在自己的小数据集上微调或者用自监督学习做预训练。第三长尾场景依然是老大难。Transformer能更好地处理局部上下文交互但对于极端罕见的场景比如道路上的罕见物体数据驱动模型都会面对数据覆盖不足的问题。这个不只是模型结构的问题要靠数据闭环和主动学习来补。我个人的体会是DETR从2D到3D的演进路径本质上是一次从手工设计到结构学习的范式迁移。2D时代我们设计锚框、设计NMS策略、设计特征金字塔进入3D时代这些手工设计在三维空间中会变得更加复杂甚至不适用。Transformer给了我们一个统一的建模思想只要把数据变成token让模型自己去学习token之间的关系就能完成结构化的预测任务。这种思路的普适性现在还只是刚刚开始展现。如果你正在考虑入手这个方向我的建议是从DETR的官方代码入手自己动手改一改过一遍训练流程然后再去接触Deformable DETR、DINO这些改进版本最后才进入3D的OpenPCDet和BEVFormer。每一步都动手跑一遍比你单纯读十篇论文要管用得多。深度学习的进步终归是在复现和理解的基础上长出来的。
返回列表