特斯拉不愿意开源的,被 BEVFormer 破解了!揭秘BEV特征提取的隐藏关卡

346 阅读6分钟

论文:《BEVFormer: Learning Bird’s-Eye-View Representation from Multi-Camera Images via Spatiotemporal Transformers

代码:github.com/fundamental…

需要中文版论文的朋友,可以关注公众号「于小咸」后台回复 「BEVFormer」获取

Motivation

  • 要生成 BEV Feature,一种思路是从图像空间投影到 BEV 空间,比如之前提到的 BEV学习笔记之-LSS,另一种思路就是找 BEV 空间下每个像素对应的相机空间特征,BEVFormer 采用了第二种思路
  • 因为传感器数据是连续的,那么前一帧的结果,对当前帧也会有帮助,特征可以在时序上做融合

Method

总体框架

BEVFormer 的整体框架图如下,按照时间顺序排布如下

  1. 图像特征提取:通过骨干网络提取多视角特征
  2. 用当前 BEV Query 与上一帧的 BEV Feature 做 self-attention,得到更新后的 BEV Feature
  3. 用第二步中的 BEV Feature 与多视角图片图像特征做 cross-attention,得到新的 BEV Feature
  4. 对第三步中得到 BEV Feature 过一个前馈神经网络,得到新的 BEV Feature
  5. 将上一步中的 BEV Feature 作为 query,重复六次步骤 2-4,得到最终的 BEV-Feature
  6. 在 BEV-Feature 结果上加多种 Head,实现不同任务

BEVFormer-Arch

BEV Query 鸟瞰图请求

BEV Query 为 WxHxC 的张量,表示宽 W 长 H 特征长度 C 的 BEV 特征,BEV Query 与 BEV 特征没有本质区别,当前层的 Feature 会作为下一层的 Query

需要注意区分的是参考点,参考点是 WxHxN 的张量,N 表示 z 方向采样点的数量,采样点分布在雷达为原点,向上 3m、向下 5m 的空间。考虑到雷达安装在车顶,距离地面大约 2m,实际 BEV 参考点的采样范围大约是 -3m ~ 5m 的空间,这样不仅可以覆盖绝大多数的高大障碍物,还可以感知到下坡路、上坡路

下面来介绍怎么把三维采样点,变为二维的 BEV 特征

Spatial Cross-Attention 空间注意力

已有三维空间中的参考点,根据外参和内参,可以将参考点投影到图像空间中,对应一个图像特征,把该图像特征转换到 BEV 空间下,通常有三种思路

  • 该图像特征与特征图中所有特征做 Attention
  • 该图像特征与附近的特征做 Attention
  • 只输出该 Attention

方法一资源消耗太高;方法三提取的特征不够丰富,对内参外参精度要求较高,可能会漏掉关键的信息;因此作者选择方案二,实现方案二的方式叫做 Deformable Attention

DeformAttm通过估计 offset ,跟特征图中对应的像素做 attention SCA(Qp,Ft)=1νhitiνhitj=1NrefDeformAttn(Qp,ρ(p,i,j),Fti)SCA(Q_p, F_t) = \frac{1}{\lvert\nu_{hit}\rvert}\sum_{i\in \nu_{hit}}\sum_{j=1}^{N_{ref}}DeformAttn(Q_p, \rho(p, i, j), F_t^i) 其中 νhit\nu_{hit} 表示命中的相机,由于相机视野问题,通常每个BEV参考点命中的只有 1~2 个相机

将所有的特征求和,就得到了 QpQ_p 的 BEV 特征

Temporal Self-Attention 时间注意力

时间注意力也用到了 Deformable Attention,考虑到车辆的运动速度,t1t-1 时刻坐标为 (x,y)(x,y) 的物体, tt 时刻也应该在 (x,y)(x,y) 附近,因此通过在 (x,y)(x,y) 附近做特征融合,就可以得到当前时刻的 BEV 特征。

TSA(Qp,{Q,Bt1})=V{Q,Bt1}DeformAttm(Qp,p,V)TSA(Q_p, \{Q,B'_{t-1}\})=\sum_{V\in \{Q,B'_{t-1}\}} DeformAttm(Q_p, p, V)

代码

相比于 LSS,BEVFormer 的代码复杂了许多,不是一个单独的代码库,而是基于 MMLab 的框架开发,使用了许多封装好的模块与函数,比如 Deformable Attention 就是用 CUDA 实现的。本文不过多涉及 MMLab,直接梳理 BEVFormer 的框架结构。大家可以参考我 fork 出来的项目 BEVFormer-annotated,我会把注释更新到代码库里。考虑到阅读体验,文章内只贴索引,不贴大段代码。

模型训练和验证的代码在 BEVFormer/tools/ 目录下,模型生成调用了 mmdetection3d 库中的 build_model,输入是模型结构配置文件,下面直接从配置文件开始介绍

模型结构概览

BEVFormer 的模型结构定义在 projects/configs/bevformer/ 目录下,总共包含 base、small、tiny 三个版本,三个版本网络结构基本一致,差别在于每个模块的参数配置。模型主要有三个组成部分:

bevformer
├── img_backbone:使用 ResNet
├── img_neck:使用 FPN
└── pts_bbox_head:BEVFormer 的核心模块+bbox检测头

pts_bbox_head 的组织结构如下,由编码器(encoder)、解码器(decoder)、bbox 检测头 和 位置编码组成:

  • 其中 encoder 用来提取 BEV 特征,总共由6层transformer,核心部分就是 时序自注意模块 TemporalSelfAttention 和 空间交叉注意力模块 SpatialCrossAttention
  • decoder 用来解码 BEV 特征,使用多头注意力输出特征给 bbox 检测头使用
transformer
├── encoder
│   ├── transformerlayers x 6
│   │   ├── TemporalSelfAttention
│   │   └── SpatialCrossAttention
│   │       └── MSDeformableAttention3D
└── decoder
    ├── transformerlayers x 6
    │   ├── MultiheadAttention
    │   └── CustomMSDeformableAttention
├── bbox_coder
└── positional_encoding

数据处理流程

BEVFormer 定义在 projects/mmdet3d_plugin/bevformer/detectors/bevformer.py,继承自 mmdet 的 MVXTwoStageDetector。从 BEVFormer 的 forward() 函数入手,可以把 bevformer 的整体流程串起来,依次执行了:

  • 历史特征获取(图像&BEV)
  • 图像特征提取 extract_feat
  • bbox检测 pts_bbox_head

看配置文件我们可以得知,pts_bbox_head 的类型是 BEVFormerHead,定义在 projects/mmdet3d_plugin/bevformer/dense_heads/bevformer_head.py

在 BEVFormerHead 的 forward() 函数中,主要执行了以下两步:

  • 生成 bev query 和 obj query
  • 调用 transformer 获取特征

transformer 类型为 PerceptionTransformer,定义在 projects/mmdet3d_plugin/bevformer/modules/transformer.py中,它的 forward() 函数执行以下步骤:

  • get_bev_features 获取 bev 特征
    • 初始化 bev query 和 位置编码
    • 补偿车体运动,将历史 BEV feature 对齐到当前坐标系下
    • 添加 CAN 信号
    • 多层级特征展平与位置编码
    • 调用 encoder 提取 BEV 特征
  • 调用 decoder 输出特征给下游

经过这么多层的调用后,我们终于接触到了 BEVFormer 的核心 encoder 部分,encoder 类型是 BEVFormerEncoder,跟它调用的 BEVFormerLayer ,都定义在 projects/mmdet3d_plugin/bevformer/modules/encoder.py文件中。

BEVFormerEncoder 的 forward 主要执行了采样操作,生成了 ref_3d 和 ref_2d,分别用于 空间交叉注意力 和 时序BEV自注意力

BEVFormerLayer 继承自 MyCustomBaseTransformerLayer,定义在 projects/mmdet3d_plugin/bevformer/modules/custom_base_transformer_layer.py 中,MyCustomBaseTransformerLayer 主要作用是把 时序注意力 和 空间注意力的一部分通用能力抽象合并到一起

BEVFormerLayer 通过一个 for 循环,遍历所有 attention 模块

  • 空间交叉注意力 的类型是 SpatialCrossAttention,定义在 projects/mmdet3d_plugin/bevformer/modules/spatial_cross_attention.py
  • 时序BEV自注意力 的类型是 TemporalSelfAttention,定义在 projects/mmdet3d_plugin/bevformer/modules/temporal_self_attention.py

参考资料