0 概述
近年来2D目标检测得到了很好的探索,并使自动驾驶等各种应用受益。当自动驾驶汽车需要在道路上平稳安全地行驶时,它必须拥有周围物体的准确3D信息,才能做出安全的决策。因此,3D目标检测在这些机器人应用中变得越来越重要。单目3D目标检测作为一种简单而廉价的部署形式,成为当今一个非常有意义的研究问题,因此,地平线集成了单目3D目标检测算法。本文为fcos3d参考算法的介绍和使用说明。
该示例为参考算法,仅作为在J5上模型部署的设计参考,非量产算法
1 性能精度指标
fcos3d模型配置:
数据集 Input shape Backbone Neck Head NuScenes 1x3x512x896 efficientnetb0 BiFPN FCOS3DHead 性能精度表现:
性能(双核FPS)浮点/量化精度 mAPNDS 589 0.2130/0.2097 0.3059/0.3023
注:Nuscenes 数据集官方介绍:Nuscenes
2 模型介绍
Fcos3d是在fcos基础上进行改进的一种anchor-free的单目3D目标检测算法,将通常定义的7-DoF 3D目标转换到图像域,并将它们解耦为2D和3D属性。考虑到目标的二维比例,将目标分布到不同的特征级别,并仅根据三维中心进行进一步分配。此外,利用基于3D中心的2D高斯分布来重新定义中心度,以拟合3D目标公式。所有这些都使该框架简单而有效,消除了任何2D检测或2D-3D对应先验。在NeurIPS 2020的nuScenes 3D检测挑战中,fcos3d算法在所有纯视觉方法中排名第一。
2.1 模型优化点
相对于官方实现,地平线对fcos3d做了如下优化:
将模型的backbone替换为与地平线硬件更为友好的efficientnetb0,提升了模型的性能;
neck网络优化为bifpn,这种重复双向跨尺度连接+ 带权重的特征融合机制,实现了更高层次的特征融合;
检测头中的卷积运算使用深度可分离卷积,大幅优化了模型的性能;
2.2 源码说明
2.2.1 Config文件
configs/detection/fcos3d/fcos3d_efficientnetb0_nuscenes.py 为该模型的配置文件,定义了模型结构、数据集加载,和整套训练流程等。配置文件主要内容包括:
注: 如果需要复现精度,config中的训练策略最好不要修改,否则可能会有意外的训练情况出现。
2.2.2 image encoder
Image encoder是对图像进行特征提取和融合。fcos3d参考算法通过backbone(efficientnetb0)和neck(BiFPN)提取图像的多尺度特征。网络结构如下图所示:

backbone
fcos3d参考算法采用与硬件比较友好的efficientnetb0作为backbone来提取图像多尺度特征,实现了性能的提升。
neck
fcos3d用于多级分支构造的neck采用的是bifpn,是用于检测不同尺度目标的主要组件,其特性可以总结为重复双向跨尺度连接+ 加权特征融合机制。bifpn将每个双向路径(自顶向下和自底而上)作为一个特征网络层,并重复同一层多次,以实现更高层次的特征融合;另外,不同的输入 featuremap 具有不同的分辨率,它们对融合输入 featuremap 的贡献也是不同的,因此简单的对他们进行相加或叠加处理并不是最佳的操作,所以bifpn实现了简单而高效的加权特征融合的机制。
2.2.3 FCOS3DHead
fcos3d不同级别的图像特征使用共享的检测头,首先通过efficientnetb0+bifpn网络提取多尺度特征,将目标分配到不同的特征级别和不同的点;然后多尺度特征通过4个共享深度可分离卷积block和small heads回归到不同的目标(如下图所示),这种为具有不同测量值的回归目标建立额外的解耦头的做法更加有效。

