我第一次认真做多相机感知的时候最大的困惑不是网络长什么样而是六个朝向完全不同的摄像头凭什么最后能变成一张干净利落的鸟瞰图BEVFormer这篇论文回答的正是这个问题——它用时空Transformer从多相机图像直接学习Birds-Eye-View表示是整个BEV范式里绕不过去的里程碑。这篇文章算是我读完论文之后的结构化笔记把BEV queries怎么定义、空间交叉注意力怎么跨相机聚合、时间自注意力又怎么利用历史帧这几件事掰开揉碎讲清楚适合正在读自动驾驶感知论文、或者想复现BEV类方法的同学参考。开头先用一个生活场景帮你建立直觉如果你坐在驾驶座上实时接收来自前后左右的视频画面你并不会在脑子里把六路视频各自单独处理而是会本能地把它们换算成自己周围一圈空间的俯视图——哪里有人、哪里是路口、哪辆车在加速。BEVFormer做的就是这个换算只不过它把换算这件事交给了Transformer。相比传统先逐图检测、再投影融合的思路它直接把整个3D空间切成了网格让每个网格自己去对应的图像里找证据。理解了这个角度反转后面所有细节都会顺很多。1. 透视视图的局限为什么整个行业都在往BEV转1.1 每个相机单独检测再融合到底别扭在哪早期多相机3D检测的主流写法是每个相机各检测各的再把2D结果投影到3D空间做融合。这条路听起来直觉上很对实际操作时会碰到几个绕不开的问题。第一个问题是遮挡和重叠。透视图里近处的大车会盖住远处的小车每个相机单独检测时被遮挡的目标直接消失。第二个问题是尺度不一致。同一个目标停在正前方1米和10米在图像里占的像素差了几十倍检测器要同时应对这两种极端尺度压力全在特征表征上。第三个问题是跨相机拼接。目标从右侧相机运动到前侧相机时如果不做跨相机的特征关联同一个目标很容易被重复检测或者干脆跟丢。BEV视角天然规避了这些问题鸟瞰图上物体不会被前景遮挡——或者说遮挡转移到3D空间里由模型自己推理尺度也被统一——一个0.4米分辨率的网格无论目标远近都是固定大小更重要的是所有相机被拉到同一个全局坐标系里跨相机的目标拼接变成了同一个平面上的相邻网格而不是两张图之间的像素匹配。1.2 BEV表示对自动驾驶感知是一种天然友好的输出格式自动驾驶的后端模块——预测、规划、控制——几乎全部工作在自车坐标系或俯视语义图上。感知模块如果直接输出鸟瞰视角的特征下游就能无缝衔接不需要再做一个透视转俯视的中间层。这也是BEV表示最近几年成为感知主流范式的原因。它就像一个统一语言检测、车道线分割、可行驶区域判断、运动预测大家都用同一张俯视特征图表达特征之间还能互相补充。BEVFormer的作者正是看重这一点所以整篇论文的落点不是用BEV做检测而是如何从多相机图像学到高质量的BEV表示。检测和分割只是用来验证这个表示够不够好的两个下游任务。1.3 但BEV不是白来的最大的工程代价在于视图变换把透视图变成俯视图最朴素的想法是逆透视映射IPM。它假设地面是平面把图像像素直接投影到地面坐标系。问题在于路面上全是立体目标一个行人站在地面上按平面假设投影后会被无限拉长看起来像躺在地上的一条影子。IPM只能处理地面本身处理不了地面上的东西。后来LSSLift-Splat-Shoot类方法走的是显式深度估计路线逐像素预测深度分布把图像特征抬升到3D体素空间再拍平成BEV。它能处理立体目标但高度依赖深度估计的质量而且显式深度监督或者稠密深度损失的成本很高。BEVFormer选择了一条完全不同的路不放图像特征做变换而是先在BEV空间铺一批可学习的查询点让每个查询点去图像里找自己的证据。这就是由空间问视图的思路——视图变换不再是几何投影的一锤子买卖而是变成了一个可学习的注意力过程。理解这一点BEVFormer的所有结构设计就都有了支点。2. 核心架构拆解BEV queries把3D信息摊平了再融合2.1 Grid-shaped queries一张网格布铺在路面上BEVFormer在自车周围定义了一块3D空间论文在nuScenes上的默认配置是横向和纵向各51.2米共102.4米见方。这块空间被分成200×200的网格每个网格实际大小为0.4米。也就是说整个BEV区域就是一张密铺的网格布每个格子都是一个query。为什么用200×200而不是别的尺寸因为要在表达精度和计算量之间取平衡。0.4米的分辨率放在当前感知任务里是一个相对经济的值——再细一倍query数量翻四倍注意力计算量直接爆炸再粗一倍小目标的位置精度就不够了。这个分辨率的选择在后来的很多工作里都被沿用说明它基本踩中了大家公认的甜点。每个BEV query都带一个可学习的嵌入向量同时拼接上它所对应的网格坐标位置编码。位置编码有两个作用一是让网络知道这个query管的是哪块地面二是让多个query之间形成相对位置关系。在时空注意力里位置编码也是区分同一个位置不同时刻的重要线索。2.2 Spatial Cross-Attention3D参考点如何打到2D图上空间交叉注意力要解决的核心问题是一个BEV query该怎么决定去看哪个相机的哪个像素BEVFormer的做法很巧妙。它把每个BEV query从地面网格竖起来——在z轴上均匀采样4个3D参考点。这4个点代表这个网格位置在不同高度上可能存在物体。比如自行车轮子在地面附近车把在1米左右卡车货厢可能到3米。z轴的取值范围是-30米到1米默认情况下采样点高度都很低因为地面目标和贴近地面的物体是感知的主体。然后这4个3D参考点通过相机的内外参数矩阵投影到6个相机的图像平面上。投影点落在哪个相机的图像内注意力就在那个相机的图像上围绕投影点做采样。一个query往往会同时落在多个相机里——比如一个站在右前方的行人会同时出现在前视相机和右前相机的画面里。这样一来跨相机特征融合就不是检测完再拼而是在注意力层面直接对多视图证据做聚合。论文采用可变形注意力来采样每个投影点附近学习8个采样偏移位置网络决定从这些位置的图像特征里提取多少信息。多个相机、多个参考点采到的特征最后通过加权求和更新这个BEV query。这一套操作下来BEV query就变成了在图像中收集完证据后的空间特征表达。我在复现时发现理解这个流程最容易卡的地方是坐标变换的方向。记住这句话永远是从3D BEV出发投影到2D图像而不是反过来。一旦你把方向搞反后面所有维度都捋不顺。2.3 Temporal Self-Attention缓存的历史BEV是怎么帮现在回忆的只靠单帧图像很多感知难题无解。物体被完全遮挡、远处目标太小、运动方向判断不清都需要时间维度上的信息来帮忙。BEVFormer在结构上做了一个非常优雅的设计把历史帧的BEV特征缓存下来作为当前帧时间自注意力的key和value。具体做法是当前帧的每个BEV query在历史BEV特征上沿自己对应位置做可变形采样。这部分注意力输出与当前帧的BEV特征相加就得到带着时间记忆的BEV表示。这里有一个必须处理的细节——自车在运动。t-1时刻的某个位置到t时刻已经因为车辆移动而漂移了。比如路口的一个路灯杆前一帧在自车右前方5米这一帧可能就到了右前方4米。如果直接用当前query去历史BEV里按老位置采样采到的全是拖影。BEVFormer用自车运动信息来对齐根据两个时刻的自车位姿推算相对位移把历史BEV特征的整体坐标平移到当前自车坐标系下。对齐之后同一个物理位置在历史和当前特征里就对应于同一个BEV坐标时间注意力才能学到真正有价值的运动信息。这个时间注意力的价值在消融实验里看得非常清楚。论文把有时间建模的版本和没有时间建模的版本做了对比后者在高难度场景里表现明显下滑。更直观的感受是一辆车完全被前面的大货车挡住时单帧模型彻底丢失目标而带时间建模的模型能在历史帧里找到它之前的锚点即使当前完全看不到也能维持对它的预测。2.4 为什么这里还带了一个Deformable前缀BEVFormer的注意力层都被冠以Deformable前缀原因是它直接借用了可变形注意力机制。简单说传统Transformer的注意力要在所有位置上算相关性而可变形注意力只在一组稀疏的、由网络预测的偏移位置附近采样。对BEVFormer来说这个设计几乎是必须的。BEV区域有200×200等于4万个query如果每个query都对6个相机的全图做一次全局注意力哪怕图像不大计算量也完全不可接受。可变形注意力把去哪里采样变成了一个轻量回归问题每个query只需要在固定数量的采样点上做特征聚合。更关键的是可变形注意力和参考点投影之间形成了很好的配合。参考点投影给了采样一个物理上的位置先验——从BEV网格出发经过射影几何告诉注意力应该去图像哪个区域附近找证据注意力再在这个先验附近做微调学一些几何投影无法覆盖的偏差比如相机标定误差的补偿、物体高度的不确定性。你会发现这里没有一个参数是多余的每一个设计都在解决一个实际问题。3. 三大关键设计背后的权衡逻辑3.1 为什么不用全局注意力而是把稀疏采样坚持到底我第一次读论文时问自己既然Transformer这么厉害为什么BEVFormer不直接用vanilla self-attention让所有BEV query和所有图像token都互相看一遍很快算了一笔账就放弃了。4万个BEV query6路相机假设每路图像缩放到小尺寸也有2500个token全图注意力就是4万×1.5万的复杂度足有6亿量级的交互这在任何单卡上都跑不动。即便强行切块做局部注意力也会丧失跨相机全局关联的能力。可变形注意力换来的是计算量和表达能力的平衡。每个query只采样固定数量的点比如4个参考点、每个参考点周围8个采样点那一个query的图像交互就限制在几十的量级。更重要的是这些采样点不是均匀撒在图上而是通过可学习的偏移量动态调整。网络可以决定某个BEV格子应该看图像里的人和地面还是看天花板——这种灵活性是普通卷积或简单投影完全给不了的。3.2 视图变换中深度估计被隐式取代了LSS类方法的核心是先逐像素估计深度再把图像特征沿着相机射线填充到3D空间里。你把它理解成给每张图先画好距离刻度再按刻度把画布上的内容贴到立体空间。这种方式很直观但显式深度估计本身就是一个额外负担训练深度估计需要监督信号哪怕用自监督也避免不了额外的损失项。BEVFormer的query-driven方式则完全不同。BEV query通过可变形注意力直接在图像里找证据不需要先预测深度。深度信息被隐式编码进了网络学到的采样权重和采样偏移里。一个BEV query如果发现某个图像位置的特征能帮助自己理解空间中的目标它就会逐渐学会在那些位置投入更多注意力。这种隐式做法省去了深度监督训练目标更干净。代价是模型对深度的利用没有LSS类方法那么外显在某些极端尺度场景下比如远处很小的目标可能会比显式深度方法弱一些。但端到端训练的收益在大多数场景下更明显而且省下来的计算量可以投入到更强的时序建模中去。3.3 从检测到分割同一套BEV特征的可复用性论文不仅用BEVFormer做3D目标检测还在同一套BEV特征上做了地图分割实验。检测任务走的是query refinement路线分割任务则直接把BEV特征图接一个解码头输出道路边界、车道线、可行驶区域等语义。这引出了一个很重要的工程思想BEV encoder是一个通用底座。一旦把多相机图像高质量地转换成BEV特征下游任务就都可以在这个底座上搭新头而不是每个任务单独做一个视图变换模块。这篇论文之后很多自动驾驶感知模型都沿用了这个思路——用检测预训练好的BEV编码器再迁移到分割、预测等任务上去。这种先学通用表示再做任务微调的方法论在BEV时代被验证得越来越扎实。4. 论文里容易被忽略但很关键的实操细节4.1 预训练与微调的正确打开方式如果只看论文的主体结构很容易低估预训练权重的作用。BEVFormer的完整流程是先在大规模检测数据集上把BEV编码器训练好再在需要的时候把编码器冻结或微调接到下游任务上。实际操作中我体会最深的是不要急着冻结编码器。在分割任务上微调时如果数据量足够大保留编码器的梯度更新、用一个小学习率去训往往比直接冻结效果好。只有数据量很小、担心过拟合时冻结编码器才更稳妥。论文的实验更多是在展示这套特征具备可迁移性而具体怎么迁移还是要看你手头的数据规模。4.2 时间对齐中的姿态漂移问题时间自注意力依赖历史BEV特征而历史特征的是否精确又依赖自车位姿的精度。在真实数据上位姿给出的相对变换通常是可靠的但偶尔会有厘米级的漂移。如果对齐稍微错位时间注意力在历史特征里采样到的信息就会出现空间误差。这个误差对近距离大目标影响不大但对远处小目标几乎是致命的——本来就只有几个网格的响应一错位就采到背景上去了。从这个角度也解释了为什么带时间建模的模型在高速公路这种远处目标密度高的场景里收益最大。4.3 从BEVFormer能顺藤摸瓜摸出哪些后续脉络读论文不只是读懂这一篇更重要的是知道它如何被后续工作继承和发展。时间建模这条路后来被StreamPETR等改进成用临时query替代缓存BEV减轻了缓存特征和当前特征之间的表示鸿沟。任务统一这条路UniAD这类工作直接拿BEV特征作为决策模块的输入把检测、跟踪、预测、规划全部串起来。还有一条分支是稀疏query方向减少BEV网格的数量只用几十个query做目标级查询代表性的思路叫Sparse4D系列。它们很多概念都能在BEVFormer里找到对应参考点投影、时间对齐、可变形采样。所以把BEVFormer的坐标-投影-采样链条吃透后面读这几条技术脉络都会轻松很多。5. 复现和使用中的几个坑个人经验5.1 训不动先检查参考点在图像边界外的比例我第一次复现时遇到的情况是loss掉得很快但验证集指标卡住不动。后来统计了一下训练初期每个query平均能命中几个相机发现问题出在参考点分布上——很多偏远位置的query投影到图像边界之外完全没有拿到图像证据。排查方法是打印一批训练样本看每个BEV query投影到各相机后落在图像内部的平均点数。如果这个比例偏低优先检查z轴采样范围。默认配置里参考点高度都很低如果目标物离得很远或者相机俯仰角设置差异大就需要适当调整参考点高度。还有一个很实用的技巧把BEV范围稍微缩小一点点让边缘query不至于太稀疏整体收敛速度会有肉眼可见的提升。5.2 多帧缓存的内存开销比想象中大时间自注意力需要缓存历史BEV特征。训练时如果采样3到5帧历史显存占用会显著上涨。很多人在单卡上复现失败不是因为算力不够而是被这个缓存撑爆了。我的建议是最开始只用单帧历史跑通流程验证逻辑没问题后再逐步加大帧数。另外注意对历史BEV特征做梯度截断——历史帧的梯度传播对训练的贡献有限但显存开销巨大。在实际工程化部署中推理阶段缓存几帧的特征成本是完全可控的训练阶段的压力主要来自反向传播所以这个截断操作能帮你省出非常可观的显存。5.3 相机外参标定误差在BEV方法里会被方法放大透视模型里标定误差可能只造成几个像素的偏移效果上还能容忍。但BEV方法里3D参考点要经过完整的投影矩阵打到图像平面任何微小的外参偏移都会被投影过程放大尤其是距离车远的位置。典型现象是远处物体整体漂移或者同一个目标在相邻相机拼接处出现重影。遇到这类问题不要急着调网络先验一下相机的内参外参标定。我们在一个模拟项目里做过测试外参旋转误差哪怕只有0.1度对50米开外的目标也会造成接近1米的定位偏差。所以在真实车辆上部署BEV模型标定精度直接决定了模型上限。5.4 检测和分割联合训练时的损失平衡如果你想在同一套BEV特征上同时接检测头和分割头损失怎么配比会影响两边效果。简单地把检测损失和分割损失一比一相加往往会导致分割头收敛过快反过来拖慢检测头的学习节奏。我在实践里比较稳妥的做法分两步先用检测任务把BEV编码器训练收敛再开分割头把编码器和解码头一起精调几轮分割损失占比控制在一个较低的水平。比一次性把两个头从零开始联合训练稳定得多。这一点论文里不会明说属于跳进代码里才看得到的经验。最后再分享一个读论文的小技巧读BEVFormer这类以空间结构为核心的论文我的习惯是第一遍直接把坐标定义抄在纸上自车坐标系怎么建立、BEV范围多少、z轴怎么采样、相机的内外参从哪里读。坐标定义一旦清楚整个网络就是你看着坐标变换一步步走完的而不是跟着公式机械地看下去。这篇论文最值得我反复咀嚼的地方其实不是某个具体的注意力层而是它让表示直接回答空间问题的思路——不管下游任务是检测、分割还是更上层的决策先问清楚特征在哪里、代表什么、怎么获取再谈网络结构。把这个思维方式带进你读的每一篇BEV论文比记住任何一张架构图都更有用。
阅读完成 · 觉得有帮助?