写在前面:
对于BEVFormer算法框架的整体理解,大家可以找到大量的资料参考,但是对于算法代码的解读缺乏详实的资料。因此,本系列的目的是结合代码实现细节、在tensor维度的变换中帮助读者对算法能有更直观的认识。
本系列我们将对BEVFormer公版代码(开源算法)进行逐行解析,以结合代码理解Bevformer原理,掌握算法细节,帮助读者们利用该算法框架开发感知算法。在本系列的最后笔者还将面向地平线的用户,指出地平线参考算法在开源算法基础上做出的修改及修改背后的考虑,在算法部署过程中为用户提供参考。
公版代码目录封装较好,且以注册器的方式调用模型,各个模块的调用关系可以从configs/bevformer中的config文件中清晰体现,我们以bevformer_tiny.py为例3解析代码。
对代码的解析和理解主要体现在代码注释中。
从上述config文件可以看出,6个相机输出的图像在前向传播过程中依次经过了'ResNet'、'FPN'获得了图像特征,然后经过'BEVFormerHead'模块中的'BEVFormerEncoder'和'DetectionTransformerDecoder'完成了特征融合的全过程。其中'BEVFormerEncoder'包括前后级联的'TemporalSelfAttention'和'SpatialCrossAttention',这种前后级联的结构在bevformer_tiny中一共有3层。
1 BEVFormer:
功能:
通过grid_mask进行了图像增强;
利用ResNet(backbone)和FPN(neck)两个网络提取图像特征;
进入BEVFormerHead中。
解析:
2 BEVFormerHead:
功能:
定义了后面要使用的bev_queries(即论文中BEV Queries)、bev_pos(表征BEV Queries各个Query的位置信息)、query_embeds;
计算了后续要使用的pc_range、real_w和real_h;
从该模块进入PerceptionTransformer。
解析:
3 PerceptionTransformer:
功能:
利用level_embeds、cams_embeds对img_feats进行图像增强
将can_bus信息融入bev_queries
如果存在prev_bev,将prev_bev进行旋转以便与当前bev对齐
从该模块进入Encoder
解析:
4 Encoder:
功能:
生成ref_3d和ref_2d,供后续TSA、CSA模块中的deformable attentiuon采样使用;
利用6个相机的内参、外参,将真实尺度下的ref_3d从自车坐标系(Lidar坐标系)投影到6个相机的像素坐标系内,判断哪些点会出现在哪些相机内,该信息体现在bev_mask内;
循环进入3个相同的BEVFormerLayer模块,一个BEVFormerLayer包含 ('self_attn', 'norm', 'cross_attn', 'norm', 'ffn', 'norm')。
解析:
prev_bev已经通过和bev对齐,这里的ref_2d没有必要在+shift,因为prev_bev已经对齐了,prev_bev的ref_2d和bev的ref_2d保持一致就好
公版算法:
shift_ref_2d = ref_2d.clone()
shift_ref_2d += shift[:, None, None, :]
bs, len_bev, num_bev_level, _ = ref_2d.shape
hybird_ref_2d = torch.stack([shift_ref_2d, ref_2d], 1).reshape(
bs*2, len_bev, num_bev_level, 2)
参考算法:
shift_ref_2d = ref_2d.clone()
bs, len_bev, num_bev_level, _ = ref_2d.shape
hybird_ref_2d = torch.stack([shift_ref_2d, ref_2d], 1).reshape(
bs * 2, len_bev, num_bev_level, 2
)
4.1 TemporalSelfAttention:
功能:
Temporal Self-Attention 模块为自注意力,提取了前一个时刻的BEV特征作为先验知识提高 BEV Query 的建模能力,相比于直接初始query来说融合历史的bev特征更能提高 BEV Query 的建模能力。用一个生动形象的图来表现下吧:

解析:
4.2 SpatialCrossAttention:
功能:
Temporal Self-Attention 模块为自注意力,提取了前一个时刻的BEV特征作为先验知识来提高 BEV Query 的建模能力,相比于直接初始query来说融合历史的bev特征更能提高 BEV Query 的建模能力,用一个生动形象的图来表现下吧:

解析:
未完待续。。。。

