地平线 bev 参考算法板端一致性验证教程

01 前言

由于部署时数据来源的硬件不同以及应用开发的高效性要求,往往会使得在板端部署阶段的数据准备操作与训练时有所差异,导致在同样的输入下,量化模型的输出结果和板端部署模型的输出结果不一致。

本文将基于开发者社区中已经发布的地平线 bev 参考算法板端输入数据准备教程,以 bev_mt_lss 参考算法为例,介绍 PC 端和板端输出一致性验证的过程。

02 PC 端输入获取

PC 端输入的获取主要包括输入数据准备、输出节点配置和运行推理脚本这三个步骤,下面将对其进行逐一介绍。

2.1 输入数据准备

bev_mt_lss 参考算法的 PC 端输入为:

获取到 6V 图像和 homography 矩阵后,配置 config 文件的 infer_cfg 字段中输入路径参数 infer_inputs:

ini 复制代码
infer_cfg = dict(
    model=model,
    infer_inputs=dict(
        #6V图像的存放路径
        imagedir="./tmp_orig_data/nuscenes/infer_imgs/single_frame/imgs",
        #homography矩阵的存放路径
        homo="./tmp_orig_data/nuscenes/infer_imgs/single_frame/homo/ego2img.npy",
    ),
    ...
)

bev 参考算法的输入的 6V 图像的有顺序的,所以需要在 config 文件的 process_inputs 函数中定义输入图像的顺序,如下所示:

ini 复制代码
def process_inputs(infer_inputs, transforms=None):

    resize_size = resize_shape[1:]
    input_size = val_data_shape[1:]
    orig_imgs = []
    #定义输入图像的顺序
    input_list=[
    'n008-2018-08-01-15-16-36-0400__CAM_FRONT_LEFT__1533151603504799.jpg',
    'n008-2018-08-01-15-16-36-0400__CAM_FRONT__1533151603512404.jpg',
    'n008-2018-08-01-15-16-36-0400__CAM_FRONT_RIGHT__1533151603520482.jpg',
    'n008-2018-08-01-15-16-36-0400__CAM_BACK_LEFT__1533151603547405.jpg',
    'n008-2018-08-01-15-16-36-0400__CAM_BACK__1533151603537558.jpg',
    'n008-2018-08-01-15-16-36-0400__CAM_BACK_RIGHT__1533151603528113.jpg'
    ]
    #for i, img in enumerate(os.listdir(infer_inputs["imagedir"])):
    for i,img in enumerate(input_list):
        img = os.path.join(infer_inputs["imagedir"], img)
        img, orig_shape = process_img(img, resize_size, input_size)
        orig_imgs.append({"name": i, "img": img})
        
        ...
    return model_input, vis_inputs

6V 图像的输入顺序为:FRONT_LEFT,FRONT,FRONT_RIGHT,BACK_LEFT,BACK,BACK_RIGHT

2.2 输出节点配置

2.2.1 dump 分割头输出

在 docker 环境下,进入到/usr/local/lib/python3.8/dist-packages/hat/models/task_modules/fcn/head.py 目录下,在 FCNHead 类的 forward 函数中保存分割头的输出,如下所示:

python 复制代码
#step1:导入fx_wrap和numpy
from hat.utils.model_helpers import fx_wrap
import numpy as np 
 
    #step2:定义保存输出的函数saveoutput并使用fx_warp
    @fx_wrap()
    def saveoutput(self,seg_pred):
        seg_pred=seg_pred.as_subclass(torch.Tensor)
        seg_pred=seg_pred.view(-1,1).cpu().numpy()
        print("------start to save seghead output------")
        np.savetxt("./lss/seg_pred.txt",seg_pred,fmt='%d', delimiter=',')
        print("-----save seghead output ok------")
        return seg_pred
    def forward(self, inputs: List[torch.Tensor]):
        x = inputs[self.input_index]
        x = self.convs(x)
        if self.dropout:
            x = self.dropout(x)
        seg_pred = self.cls_seg(x)
        #step3:调用saveoutput函数
        seg_pred=self.saveoutput(seg_pred)
        if self.training:
            if self.upsample_output_scale:
                seg_pred = self.resize(seg_pred)
            if self.argmax_output:
                seg_pred = seg_pred.argmax(dim=1)
        
        if self.dequant_output:
            seg_pred = self.dequant(seg_pred)
        return seg_pred

2.2.2 dump 检测头输出

本节以 bev 参考算法检测头的"height"属性输出为例,介绍如何导出 PC 端的检测头输出,将其保存为 txt 文件。

