0.概述
自动驾驶场景中会面临不同的遮挡情景,当相机只能观察到车辆的一侧时,通过关键点来确定全车的位置显得尤为重要。深度学习的进展使得通过多个视图检测车辆部件(车轮、前照灯、车门等)变得越来越可靠。Keypoint_EfficientNetb0通过编码器-解码器结构将Heatmap回归到车辆的关键点特征图,可以用于加强城市交通交叉路口的交通分析。本文为关键点检测算法Keypoint_EfficientNetb0的介绍和使用说明。
1.性能精度指标
Keypoint_EfficientNetb0模型配置:
infer/ms post-precess/ms 双核FPS 精度(PCK) 0.887 0.359 3290.12 浮点:0.9433 量化:0.9431 注:CarFusion数据集官方介绍:CarFusion
2.模型介绍
2.1 模型结构
Keypoint_EfficientNetb0网络采用了编码器-解码器结构,基于Heatmap进行车辆关键点的检测。Keypoint_EfficientNetb0由以下部分组成:
Backbone:使用Efficinetb0提取图像特征,更好地兼顾了性能和精度 ;
Decoder head:由3个反卷积层和1个卷积层组成,将Heatmap回归到关键点特征图;
Post process:对上采样后的特征进行max取值和平均,获取关键点目标。
2.2 源码说明
2.2.1 Config文件
configs/keypoint/keypoint_efficientnetb0_carfusion.py 为该模型的配置文件,定义了模型结构、数据集加载,和整套训练流程,所需参数的说明在算子定义中会给出。配置文件主要内容包括:
注: 如果需要复现精度,config中的训练策略最好不要修改,否则可能会有意外的训练情况出现。
2.2.2 Backbone
Keypoint_EfficientNetb0的backbone采用EfficinetNetb0提取图像特征,兼顾了性能和精度。Efficientb0的结构如下所示:

2.2.3 Decode head
Efficientnetb0提取图像特征后,解码器通过对特征图进行上采样并将Heatmap回归到关键点来处理提取的特征。解码器层由3个反卷积层和1个卷积层组成,反卷积层将特征图尺寸由4x4上采样到32x32, 然后使用卷积层将Heatmap回归到车辆的12个关键点,流程图如下所示:

代码如下所示:
2.2.4 Post process
通过编码器-解码器结构获得关键点预测后,对结果做后处理。后处理的mode为“averaged”,对Heatmap值最大点坐标周围区域的坐标和Heatmap值(大小为5 x 5)进行加权,以获得关键点的坐标和对应置信度。流程如下所示:

