目前在地平线浮点转换工具链中,提供了十几个模型示例。而其中 mapper 路径下的脚本和代码都是用于推理转换后的量化模型(*_quantized_model.onnx,下文简称 quanti.onnx)的。但有时候我们也有浮点模型(*_original_float_model.onnx,下文简称 float.onnx)推理的需求,可能用于分析 quanti.onnx 单张图片推理的准确性或者在完整数据集上的精度损失等。
float.onnx 保持了与 prototxt 相同的 layout,一般为 NCHW,同时数据类型为 float32;
quanti.onnx 则为了适配芯片的运行逻辑,layout 为 NHWC,数据类型为 int8。
这两个参数决定了我们会为模型插入什么样的预处理节点,其中:
input_type_train 是模型实际训练时的数据格式,一般为 bgrp、rgbp、gray 等;
input_type_rt 是我们实际应用场景中传输给模型的数据类型,一般摄像头场景以 nv12 和 gray 为主;
根据参数配置,预处理节点会将 input_type_rt 类型的输入数据转换成 input_type_train,数值范围为 [0, 255],再根据 yaml 中配置的 mean 和 scale 进行归一化操作,最后将处理完的数据送给后续模型。
该脚本主要用于对原始数据(一般为 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]

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

- input_type_rt: 'bgrp', input_type_train: 'bgrp':
预处理节点 HzPreProcess 参数如下图所示:

03_classification/cls_inference.py 改动如下所示:
- #50 注释掉 BGR->YUV444 的颜色空间转换
- #53 改动 dtype 为 np.float32,并减 128 以适配 BPU 输入要求
- #65 改动与上述一致

2) 05_miscellaneous/01_lenet_gray:
- input_type_rt: 'gray', input_type_train: 'gray':
预处理节点 HzPreProcess 参数如下图所示:

01_lenet_gray/mapper/inference.py 改动如下:
- #21 将 gray 更改为 float
- #32 将 transpose 去除,将 dtype 配置为 np.float32,并减 128

3) 05_miscellaneous/02_resnet50_feature:
- input_type_rt: 'featuremap', input_type_train: 'featuremap':
如下图所示,feature 输入的模型没有预处理节点,模型以 float32 输入。所以代码上不用做任何修改,可以直接基于量化模型的代码和脚本运行。


