0 概述
在深度学习领域,backbone作为神经网络特征提取的重要部分,在一定程度上决定了任务的最终结果。为了应对更高等级的自动驾驶场景,地平线提出了与J5芯片深度耦合的高效网络结构MixVargGENet。本文将基于ImageNet数据集,对以MixVargGENet为backbone的分类算法进行介绍和使用说明。
该示例为参考算法,仅作为在J5上模型部署的设计参考,非量产算法
1 性能精度指标
dataset 输入大小 分类精度 帧率(J5/双核) ImageNet 1x3x224x224 0.7133(浮点)0.7066(定点) 5790.35 2 模型介绍
2.1 模型设计思路
MixVarGENet高度秉承了“软硬结合”的设计理念,针对J5芯片的大算力特性做了一些定制化设计,其设计思路可以总结为:
小channel时使用normal conv,发挥J5大算力优势;
大channe时引入group conv,缓解带宽压力;
Block内部扩大channel,提升网络算法性能;
缩短feature复用时间间隔,减少SRAM到DDR访存。
2.2 源码说明
config文件
注: 如果需要复现精度,config中的训练策略最好不要修改。否则可能会有意外的训练情况出现。
MixVarGEBlock

并且,head_op 和stack_op都是由BasicMixVarGEBlock(如mixvarge_f2,mixvarge_f4,mixvarge_f2_gb16)这样的基本单元构成。
MixVarGENet模型的主要构成可以用BasicMixVarGEBlock表示:
stage 0 stage 1 stage 2 stage 3 stage 4 head_op mixvarge_f2 mixvarge_f4 mixvarge_f4 mixvarge_f2_gb16 mixvarge_f2_gb16 stack_op None 2*mixvarge_f4 2*mixvarge_f4 6*mixvarge_f2_gb16 2*mixvarge_f2_gb16 注:这里需要指出stage0是不含有stack_op的特殊MixVarGEBlock。
head op和stack op
head op 和stack op 是MixVarGENet中基本的计算单元,共享相同的结构空间,它们都是由BasicMixVarGEBlock组成。
BasicMixVarGEBlock
BasicMixVarGEBlock是构成head_op和stack_op的基本单元,基于J5芯片计算特性对其结构进行了定制化设计。BasicMixVarGEBlock结构示意图如下所示:

BasicMixVarGEBlock的基本结构由两个conv及一个shortcut组成,它在小通道数时使用normal conv,大通道数时使用group conv,还在block内部通过factor扩大通道数来提高模型性能。下面是BasicMixVarGEBlock中的两个conv层的定义代码:
BasicMixVarGEBlock的内部的两个conv层参数mid_channle、conv1_kernel_size、conv1_groups、conv2_kernel_size、conv2_groups都是由类似于"mixvarge_f2"的BasicMixVarGEBlock中的键值对定义的,可以通过配置不同的BasicMixVarGEBlock来组成head op和stack op。
BLOCK_CONFIG
mixvarge_f2,mixvarge_f4,mixvarge_f2_gb16的结构是在hat/models/base_modules/basic_MixVarGENet_module.py中进行定义的,分别对应着不同结构的BasicMixVarGEBlock,相关配置细节如下表所示:
BasicMixVarGEBlock Block Config mixvarge_f2 {"conv2_kernel_size": 1, "padding": 0, "factor": 2} mixvarge_f4 {"conv2_kernel_size": 1, "padding": 0, "factor": 4} mixvarge_f2_gb16 { "conv2_kernel_size": 1, "padding": 0, "factor": 2, "conv1_group_base": 16,} 上表中的参数含义是:
- "conv2_kernel_size" 和"padding"定义了ConvModule2d卷积核的大小和padding的方式;
- "factor" 是Block内部扩大channel的因子,它的取值根据featuremap大小来确定,通常为2的倍数,如果factor=2,那么中间卷积层mid_channle的大小就是in_channels * 2;
- "conv1_group_base" 定义了ConvModule2d组卷积运算参数,它的取值根据芯片的计算模式,通常为8的倍数,这样就不会引入额外的padding;
downsample layers
downsample layers是kernel=3,stride=2的卷积,将当前stage的featuremap下采样,以便后续的stage 的fusion layer使用。如下为downsample layers中卷积层的代码:
fusion layer
fusion layers是pointwise卷积,用于将前几个stage的featuremap映射到当前stage,比如Stride 16的head_op 的fusion_strides包含了Stride 4和Stride 8的下采样结果。fusion layers的示意图如下所示:

3 浮点模型训练
3.1 Before Start
3.1.1 发布物及环境部署
step1:获取发布物
step2:解压发布包
解压后文件结构如下:
step3:拉取docker环境
3.1.2 数据准备
3.1.2.1 数据集下载
3.1.2.2 数据集打包
将数据集解压之后,使用以下命令进行打包:
train_lmdb 和 val_lmdb 就是打包之后的训练数据集和验证数据集,也是神经网络最终读取的数据集。
3.1.3 config配置
在进行模型训练和验证之前,需要对configs文件中的部分参数进行配置,一般情况下,我们需要配置以下参数:
device_ids、batch_size_per_gpu:根据实际硬件配置进行device_ids和每个gpu的batchsize的配置;
ckpt_dir: 浮点、calib、量化训练的权重路径配置,权重下载链接在config文件夹下的README中;
data_loader中的data_path:上节中打包的train_lmdb路径;
val_data_loader中的data_path :上节中打包的val_lmdb路径;
3.2 浮点模型训练
float训练后模型ckpt的保存路径为config配置的ckpt_callback中save_dir的值,默认为ckpt_dir。
3.3 浮点模型精度验证
浮点模型训练完成以后,可以使用以下命令验证已经训练好的浮点模型精度:
4 模型量化和编译
4.1 Calibration
模型完成浮点训练后,便可进行 Calibration。calibration在forward过程中通过统计各处的数据分布情况,从而计算出合理的量化参数。 通过运行下面的脚本就可以开启模型的Calibration过程:
4.2 Calibration 精度验证
Calibration完成以后,可以使用以下命令验证经过calib后模型的精度:
对于MixVarGENet模型,仅做Calibration即可满足量化精度,无需做qat训练!
4.3 量化模型精度验证
Calibration完成后,通过运行以下命令进行量化模型的精度验证:
4.4 仿真上板精度验证
4.5 模型量化编译
opt为优化等级,取值范围为0~3,数字越大优化等级越高,编译时间也会越长;out_dir为编译后产出物的存放路径。
运行后,会在out-dir目录下产出以下文件:
5 结果可视化
如果你希望可以看到训练出来的模型对于单帧的检测效果,我们的tools文件夹下面同样提供了单帧预测及可视化的脚本, 你只需要按照infer.py中的格式给出每张图片的大小以及单应矩阵, 然后运行以下脚本即可:
1.输入图像路径通过修改config文件中infer_cfg字段中的infer_inputs来配置;
2.--save-path为可视化结果的保存路径。
6 板端部署
本节将介绍hbm模型编译完成后,在板端使用dnn工具进行性能评测和运行AI-Benchmark示例进行性能和精度评测的流程。
6.1 dnn工具评测
hbm模型编译成功后,可以在板端使用hrt_model_exec perf工具评测hbm模型的FPS,参考命令如下:
命令运行结束后,会在本地会产出profile.log和profile.csv日志文件,用以分析算子耗时和调度耗时。
6.2 AI Benchmark示例
可在板端使用以下命令执行做模型评测:


