5.3. BPU 算法推理
5.3.1. 概述
本文档主要介绍了地平线Python版本推理引擎API、数据结构、使用方法。 通过阅读本文档用户可以在开发板上,利用API通过简单的函数调用,来完成模型加载、数据及Tensor的准备、模型推理、获取模型输出等操作。
5.3.2. 数据相关类及结构
class hobot_dnn.pyeasy_dnn.TensorProperties
Parameters:
1、tensor_type (string):表示tensor的数据类型,例如:NV12、BGR、float32等
2、dtype (string):表示数据的存储类型,同numpy数据类型,例如:int8、uint8、float32等
3、layout (string):表示数据排布格式,NHWC或者NCHW
4、shape (tuple):表示存储数据的shape信息,例如:(1,3,224,224)
class hobot_dnn.pyeasy_dnn.pyDNNTensor
Parameters:
1、properties (TensorProperties):表示模型tensor的属性,详细参见 `class hobot_dnn.pyeasy_dnn.TensorProperties`
2、buffer (numpy):表示模型tensor中的数据,数据访问方式同numpy
3、name (string):表示模型tensor的名称
class hobot_dnn.pyeasy_dnn.Model
Parameters:
1、name (string):表示模型名称
2、inputs (tuple(pyDNNTensor)):表示模型的输入tensor信息
3、outputs (tuple(pyDNNTensor)):表示模型的输出tensor信息
4、forward (args &args, kwargs &kwargs):模型推理函数接口,输入模型推理所必要的参数,返回模型推理结果
parameters:
args: 提供三种形式的tensor输入,详细使用参考文末示例,或者SDK的示例脚本
非resizer模型:
a. numpy:单输入模型场景,直接提供numpy数据进行推理
b. list[numpy, numpy, ...]:多输入模型场景,将numpy数据打包成list,list长度应当为模型的输入个数
resizer模型:
a. list[list[numpy, list], list[numpy, list], ...]:将numpy数据与roi框的信息打包成一个list,作为一个tensor输入,多个tensor打包成一个list,作为模型整体输入
kwargs:core_id (int):表示模型推理的core id,可为0,1,2,默认为0表示任意核推理。
kwargs:priority (int):表示当前模型推理任务的优先级,范围[0~255],越大优先级越高。
returns: 接口返回模型输出结果
非resizer模型:
a. 输出为一维tuple: tuple(pyDNNTensor),tuple长度为模型输出个数;
resizer模型:
a. 输出为二维tuple: tuple(tupe(pyDNNTensor)),len(output)长度为roi的数量,len(output[0])长度为模型单个roi输出数量。
NV12数据说明
根据 NV12
数据类型本身的特点,在准备 numpy
数据时,应当保证 shape=(h * 3 / 2, w)
,确保数据的合法的性。
对于 NV12
输入类型的模型,获取得到的输入 shape
信息为 shape=(n,c,h,w)
或 shape=(n,h,w,c)
,其 shape
保留了原始图像的 h
和 w
信息,c
通道数值无意义,不作为参考。
5.3.3. API接口
python推理接口提供load函数,用于加载模型,并且返回一个tuple
hobot_dnn.pyeasy_dnn.load(model_file)
接口支持两种模型加载方式:
1、输入模型的文件路径,加载单个模型,或者单个pack模型
model_file = "/userdata/single_model.bin"
models = hobot_dnn.pyeasy_dnn.load(model_file)
2、输入模型的文件列表,加载多个模型
model_file = ["model1.bin", "model2.bin"]
models = hobot_dnn.pyeasy_dnn.load(model_file)
接口返回hobot_dnn.pyeasy_dnn.Model类型的tuple列表
5.3.4. 示例
from hobot_dnn import pyeasy_dnn as dnn
import numpy import np
# 加载一个单输入NV12模型
models = dnn.load('./fcos_512x512_nv12.bin')
# 获取模型输入信息
input_dtype = models[0].inputs[0].properties.dtype
# 构造模型NV12输入数据
tensor = np.zeros((768, 512), dtype=input_dtype)
outputs = models[0].forward(tensor)
# 获取模型输出数据,类型为numpy数据
output_buffer = outputs[0].buffer
# 加载一个多输入bgr模型
models = dnn.load('./mobilenet_416x4126_bgr.bin')
shape1 = models[0].inputs[0].properties.shape
dtype1 = models[0].inputs[0].properties.dtype
shape2 = models[0].inputs[1].properties.shape
dtype2 = models[0].inputs[1].properties.dtype
# 构造模型数据
tensor1 = np.ones(shape1, dtype=type1)
tensor2 = np.zeros(shape2, dtype=dtype2)
input_data=[tensor1, tensor2]
outputs = models[0].forward(input_data)
# 获取模型输出数据,类型为numpy数据
output_buffer = outputs[0].buffer
# 加载resizer模型
models = dnn.load('resizer_512x512_nv12.bin')
# 构造模型NV12数据
data1 = np.zeros((768, 512), dtype='uint8')
roi1 = [18, 20, 99, 99]
tensor1 = [data1, roi1]
data2 = np.zeros((624, 416), dtype='uint8')
roi2 = [20, 22, 97, 97]
tensor2 = [data2, roi2]
input_data = [tensor1, tensor2]
outputs = models[0].forward(input_data)
# 模型输入roi框数量为2
assert len(outputs) == 2
# 模型单个roi框对应的输出tensor为1个
assert len(outputs[0]) == 1
# 获取模型输出数据,类型为numpy数据
output_buffer1 = outputs[0][0].buffer
output_buffer2 = outputs[1][0].buffer