FCOS3DHead回归目标包括以下部分:
- cls_score: 分类分数
Δx\Delta xΔx,Δy\Delta yΔy,log(d)log(d)log(d): 2.5D中心到特定前景点的偏移、 以及其相应的深度d
W,H,L,θW,H,L,\thetaW,H,L,θ: 回归框尺寸和旋转角度
vx,vyv_x,v_yvxu200b,vyu200b: 回归速度
CθC_{\theta}Cθu200b: 即2-bin direction classification,考虑相反方向的目标具有相同的 sin(θ)sin(\theta)sin(θ)值
- attr_pred: 属性预测
- centerness: 即3D Center-ness,它作为一个softmax二分类器来确定哪些点更靠近中心,并有助于抑制那些远离目标中心的低质量预测
2.2.4 FCOS3DTarget
FCOS3DTarget的作用是在训练阶段生成分类/回归目标用于loss计算,包括labels_3d, bbox_targets_3d, centerness_targets 和 attr_targets。
points获取
与基于锚的检测器通过将预定义的锚框作为参考来回归目标不同,fcos3d作为anchor-free的目标检测范式,通过特征图上的每个点来预测目标,该点对应于原始输入图像上均匀分布的点。fcos3d是通过特征图的尺寸和stride的计算获得points,对于特征图FiF_iFiu200b上的每个位置(x,y),假设直到第i层的总stride是s,那么原始图像上的相应points位置应该是:
(sx+⌊s2⌋,sy+⌊s2⌋)(sx+\left \lfloor \frac{s}{2} \right \rfloor,sy+\left \lfloor \frac{s}{2} \right \rfloor)(sx+⌊2su200b⌋,sy+⌊2su200b⌋)
对应代码:
centerness计算
由于fcos3d的回归目标改为基于3D中心的范式,通过以投影的3D中心为原点的2D高斯分布来定义centerness。二维高斯分布简化为:
c=e−α((Δx)2+(Δy)2)c=e^{-\alpha((\Delta x)^2+(\Delta y)^2)}c=e−α((Δx)2+(Δy)2)
这里,α\alphaα用于调整从中心到外围的强度衰减,并设置为2.5。fcos3d将c作为centerness的groundtruth,并从回归分支对其进行预测,以便稍后过滤低质量的预测。
对应代码:
FCOS3DTarget的forward代码为:
2.2.5 Loss
获取到labels_3d, bbox_targets_3d,centerness_targets, attr_targets等分类回归groundtruth后,需要在训练阶段进行loss的计算。fcos3d参考算法的损失定义与公版一致,对于分类和不同的回归目标,分别定义它们的损失,损失函数的设置在config文件中:
2.2.6 PostProcess
fcos3d的3D边界框的回归采用了比较简单的方法,即把通常定义的7-DoF(3D bbox中心、尺寸和偏转角)回归目标转换为2.5D中心和3D尺寸。通过相机固有矩阵,可以将2.5D中心转换回3D空间,因此,对2.5D中心进行回归可以进一步简化为对从中心到特定前景点的偏移量∆x、∆y及其相应深度d进行回归。所以,在获取到回归目标后,在后处理阶段进行了坐标转换和非极大值抑制(Non-Maximum Suppression,NMS)等操作,将class score和centerness相乘作为每个预测的置信度,并在鸟瞰图中作为大多数3D检测器进行旋转的NMS,以获得最终结果。
置信度计算
fcos3d的后处理阶段是根据分类分数cls_score和centerness的乘积来筛选3d bbox的,对乘积的结果进行降序排列后,选择前100个作为我们需要的bbox,流程如下图所示:

相关代码如下所示:
非极大值抑制
fcos3d通过计算投影的3D边界框的外部矩形来生成2D边界框,然后,在鸟瞰图中作为大多数3D检测器进行旋转的非最大值抑制,以获得最终结果。相关代码如下所示:
forward代码为:
3 浮点模型训练
3.1 Before Start
3.1.1 发布物及环境部署
step1:获取发布物
step2:解压发布包
解压后文件结构如下:
step3:拉取docker环境
3.1.2 数据集准备
3.1.2.1 数据集下载
Full dataset(v1.0)包含多个子数据集,如果不需要进行v1.0-trainval数据集的浮点训练和精度验证,可以只下载v1.0-mini数据集进行小场景的训练和验证。
将下载完成的v1.0-trainval01_blobs.tar~v1.0-trainval10_blobs.tar、v1.0-trainval_meta.tar和can_bus.zip进行解压,解压后的目录如下所示:
3.1.2.2 数据集打包
--src-data-dir为解压后的nuscenes数据集目录;
--target-data-dir为打包后数据集的存储目录;
--version 选项为["v1.0-trainval", "v1.0-test", "v1.0-mini"],如果进行全量训练和验证设置为v1.0-trainval,如果仅想了解模型的训练和验证过程,则可以使用v1.0-mini数据集;v1.0-test数据集仅为测试场景,未提供注释。
全量的nuscenes数据集较大,打包时间较长。每打包完100张会在终端有打印提示,其中train打包约28100张,val打包约6000张。
3.1.2.3 meta文件夹构建
3.1.3 config配置
在进行模型训练和验证之前,需要对configs/detection/fcos3d/fcos3d_efficientnetb0_nuscenes.py文件中的部分参数进行配置,一般情况下,我们需要配置以下参数:
device_ids、batch_size_per_gpu:根据实际硬件配置进行device_ids和每个gpu的batchsize的配置;
ckpt_dir:浮点、calib、量化训练的权重路径配置,权重下载链接在config文件夹下的README中;
data_rootdir:3.1.2.2中打包的数据集路径配置;
meta_rootdir :3.1.2.3中创建的meta文件夹的路径配置;
float_trainer下的checkpoint_path:浮点训练时backbone的预训练权重所在路径,可以使用README的# Backbone Pretrained ckpt中ckpt download提供的float-checkpoint-best.pth.tar权重文件。
3.2 浮点模型训练
config文件中的参数配置完成后,使用以下命令训练浮点模型:
float训练后模型ckpt的保存路径为config配置的ckpt_callback中save_dir的值,默认为ckpt_dir。
3.3 浮点模型验证
浮点模型训练完成以后,可以使用以下命令验证已经训练好的浮点模型精度:
4 模型量化和编译
4.1 Calibration
模型完成浮点训练后,便可进行 Calibration。calibration在forward过程中通过统计各处的数据分布情况,从而计算出合理的量化参数。 通过运行下面的脚本就可以开启模型的Calibration过程:
4.2 Calibration 模型精度验证
Calibration完成以后,可以使用以下命令验证经过calib后模型的精度:
模型经过 Calibration 后的量化精度若已满足要求,便可直接进行转定点模型的步骤,否则需要进行量化训练进一步提升精度。
4.3 量化训练
fcos3d经过 Calibration 后的量化精度未能满足要求,所以需要使用以下命令进行量化训练:
4.4 qat模型精度验证
量化训练完成后,通过运行以下命令验证qat模型的精度:
4.5 量化模型精度验证
通过运行以下命令验证量化模型的精度:
qat模型的精度验证对象为插入伪量化节点后的模型(float32);quantize模型的精度验证对象为定点模型(int8),验证的精度是最终的int8模型的真正精度,这两个精度应该是十分接近的。
4.6 仿真上板精度验证
除了上述模型验证之外,我们还提供和上板完全一致的精度验证方法,可以通过下面的方式完成:
4.7 量化模型编译
在量化训练完成之后,可以使用compile_perf.py脚本将量化模型编译成可以板端运行的hbm模型,同时该工具也能预估在BPU上的运行性能,compile_perf脚本使用方式如下:
opt为优化等级,取值范围为0~3,数字越大优化等级越高,编译时间也会越长;
可以指定--out_dir为编译后产出物的存放路径,默认在ckpt_dir的compile文件夹
运行后,ckpt_dir的compile目录下会产出以下文件:
5 其他工具
5.1 结果可视化
如果你希望可以看到训练出来的模型对于单帧图像的检测效果,我们的tools文件夹下面同样提供了预测及可视化的脚本,你只需要运行以下脚本即可:
推理脚本中的参数:
- save_path:推理可视化结果保存路径;需在config文件中配置infer_cfg字段。
可视化示例:

6 板端部署
6.1 上板性能实测
使用hrt_model_exec perf工具将生成的.hbm文件上板做BPU性能FPS实测,hrt_model_exec perf参数如下:
6.2 AIBenchmark 示例
可在板端使用以下命令执行做模型评测:

