专栏算法工具链【参考算法】地平线 PETR 参考算法-v1.2.2

【参考算法】地平线 PETR 参考算法-v1.2.2

芯链情报局2023-04-26
528
0

0 概述

在自动驾驶感知算法中BEV感知成为热点话题,BEV感知可以弥补2D感知的缺陷构建3D“世界”,更有利于下游任务和特征融合。为响应市场需求,地平线集成了基于bev的纯视觉算法,目前已支持ipm-based 、lss-based、 transformer-based(Geometry-guided Kernel Transformer、detr3d、PETR) 的多种bev视觉转换方法。其中PETR为基于detr的3D检测算法,实现是端到端的,本文为PETR感知算法的介绍和使用说明。

该示例为参考算法,仅作为在J5上模型部署的设计参考,非量产算法

1 性能精度指标

PETR模型配置及指标::

dataset backbone input_shape num_query NDS(浮点/定点) FPS(双核) Nuscenes Eficientnet-B3 6x3x512x1408 900 37.66/37.19 8.3 注:建议使用小分辨率对模型性能会更友好:例如输入为[4,3,480,640]时,性能表现为双核62FPS,以实际需求为主

Nuscenes 数据集官方介绍:nuScenes

2 模型介绍

PETR模型主要包括以下部分:


Part1—2D feature extra:对输入的6V图像经过2D CNN提取多视图2D图像特征。

Part2—3D Position Encoder:生成3D坐标,对3D坐标融合位置编码形成3D Position Embedding。

Part3—transfomer Decoder:transformer解码器,将query做自注意力后再与图像特征做交互注意力,最后通过FFN层得到目标的类别分数和位置。

2.1 改动点说明

  • 替换了backbone,由resnet50的backbone替换回了同级别的efficientnet b3

  • Decoder部分,query由原来的3维(1,900,256)/ NQC 改成了(1,256, 4, 128)/NCHW,逻辑实现上与公版一致

  • 使用1x1的卷积替换了公版的linear,减少transpose和reshape的操作

  • LayerNorm2d为地平线内部自实现算子,性能更高

2.2 源码说明

2.2.1 Config文件

configs/bev/petr_efficientnetb3_nuscenes.py 为该模型的配置文件,定义了模型结构、数据集加载,和整套训练流程,所需参数的说明在算子定义中会给出。配置文件主要内容包括:

注: 如果需要复现精度,config中的训练策略最好不要修改。否则可能会有意外的训练情况出现。

2.2.2 img_encoder

来自6个view的image作为输入通过共享的backbone(efficientnet-b3)输出经过encoder后的feature,feature_shape为(6*B,C,1/2H,1/2W)。encoder即对多个view的img_feature 做特征提取,过程见下图:

对应代码:hat/models/backbones/efficientnet.py

2.2.3 head

由上图可知,PETR的head层完成特征提取和生成预测目标的全流程,通过生成的3D coords融合位置编码生成成pos_embed ;根据num_query生成可学习的query_embed;再将2D feature 做1x1的conv映射,将以上做为transformer解码器的输入。经由transfomer层做注意力计算生成target,通过cls、reg分支得到预测类别和位置。

对应代码:hat/models/task_modules/petr/head.py

2D-Features 映射

将2D feature使用1x1的卷积映射:

3D Coords 生成

实现为position_embeding,通过feat的shape和homo生成3D coords:

生成位置编码

位置编码记录图像的位置信息,编码方式为正弦编码,实现为 SinePositionalEncoding3D

3D PE 生成

对3D coords 编码,实现为conv+relu+conv,输出的C为embed_dims

融合位置编码

为了得到位置信息,将位置信息添加到PE中,融合方式为add

生成query 编码

生成可学习的reference_points(queries) ,转换为3D的query,然后将其编码(conv+relu+conv),最终形成query_embed 。

transformer层

完成2D features到3D features的 特征转换,该部分会在1.2.4章节详细说明。

预测层

预测分支分为reg_branch和cls_branch,PC端在head层完成根据reference_points和reg计算bbox过程。

1.2.4 PETR Transformer

由DecoderLayer构成:

Decoder层数为6层,上一层的输出为下一层的输入,每层主要完成两个注意力计算:在query之间做self-attention,再和图像特征之间做cross-attention。整理流程如下图:

Self attention

该层为query之间的4维自注意力层,q=k,避免不同的queries 预测同一个目标。

self_attns为多头注意力机制MultiheadAttention,具体实现的代码路径为hat/models/base_modules/attention.py:

CrossAttention

该层为交叉注意力层,为MultiheadAttention,将2D feature融合3D PE作为key,该层在特征中实现提取和聚集目标信息,参数如下:

