专栏算法工具链如何基于工具链示例代码实现浮点模型推理

如何基于工具链示例代码实现浮点模型推理

芯链情报局2020-10-30
449
0

目前在地平线浮点转换工具链中,提供了十几个模型示例。而其中 mapper 路径下的脚本和代码都是用于推理转换后的量化模型(*_quantized_model.onnx,下文简称 quanti.onnx)的。但有时候我们也有浮点模型(*_original_float_model.onnx,下文简称 float.onnx)推理的需求,可能用于分析 quanti.onnx 单张图片推理的准确性或者在完整数据集上的精度损失等。

以下将基于地平线最新发布的 1.1.17e 版本工具链,说明如何在现有示例代码上进行更改,以完成对浮点模型的正确推理。在实操之前,我们先来理解几个概念:
1. 理解 float.onnx 和 quanti.onnx 在输入 layout 和 data_type 上的差异。
  • float.onnx 保持了与 prototxt 相同的 layout,一般为 NCHW,同时数据类型为 float32;

  • quanti.onnx 则为了适配芯片的运行逻辑,layout 为 NHWC,数据类型为 int8。

2. 理解 yaml 中配置的 input_type_rt、input_type_train 参数。
  • 这两个参数决定了我们会为模型插入什么样的预处理节点,其中:

    • input_type_train 是模型实际训练时的数据格式,一般为 bgrp、rgbp、gray 等;

    • input_type_rt 是我们实际应用场景中传输给模型的数据类型,一般摄像头场景以 nv12 和 gray 为主;

    • 根据参数配置,预处理节点会将 input_type_rt 类型的输入数据转换成 input_type_train,数值范围为 [0, 255],再根据 yaml 中配置的 mean 和 scale 进行归一化操作,最后将处理完的数据送给后续模型。

3. 理解示例包中的 02_preprocess.sh 脚本的作用。
  • 该脚本主要用于对原始数据(一般为 jpg 等)进行预处理,但需要注意:

    • samples/03_classification 为了适配 mobilenet 原 repo,采用了 skimage.io.imread 读取图片,颜色空间为 RGB,数值范围为 [0,1],可通过 03_classification/data_preprocess.py 确认;

    • samples/04_detection 为了适配 yolo 系列 repo,则采用了 cv2.imread 读取图片,颜色空间为 BGR,数值范围为 [0, 255],可通过 04_detection/data_preprocess.py 确认;

    • 基于分类和检测示例所调用的不同的接口,我们在各模型示例包下的 data_transformer.py 中会添加不同的 transformer。以 resnet18 为例,这里除了短边 resize 和 centercrop 外,还进行了 C 通道转换和 scale,使得最后的数据输出为模型本身训练的 BGR,数值范围为 [0, 255]

理解了以上信息后,我们以交付包中的 ResNet18、LeNet_gray、ResNet50_feature 为例进行具体说明,分别对应不同的数据输入类型。

1)03_classification/03_resnet18:

  • input_type_rt: 'yuv444_128/nv12', input_type_train: 'bgrp':

nv12 编译的模型,由于芯片内部的通路逻辑,实际送到模型处的数据其实也是 YUV444_128,所以其测试方法同 YUV444_128 编译模型。

下图为编译后的 original_float 模型插入的预处理节点 HzPreProcess。其中 layout=NCHW,数据类型为 float32 的 YUV444_128。

所以在 03_classification/cls_inference.py 代码中的改动为以下几处:

  1. #51 将 YUV444 更改为 YUV444_128,即在上文所述的 data_transformer 之后再添加 BGR->YUV444_128 的转换,以适配上图中的 input_type
  2. #54 去掉了 transpose,因为如上文所述,quanti.onnx 为了满足 BPU 要求是 NHWC 输入,而 original_float.onnx 为 NCHW 输入
  3. #54 将 dtype 配置为 np.float32,以适配上图中的 type
  4. #65 将 yuv444 更改为 float
  5. 完成以上改动后可基于 04_inference.sh 脚本直接推理 *_original_float.onnx,验证结果准确性。

  • input_type_rt: 'bgrp', input_type_train: 'bgrp':

预处理节点 HzPreProcess 参数如下图所示:

03_classification/cls_inference.py 改动如下所示:

  1. #50 注释掉 BGR->YUV444 的颜色空间转换
  2. #53 改动 dtype 为 np.float32,并减 128 以适配 BPU 输入要求
  3. #65 改动与上述一致

2) 05_miscellaneous/01_lenet_gray:

  • input_type_rt: 'gray', input_type_train: 'gray':

预处理节点 HzPreProcess 参数如下图所示:

01_lenet_gray/mapper/inference.py 改动如下:

  1. #21 将 gray 更改为 float
  2. #32 将 transpose 去除,将 dtype 配置为 np.float32,并减 128

3) 05_miscellaneous/02_resnet50_feature:

  • input_type_rt: 'featuremap', input_type_train: 'featuremap':

如下图所示,feature 输入的模型没有预处理节点,模型以 float32 输入。所以代码上不用做任何修改,可以直接基于量化模型的代码和脚本运行。

算法工具链
杂谈
评论0
0/1000