在 docker 环境下,进入到/usr/local/lib/python3.8/dist-packages/hat/models/task_modules/centerpoint/head.py 目录下,在 TaskHead 类的 forward 函数中 dump 检测头的输出,如下所示:

python 复制代码
#step1:导入fx_wrap和numpy
from hat.utils.model_helpers import fx_wrap
import numpy as np
    #step2:定义保存指定检测头的输出函数 
    @fx_wrap()
    def saveoutput(self,x):
        x=self.__getattr__("height")(x).as_subclass(torch.Tensor)
        x=x.view(-1,1).cpu().numpy()
        print("------start to save dethead output------")
        np.savetxt("./lss/output_height.txt",x,fmt='%d', delimiter=',')
        print("-----save dethead output ok------")
        return x  
    def forward(self, x):
        ret_dict = {}
        #step3:调用输出保存函数
        x = self.saveoutput(x)
        for head in self.heads:
            ret_dict[head] = self.dequant(self.__getattr__(head)(x))
        return ret_dict

本节仅选择了检测头的一个类别的 height 输出一致性的验证,也可以选择在/usr/local/lib/python3.8/dist-packages/hat/models/task_modules/centerpoint/head.py 中保存检测头的其它属性输出来验证一致性。

2.3 运行 infer.py

最后,运行推理脚本 infer.py

bash 复制代码
#启动docker
#进入到OE包的ddk/samples/ai_toolchain/horizon_model_train_sample/scripts目录下
python3 tools/infer.py -c  ./configs/bev/bev_mt_lss_efficientnetb0_nuscenes.py

运行 infer.py 之前请参考【参考算法】地平线 Bev_mt_lss 参考算法-v1.2.1 3.1.3 节对 config 文件进行必要的修改

运行 infer.py 完毕后,生成的 seg_pred.txt 即为模型的分割头输出,output_height.txt 为检测头的 "height" 输出。

03 板端输入获取

板端端输入的获取主要包括输入数据准备和运行 hrt_model_exec 工具这两个步骤,下面将对其进行逐一介绍。

3.1 输入数据准备

3.2 运行 hrt_model_exec 工具

获取到 bev_mt_lss 板端 hbm 的 3 个输入后,在板端运行 hrt_model_exec 工具来 dump 模型的输出,命令如下:

css 复制代码
hrt_model_exec infer --model_file=model.hbm --input_file=inputnv12_lss.bin,fpoints.bin,dpoints.bin --enable_dump True --dump_format txt

工具运行完成后,会在当前路径下生成数个 txt 文件,分割头对应的输出是 model_infer_output_0.txt,检测头的"height"属性对应的输出是 model_infer_output_32.txt 文件。

可通过 hrt_model_exec model_info --model_file model.hbm 来获取模型输出节点的信息。

04 输出结果对比

将 2.3 节导出的 PC 端分割头的输出 seg_pred.txt 和检测头输出 output_height.txt 分别与 3.2 节 dump 出的 model_infer_output_0.txt 和 model_infer_output_32.txt 对比,如果数值相同,则说明一致性验证通过。

相关推荐
宸码38 分钟前
【机器学习】手写数字识别的最优解:CNN+Softmax、Sigmoid与SVM的对比实战
人工智能·python·神经网络·算法·机器学习·支持向量机·cnn
太空漫步111 小时前
逆序对个数
java·算法·排序算法
23级二本计科1 小时前
分治_归并_归并排序(逆序对)
数据结构·算法·排序算法
CHENWENFEIc1 小时前
基础排序算法详解:冒泡排序、选择排序与插入排序
c语言·数据结构·算法·排序算法·学习方法·冒泡排序
养佳工具人1 小时前
Java各种排序
java·算法·排序算法
都适、隶仁ミ1 小时前
【密码学】SM4算法
linux·运维·服务器·算法·网络安全·密码学·网络攻击模型
睡觉狂魔er1 小时前
自动驾驶控制与规划——Project 1: 车辆纵向控制
人工智能·机器学习·自动驾驶
goomind1 小时前
YOLOv8实战bdd100k自动驾驶目标识别
人工智能·深度学习·yolo·计算机视觉·目标跟踪·自动驾驶·bdd100k
GIS 数据栈1 小时前
自动驾驶领域常用的软件与工具
人工智能·机器学习·自动驾驶
博雅智信1 小时前
人工智能-自动驾驶领域
人工智能·python·深度学习·yolo·机器学习·计算机视觉·自动驾驶