OccNet注意力机制解析:时间自注意力与空间交叉注意力是如何工作的?
OccNet注意力机制解析时间自注意力与空间交叉注意力是如何工作的【免费下载链接】OccNet[ICCV 2023] OccNet: Scene as Occupancy项目地址: https://gitcode.com/gh_mirrors/oc/OccNetOccNetICCV 2023提出了场景即占据Scene as Occupancy的理念与其只画几个 3D 框不如把整个空间体素化逐格预测这里有没有东西、是什么东西。而这一切的引擎正是 OccNet注意力机制——一对分工明确的搭档时间自注意力Temporal Self-AttentionTSA和空间交叉注意力Spatial Cross-AttentionSCA。本文就用最通俗的语言拆解这两个核心模块到底是如何工作的。先认识 OccNet把世界变成乐高积木OccNet 以环视相机图像为输入输出一个 200×200×16 的 3D 占据网格每个 0.4m 见方的小格子都被标注为空闲或属于某类物体同时还能预测每个格子的运动速度flow。下图直观展示了真实场景与占用网格的对应关系要完成这个任务模型必须解决两个难题现在怎么融合多相机信息、过去怎么利用历史帧信息。前者交给空间交叉注意力后者交给时间自注意力。OccNet注意力机制总览一条 BEV 的诞生之路整个流程可以浓缩成一条流水线对应 transformer_occ.py 的get_bev_features6 路相机图像经过 ResNet50 FPN得到 4 个尺度的多相机特征预置 200×200 40000 个 BEV query铺满自车周围的鸟瞰平面这些 query 依次穿过4 层 BEVFormer 编码层每层的执行顺序固定为时间自注意力 → 归一化 → 空间交叉注意力 → 归一化 → FFN → 归一化见配置文件 bevformer_base_occ.py 的operation_order输出 BEV 特征后由 3D 解码器扩展出 16 个高度层最终预测每个体素的类别与流速。也就是说注意力机制全部发生在第 3 步下面分别深入这两个模块。时间自注意力是如何工作的——让模型记住上一帧想象你开车经过一个路口上一帧能看到路牌这一帧被卡车挡住。单看一帧路牌就消失了。时间自注意力TSA解决的正是这个问题——它让当前帧的每个 BEV query 主动去翻旧账从上一帧的 BEV 特征中找回被遮挡或模糊的信息。在 temporal_self_attention.py 中TemporalSelfAttention的实现有 4 个关键设计BEV 队列长度为 2模型维护一个历史 BEV 和当前 BEV二者拼成队列num_bev_queue2query 由历史特征 当前 query拼接而成让模型知道该以谁为参照运动补偿自车在动同一物体的位置在两帧间发生了位移。代码里用can_bus提供的偏航角旋转历史 BEVrotate_prev_bevTrue把上一帧对齐到当前坐标系再把参考点做平移shift_ref_2d这就是对齐的本质只采样少量点TSA 沿用 Deformable DETR 的可变形注意力每个 query 只在 BEV 平面上的少量采样点默认 8 个取特征而不是全图注意力计算量大幅下降加权融合历史与当前两路输出按均值融合mean(-1)完成时序信息的合并。一句话总结时间自注意力 对齐历史 稀疏采样 时序融合让 BEV 特征带上记忆。空间交叉注意力是如何工作的——让 BEV 去看图像时间维度解决后空间维度怎么把 2D 图像信息抬升到 BEV这正是空间交叉注意力SCA的核心实现在 spatial_cross_attention.py。它的思路非常巧妙让每个 BEV 格子竖起一根柱子从柱子里取几个 3D 参考点投影到相机图像上取特征。具体分四步生成 3D 参考点在 encoder.py 的get_reference_points中沿每个柱子的高度方向均匀采样 8 个点num_points_in_pillar8形成 3D 坐标投影到 6 个相机point_sampling用 lidar→相机的外参矩阵把这 8 个 3D 点投影到每张相机图上得到 2D 像素坐标同时用bev_mask过滤掉落在图像外的点比如被自车挡住、超出视野可变形注意力采样投影后的 2D 点作为参考点MSDeformableAttention3D在 4 级 FPN 特征上各采样 8 个偏移点取回图像特征多相机聚合一个 BEV 格子可能同时被多个相机看到代码里每个相机只与看得到它的BEV query 交互能大幅省显存最后把多个相机的结果按可见相机数量做平均归一化。一句话总结空间交叉注意力 柱体采样 3D 投影 多相机聚合把图像像素翻译成BEV 格子的特征。两大注意力的协作一次完整的前向传播把两个模块串起来看一次前向传播就像一次复盘会每个 BEV query 先开时间会TSA看向上一帧的自己找回被遮挡信息再开空间会SCA向 6 个相机提问收集当前时刻各视角的证据经过 FFN 提炼后进入下一层编码器重复同样的流程——4 层之后每个 BEV 格子就同时拥有了时间上的记忆和空间上的多视角信息最终 BEV 特征被 3D 解码器拉伸成 16 层高的体素网格输出占据类别与流速见 transformer_occ.py 的decoder与predicter。值得一提的是TSA 与 SCA 都建立在可变形注意力之上不计算全部位置的注意力权重而是学习该往哪里看这让整个编码器在 40000 个 query、4 级特征、6 个相机的规模下依然可控。小结OccNet注意力机制的两把钥匙维度时间自注意力TSA空间交叉注意力SCA解决的问题时序遮挡、单帧信息不足多相机 2D → 3D 特征融合参考点在哪2D BEV 平面3D 柱体 投影到图像信息来源历史 BEV 特征当前帧多相机图像特征关键技巧运动补偿、BEV 队列柱体采样、bev_mask、多相机聚合核心代码temporal_self_attention.pyspatial_cross_attention.py理解了这对搭档你就抓住了 OccNet 乃至整个 BEVFormer 家族的灵魂时间自注意力负责不忘过去空间交叉注意力负责看清现在二者交替作用最终让模型在纯视觉输入下也能输出稳定、稠密的 3D 占据预测。这也是场景即占据从论文走向自动驾驶落地的最关键一环。【免费下载链接】OccNet[ICCV 2023] OccNet: Scene as Occupancy项目地址: https://gitcode.com/gh_mirrors/oc/OccNet创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考