3 浮点模型训练

3.1 Before Start

3.1.1 发布物及环境部署

step1:获取发布物

下载OE包horizon_j5_open_explorer_v$version$.tar.gz,获取方式见地平线开发者社区 OpenExplorer算法工具链 版本发布

step2:解压发布包

解压后文件结构如下:

其中horizon_model_train_sample为参考算法模块,包含以下模块:

step3:拉取docker环境

3.1.2 数据集准备

3.1.2.1 数据集下载

进入nuscenes官网,根据提示完成账户的注册,下载Full dataset(v1.0)、CAN bus expansion和Map expansion(v1.3)这三个项目下的文件。下载后的压缩文件为:

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 数据集打包

进入 horizon_model_train_sample/scripts 目录,使用以下命令将训练数据集和验证数据集打包,格式为lmdb:

--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张。

数据集打包命令执行完毕后会在target-data-dir下生成train_lmdb和val_lmdb,train_lmdb和val_lmdb就是打包之后的训练数据集和验证数据集为config中的data_rootdir。

2.1.2.3 meta文件夹构建

在tmp_data/nuscenes 下创建meta文件夹,将v1.0-trainval_meta.tar压缩包解压至meta,得到meta/maps文件夹,再将nuScenes-map-expansion-v1.3.zip压缩包解压至meta/maps文件夹下,解压后的目录结构为:

3.1.3 config配置

在进行模型训练和验证之前,需要对configs文件中的部分参数进行配置,一般情况下,我们需要配置以下参数:

  • device_ids、batch_size_per_gpu:根据实际硬件配置进行device_ids和每个gpu的batchsize的配置;

  • ckpt_dir:浮点、calib、量化训练的权重路径配置,权重下载链接在config文件夹下的README中;

  • data_rootdir:2.1.2.2中打包的数据集路径配置;

  • meta_rootdir :2.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 浮点模型精度验证

浮点模型训练完成以后,通过指定训好的float_checkpoint_path,使用以下命令验证已经训练好的模型精度:

验证完成后,会在终端打印浮点模型在验证集上检测和分割精度,如下所示:

4 模型量化和编译

完成浮点训练后,还需要进行量化训练和编译,才能将定点模型部署到板端。地平线对该模型的量化采用horizon_plugin框架,经过Calibration+定点模型转换后,使用compile的工具将量化模型编译成可以上板运行的hbm文件。

4.1 Calibration

模型完成浮点训练后,便可进行 Calibration。calibration在forward过程中通过统计各处的数据分布情况,从而计算出合理的量化参数。 通过运行下面的脚本就可以开启模型的Calibration过程:

4.2 Calibration 模型精度验证

calibration完成以后,可以使用以下命令验证经过calib后模型的精度:

验证完成后,会在终端输出calib模型在验证集上检测和分割精度,格式见3.3。

4.3 量化模型训练

Calibration完成后,就可以加载calib权重开启模型的量化训练。 量化训练其实是在浮点训练基础上的finetue,具体配置信息在config的qat_trainer中定义。量化训练的时候,初始学习率设置为浮点训练的十分之一,训练的epoch次数也大大减少。和浮点训练的方式一样,将checkpoint_path指定为训好的calibration权重路径。

通过运行下面的脚本就可以开启模型的qat训练:

4.4 量化模型精度验证

量化模型的精度验证,只需要运行以下命令:

qat模型的精度验证对象为插入伪量化节点后的模型(float32);quantize模型的精度验证对象为定点模型(int8),验证的精度是最终的int8模型的真正精度,这两个精度应该是十分接近的。

4.5 仿真上板精度验证

除了上述模型验证之外,我们还提供和上板完全一致的精度验证方法,可以通过下面的方式完成:

4.6 量化模型编译

在训练完成之后,可以使用compile的工具用来将量化模型编译成可以上板运行的hbm文件,同时该工具也能预估在BPU上的运行性能,可以采用以下脚本:
opt为优化等级,取值范围为0~3,数字越大优化等级越高,运行时间越长。
compile_perf脚本将生成.html文件和.hbm文件(compile文件目录下),.html文件为BPU上的运行性能,.hbm文件为上板实测文件。

5 其他工具

5.1 结果可视化

如果你希望可以看到训练出来的模型对于单帧的检测效果,我们的tools文件夹下面同样提供了预测及可视化的脚本,你只需要运行以下脚本即可:

注:需在config文件中配置infer_cfg字段。

可视化示例:

6 板端部署

6.1 上板性能实测

使用hrt_model_exec perf工具将生成的.hbm文件上板做BPU性能FPS实测,hrt_model_exec perf参数如下:
算法工具链
征程5官方教程
评论0
0/1000