对应代码:
代码路径:
/usr/local/lib/python3.8/dist-packages/hat/models/task_modules/carfusion_keypoints/heatmap_decoder.py
/usr/local/lib/python3.8/dist-packages/hat/core/heatmap_decoder.py
3. 浮点模型训练
3.1 Before Start
3.1.1 发布物及环境部署
step1:获取发布物
step2:解压发布包
解压后文件结构如下:
step3:拉取docker环境
3.1.2 数据集准备
Keypoint_EfficientNetb0基于Carfusion数据集训练和验证,数据集的准备包括Carfusion数据集下载、裁剪和打包这3个步骤。
3.1.2.1 数据集下载
3.1.2.1 数据集下载
解压后的数据目录结构如下所示:
3.1.2.2 数据集裁剪
这里我们只考虑更简单的情形,即从检测好的汽车图片中检测12个关键点。因此,我们首先需要根据数据标注框从图片中裁剪出汽车。 运行以下命令即可将数据转换为裁剪好的格式:
脚本运行后的目录结构如下:
其中 keypoints_test.json 和 keypoints_train.json 分别包含测试集和训练集的标注。 每个样本以json字典格式存储,样式为: “img_path”: keypoints_list, 其中keypoints_list形状为(12,3),每行前两个元素为关键点坐标(x,y),第三个元素为关键点是否是有效的标注,当关键点不在图内或无效时,第三个元素为0。
关键点检测的12个类别为: "Right_Front_wheel", "Left_Front_wheel", "Right_Back_wheel", "Left_Back_wheel", "Right_Front_HeadLight", "Left_Front_HeadLight", "Right_Back_HeadLight", "Left_Back_HeadLight", "Right_Front_Top", "Left_Front_Top", "Right_Back_Top", "Left_Back_Top"
3.1.2.3 数据集打包
使用以下命令将训练数据集和验证数据集打包,格式为lmdb:
执行后会在target-data-dir下生成train_lmdb和test_lmdb,train_lmdb和test_lmdb就是打包之后的训练数据集和测试数据集,也是网络最终读取的数据集。打包完成后的目录结构如下所示:
3.1.3 config配置
在进行模型训练和验证之前,需要对configs文件中的部分参数进行配置,一般情况下,我们需要配置以下参数:
device_ids、batch_size_per_gpu:根据开发机实际硬件配置进行device_ids和每个gpu的batchsize的配置;
ckpt_dir: 权重路径配置,权重下载链接在configs/keypoint文件夹下的README.md中;
data_root: 配置为上节中打包的训练/验证数据集路径./tmp_data/carfusion;
pretrain_model_path :float训练时backbone的预训练权重,权重下载链接在configs/classification/README.md中。
3.2 浮点模型训练
在scripts/configs/keypoint/keypoint_efficientnetb0_carfusion.py下配置硬件参数、数据集路径和预训练模型路径,然后使用以下命令进行浮点训练:
float训练后模型ckpt的保存路径为config配置的ckpt_callback中save_dir的值,默认为ckpt_dir。
3.3 浮点模型精度验证
浮点模型训练完成以后,可以使用以下命令验证已经训练好的浮点模型精度:
4. 量化训练和编译
4.1 Calibration
模型完成浮点训练后,便可进行 Calibration。calibration在forward过程中通过统计各处的数据分布情况,从而计算出合理的量化参数。 通过运行下面的脚本就可以开启模型的Calibration过程:
4.2 Calibration 模型精度验证
Calibration完成以后,可以使用以下命令验证经过calib后模型的精度:
对于EfficietNet_Heatmap模型,仅做Calibration即可满足量化精度,无需做qat训练
4.3 量化模型精度验证
Calibration完成后,通过运行以下命令进行量化模型的精度验证:
4.4 仿真上板精度验证
除了上述模型验证之外,我们还提供和上板完全一致的精度验证方法,可以通过下面的方式完成:
4.5 量化模型编译
opt为优化等级,取值范围为0~3,数字越大优化等级越高,编译时间也会越长;out_dir为编译后产出物的存放路径。
运行后,会在out-dir目录下产出以下文件:
5. 其他工具
5.1 推理结果可视化
如果您想查看单张图片的关键点检测结果,tools目录下提供了关键点检测和可视化的脚本infer.py, 脚本运行方式如下:
--save-path:可视化结果保存路径;
通过修改config文件中infer_cfg字段中的img参数来配置输入图像路径。
可视化示例:

6. 板端部署
本节将介绍hbm模型编译完成后,在板端使用dnn工具进行性能评测和运行AI-Benchmark示例进行性能和精度评测的流程。
6.1 dnn工具评测
hbm模型编译成功后,可以在板端使用hrt_model_exec perf工具评测hbm模型的FPS,参考命令如下:
命令运行结束后,会在本地会产出profile.log和profile.csv日志文件,用以分析算子耗时和调度耗时。
6.2 AI Benchmark示例
fps.sh:实现多线程fps统计(多线程调度,用户可以根据需求自由设置线程数);
latency.sh:实现单帧延迟性能统计,包含模型推理和后处理延迟(单线程,单帧);
accuracy.sh:用于精度评测。
编译完成后,将ai_benchmark/j5/qat文件夹拷贝至板端:
然后在板端执行qat/script/detection/keypoint_efficientnetb0文件夹下的评测脚本。进入到需要评测的模型目录下,运行latency.sh 即可测试出单帧延迟, 如下所示:
终端输出的延迟包含模型推理耗时(Infer latency)和后处理耗时(Post process)。
运行fps.sh 即可测试出双核多线程fps, 如下所示:
