点击头像,立即联系微信客服
       福州牛新牛科技有限公司是一家专业的嵌入式人工智能物联网(Embedded AIoT)产品供应商和技术方案商,同时也是一家集设计、研发、生产和销售于一体的国家级高新技术企业。公司批量供应AI核心板、工控板、AIoT智能网关、AI边缘计算终端等产品,并提供定制开发服务和一站式AIoT解决方案。NNEWN提供免费技术方案咨询和项目评估,有需要的读者可以点击右侧图标跳转到需求提交页面提交您的项目需求:
【AI开发_05】模型转换API说明
来源: | 作者:nnewn | 发布时间: 2021-08-28 | 2323 次浏览 | 分享到:

1.模型加载

1.1 caffe模型加载

APIload_caffe
描述加载caffe模型
参数model:caffe模型文件(.prototxt后缀文件)所在路径。
proto:caffe模型的格式(可选值为’caffe’或’lstm_caffe’)。为了支持RNN模型,增加了相关网络层的支持,此时需要设置caffe格式为’lstm_caffe’。
blobs:caffe模型的二进制数据文件(.caffemodel后缀文件)所在路径。
返回值0:加载成功
-1:加载失败

  如,从当前路径加载 mobilenet_v2 模型

  1. ret=rknn.load_caffe(model=’./mobilenet_v2.prototxt’,
                        proto=’caffe
                        blobs=’./mobilenet_v2.caffemodel’)


1.2 Tensorflow模型加载

APIload_tensorflow
描述加载tensorflow模型
参数tf_pb:TensorFlow模型文件(.pb后缀)所在路径。
inputs:模型输入节点,支持多个输入节点。所有输入节点名放在一个列表中。
input_size_list:每个输入节点对应的图片的尺寸和通道数。如示例中的mobilenet-v1模型,其输入节点对应的输入尺寸是[224, 224, 3]。
outputs:模型的输出节点,支持多个输出节点。所有输出节点名放在一个列表中。
predef_file:为了支持一些控制逻辑,需要提供一个npz格式的预定义文件。可以通过以下方法生成预定义文件:np.savez(‘prd.npz’, [placeholder name]=prd_value)。如果“placeholder name”中包含’/‘,请用’#’替换。
mean_values:输入的均值。只有当导入的模型是已量化过的模型时才需要设置该参数,且模型输入的三个通道均值都相同。
std_values:输入的scale值。只有当导入的模型是已量化过的模型时才需要设置该参数。
返回值0:加载成功
-1:加载失败

  如,从当前路径加载 ssd_mobilenet_v1 模型

  1. ret = rknn.load_tensorflow(tf_pb=’./ssd_mobilenet_v1_coco_2017_11_17.pb’,
                               inputs=[‘FeatureExtractor/MobilenetV1/MobilenetV1/Conv2d_0/BatchNorm/batchnorm/mul_1’],
                               outputs=[‘concat’, concat_1’],
                               input_size_list=[[300, 300, 3]])


1.3 Tensorflow Lite模型加载

APIload_tflite
描述加载tensorflow lite模型
参数model: Tensorflow lite 模型文件(.tflite后缀)所在路径
返回值0: 加载成功
-1:加载失败

  如,从当前路径加载 mobilenet_v1 模型

ret = rknn.load_tflite(model = ‘./mobilenet_v1.tflite’)


1.4 ONNX模型加载

APIload_onnx
描述加载onnx模型
参数model: onnx模型文件(.onnx后缀)所在路径
返回值0: 载入成功
-1:载入失败

  如,从当前路径加载 arcface 模型

ret = rknn.load_onnx(model = ‘./arcface.onnx’)


1.5 Darknet模型加载

APIload_darknet
描述加载Darknet模型
参数model: Darknet模型文件(.cfg后缀)所在路径
weight: 权重文件 (.weights后缀)所在路径
返回值0 :加载成功
-1:加载失败

  如,从当前路径加载 yolov3-tiny模型

ret = rknn.load_darknet(model = ‘./yolov3-tiny.cfg’, weight=’./yolov3.weights’)

1.6 Pytorch模型加载

APIload_pytorch
描述加载Pytorch模型
参数model: Pytorch模型文件(.pt后缀)所在路径,而且需要是torchscript格式的模型,必填参数。
input_size_list: 每个输入节点对应的图片的图片的尺寸和通道数。例如[[1,224,224],[3,224,224]]表示有两个输入,其中一个输入的shape是[1,224,224],另外一个输入的shape是[3,224,224],必填参数。
返回值0 :导入成功
-1:导入失败

  如,从当前路径加载 resnet18 模型

ret = rknn.load_pytorch(model = ‘./resnet18.pt’, input_size_list=[[3,224,224]])

2.RKNN模型配置

APIconfig
描述设置模型参数
参数batch_size:每一批数据的大小,默认值为100。
channel_mean_value:包括四个值(M0 M1 M2 S0),前三个值为均值参数,后面一个值为Scale 参数。对于输入数据是三通道的(Cin0, Cin1, Cin2)数据来讲,经过预处理后,输出的数据为(Cout0,Cout1, Cout2),计算过程如下:
Cout0 = (Cin0 - M0)/S0
Cout1 = (Cin1 - M1)/S0
Cout2 = (Cin2 - M2)/S0
例如,如果需要将输入数据归一化到[-1, 1]之间,则可以设置这个参数为(128 128 128 128);如果需要将输入数据归一化到[0, 1]之间,则可以设置这个参数为(0 0 0 255)。
如果有多个输入,对应的每个输入的参数以“#”进行分割,如’128 128 128 128#128 128 128 128’。
epochs:量化时的迭代次数,每迭代一次,就选择batch_size指定数量的图片进行量化校正。默认值为1
reorder_channel:表示是否需要对图像通道顺序进行调整。
‘0 1 2’表示按照输入的通道顺序来推理,比如图片输入时是RGB,那推理的时候就根据RGB顺序传给输入层;
‘2 1 0’表示会对输入做通道转换,比如输入时通道顺序是RGB,推理时会将其转成BGR,再传给输入层,同样的,输入时通道的顺序为BGR的话,会被转成RGB后再传给输入层。如果有多个输入,对应的每个输入的参数以“#”进行分割,如’0 1 2#0 1 2’。
need_horizontal_merge:是否需要合并Horizontal,默认值为False。如果模型是inception v1/v3/v4,建议开启该选项。
quantized_dtype:量化类型,目前支持的量化类型有asymmetric_quantized-u8、dynamic_fixed_point-8、dynamic_fixed_point-16,默认值为asymmetric_quantized-u8
返回值

  如,下面的例子

  1. rknn.config(channel_mean_value=’103.94 116.78 123.68 58.82’,
                reorder_channel=’0 1 2’,
                need_horizontal_merge=True)

3.构建RKNN模型

APIBuild
描述根据导入的模型,构建对应的RKNN模型
参数do_quantization:是否对模型进行量化,值为True或False。
dataset:量化校正数据的数据集。目前支持文本文件格式,用户可以把用于校正的图片(jpg或png格式)或npy文件路径放到一个.txt文件中。文本文件里每一行一条路径信息。如:
  a.jpg
  b.jpg

  a.npy
  b.npy
如有多个输入,则每个输入对应的文件用空格隔开,如:
  a.jpg a2.jpg
  b.jpg b2.jpg

  a.npy a2.npy
  b.npy b2.npy
Pre_compile: 预编译开关,如果设置成True,可以减小模型大小,以及模型在硬件设备上的首次启动速度。但在打开这个开关后,构建出来的模型就只能在硬件平台上运行,无法通过模拟器进行推理或性能评估。如果硬件有更新,则对应的模型要重新构建。
注:
1. RKNN-Toolkit-V1.0.0及以上版本生成的预编译模型不能在NPU驱动版本小于0.9.6的设备上运行;RKNN-Toolkit-V1.0.0以前版本生成的预编译模型不能在NPU驱动版本大于等于0.9.6的设备上运行。驱动版本号可以通过get_sdk_version接口查询。
2. 如果多个输入,该选项需要设置成False。
rknn_batch_size:模型的输入Batch参数调整,默认值为1。如果大于1,则可以在一次推理中同时推理多帧输入图像或输入数据,如MobileNet模型的原始input维度为[1, 224, 224, 3],output维度为[1, 1001],当rknn_batch_size设为4时,input的维度变为[4, 224, 224, 3],output维度变为[4, 1001]。
注:
1. rknn_batch_size的调整并不会提高一般模型在NPU上的执行性能,但却会显著增加内存消耗以及增加单帧的延迟。
2. rknn_batch_size的调整可以降低超小模型在CPU上的消耗,提高超小模型的平均帧率。(适用于模型太小,CPU的开销大于NPU的开销)。
3. rknn_batch_size的值建议小于32,避免内存占用太大而导致推理失败。
4. rknn_batch_size修改后,模型的input/output维度会被修改,使用inference推理模型时需要设置相应的input的大小,后处理时,也需要对返回的outputs进行处理。
返回值0 :构建成功
-1:构建失败

  如,构建RKNN模型,并且做量化

ret = rknn.build(do_quantization=True, dataset=’./dataset.txt’)

4.导出RKNN模型

APIexport_rknn
描述将RKNN模型保存到指定文件中(.rknn 后缀)
参数export_path: 导出模型文件的路径
返回值0: 导出成功
-1:导出失败

  如,将构建好的RKNN模型保存到当前路径的mobilne_v1.rknn文件中

ret = rknn.export_rknn(export_path = ‘./mobilenet_v1.rknn’)

5.加载RKNN模型

APIload_rknn
描述加载rknn模型
参数path: RKNN模型文件路径
返回值0: 加载成功
-1: 加载失败

  如,从当前路径加载mobilenet_v1.rknn模型

ret = rknn.load_rknn(path=’./mobilenet_v1.rknn’)

6.初始化运行时环境

APIInit_runtime
描述初始化运行时环境。确定模型运行的设备信息(硬件平台信息、设备ID);性能评估时是否启用debug模式,以获取更详细的性能信息。
参数target:目标硬件平台,目前支持“rk1808”。默认为None,即在PC使用工具时,模型在模拟器上运行。
device_id:设备编号,如果PC连接多台设备时,需要指定该参数,设备编号可以通过”list_devices”接口查看。默认值为None。
perf_debug:进行性能评估时是否开启debug模式。在debug模式下,可以获取到每一层的运行时间,否则只能获取模型运行的总时间。默认值为False。
eval_mem: 是否进入内存评估模式。进入内存评估模式后,可以调用eval_memory接口获取模型运行时的内存使用情况。默认值为False。
async_mode:是否使用异步模式。调用推理接口时,涉及设置输入图片、模型推理、获取推理结果三个阶段。如果开启了异步模式,设置当前帧的输入将与推理上一帧同时进行,所以除第一帧外,之后的每一帧都可以隐藏设置输入的时间,从而提升性能。在异步模式下,每次返回的推理结果都是上一帧的。该参数的默认值为False。
返回值0:初始化运行环境成功
-1:初始化运行时环境失败

  初始化运行时环境

  1. ret = rknn.init_runtime(target=’rk1808’, device_id=’012345789AB’)
    if ret!=0:
        print(‘Init runtime environment failed’)
        exit(ret)

7.模型推理

APIInference
描述使用模型对指定的输入进行推理,得到推理结果。
如果RKNN-Toolkit运行在PC上,且初始化运行环境时设置target为 “rk1808”,得到的是模型在硬件平台上的推理结果。
如果RKNN-Toolkit运行在PC上,且初始化运行环境时没有设置target,得到的是模型在模拟器上的推理结果。
参数inputs:待推理的输入,如经过cv2处理的图片。格式是ndarray list。
data_type:输入数据的类型,可填以下值:’float32’, ‘float16’, ‘int8’, ‘uint8’, ‘int16’。默认值为’uint8’。
data_format:数据模式,可以填以下值: “nchw”, “nhwc”。默认值为’nhwc’。这两个的不同之处在于channel数放置的位置。
outputs:指定输出数据的格式,格式是ndarray list,用于指定输出的shape和dtype。默认值为None,此时返回的数据dtype为float32。
inputs_pass_through: 将输入透传给NPU驱动。非透传模式下,在将输入传给NPU驱动之前,工具会对输入进行减均值、除方差等操作;而透传模式下,不会做这些操作。这个参数的值是一个数组,比如要透传input0,不透彻input1,则这个参数的值为[1, 0]。目前我们只支持单输入,所以值为[0]表示不透传,值为[1]表示透传。默认值为None,即对所有输入都不透传。
返回值results:推理结果,类型是ndarray list。

  如,执行mobilenet_v1模型:

  1. outputs = rknn.inference(inputs=[img])
    show_outputs(outputs)


  输出的结果TOP5 结果如下

  1. ——TOP 5——
    [156]: 0.8837890625
    [155]: 0.0677490234375
    [188]: 0.00867462158203125
    [205]: 0.00867462158203125
    [263]: 0.0057525634765625

8.评估模型性能

APIeval_perf
描述评估模型性能。
模型运行在PC上,初始化运行环境时不指定target,得到的是模型在模拟器上运行的性能数据,包含逐层的运行时间及模型完整运行一次需要的时间。
模型运行在与PC连接的RK1808上,且初始化运行环境时设置perf_debug为False,则获得的是模型在硬件上运行的总时间;如果设置perf_debug为True,除了返回总时间外,还将返回每一层的耗时情况。
参数inputs:输入数据,如经过cv2处理得图片。格式是ndarray list。
data_type:输入数据的类型,可填以下值:’float32’, ‘float16’, ‘int8’, ‘uint8’, ‘int16’。默认值为’uint8’
data_format:数据模式,可以填以下值: “nchw”, “nhwc”。默认值为’nhwc’。
is_print:是否以规范格式打印性能评估结果。默认值为True。
返回值perf_result:性能信息。类型为字典。在硬件平台上运行,且初始运行环境时设置perf_debug为False时,得到的字典只有一个字段’total_time’,示例如下:
{
  ‘total_time’: 1000
}
其他场景下,得到的性能信息字典多一个’layers’字段,这个字段的值也是一个字典,这个字典以每一层的ID作为key,其值是一个包含’name’(层名)、’operation’(操作符,只有运行在硬件平台上时才有这个字段)、’time’(该层耗时)等信息的字典。举例如下:
{
  ‘total_time’, 4568,
  ‘layers’:
  {
    ‘0’:
    {
    ‘name’: ‘convolution.relu.pooling.layer2_2’,
    ‘operation’: ‘CONVOLUTION’,
    ‘time’, 362
    }
    ‘1’:
    {
    ‘name’: ‘convolution.relu.pooling.layer2_2’,
    ‘operation’: ‘CONVOLUTION’,
    ‘time’, 158
    }
  }
}

  对模型性能进行评估

rknn.eval_perf(inputs=[image], is_print=True)


  如mobilenet-ssd,其性能评估结果打印如下(以下是在PC模拟器上得到的结果,连接硬件设备时得到的详情与该结果略有不同):

  1. Performance
    Layer_ID                        Name                                Time(us)
    0                   tensor.transpose_3                               125
    71                  convolution.relu.pooling.layer2_3                325
    105                 convolution.relu.pooling.layer2_2                331
    72                  convolution.relu.pooling.layer2_2                437
    106                 convolution.relu.pooling.layer2_2                436
    73                  convolution.relu.pooling.layer2_2                223
    107                 convolution.relu.pooling.layer2_2                374
    74                  convolution.relu.pooling.layer2_2                327
    108                 convolution.relu.pooling.layer2_3                533
    75                  convolution.relu.pooling.layer2_2                201
    109                 convolution.relu.pooling.layer2_2                250
    76                  convolution.relu.pooling.layer2_2                320
    110                 convolution.relu.pooling.layer2_2                250
    77                  convolution.relu.pooling.layer2_2                165
    111                 convolution.relu.pooling.layer2_2                257
    78                  convolution.relu.pooling.layer2_2                319
    112                 convolution.relu.pooling.layer2_2                257
    79                  convolution.relu.pooling.layer2_2                319
    113                 convolution.relu.pooling.layer2_2                257
    80                  convolution.relu.pooling.layer2_2                319
    114                 convolution.relu.pooling.layer2_2                257
    81                  convolution.relu.pooling.layer2_2                319
    115                 convolution.relu.pooling.layer2_2                257
    82                  convolution.relu.pooling.layer2_2                319
    83                  convolution.relu.pooling.layer2_2                181
    27                  tensor.transpose_3                               48
    84                  convolution.relu.pooling.layer2_2                45
    28                  tensor.transpose_3                               6
    116                 convolution.relu.pooling.layer2_3                297
    85                  convolution.relu.pooling.layer2_2                233
    117                 convolution.relu.pooling.layer2_2                311
    86                  convolution.relu.pooling.layer2_2                479
    87                  convolution.relu.pooling.layer2_2                249
    35                  tensor.transpose_3                               29
    88                  convolution.relu.pooling.layer2_2                30
    36                  tensor.transpose_3                               5
    89                  convolution.relu.pooling.layer2_2                125
    90                  convolution.relu.pooling.layer2_3                588
    91                  convolution.relu.pooling.layer2_2                96
    41                  tensor.transpose_3                               10
    92                  convolution.relu.pooling.layer2_2                11
    42                  tensor.transpose_3                               5
    93                  convolution.relu.pooling.layer2_2                31
    94                  convolution.relu.pooling.layer2_3                154
    95                  convolution.relu.pooling.layer2_2                50
    47                  tensor.transpose_3                               6
    96                  convD_2                                          6
    48                  tensor.transpose_3                               4
    97                  convolution.relu.pooling.layer2_2                17
    98                  convolution.relu.pooling.layer2_3                153
    99                  convolution.relu.pooling.layer2_2                49
    53                  tensor.transpose_3                               5
    100                 convolution.relu.pooling.layer2_2                6
    54                  tensor.transpose_3                               4
    101                 convolution.relu.pooling.layer2_2                10
    102                 convolution.relu.pooling.layer2_2                21
    103                 fullyconnected.relu.layer_3                      13
    104                 fullyconnected.relu.layer_3                      8

    Total Time(us): 10462
    FPS(800MHz): 95.58

9.获取内存使用情况

APIEval_memory
描述获取模型在硬件平台运行时的内存使用情况。
模型必须运行在与PC连接的RK1808上。
注:使用该功能时,对应的驱动版本必须要大于等于0.9.4。驱动版本可以通过get_sdk_version接口查询。
参数is_print: 是否以规范格式打印内存使用情况。默认值为True。
返回值memory_detail:内存使用情况。类型为字典。
内存使用情况按照下面的格式封装在字典中:
{
  ‘system_memory’:
    {
    ‘maximum_allocation’: 128000000,
    ‘total_allocation’: 152000000
    }
  ‘npu_memory’:
    {
    ‘maximum_allocation’: 30000000,
    ‘total_allocation’: 40000000
    }
  ‘total_memory’:
    {
    ‘maximum_allocation’: 158000000,
    ‘total_allocation’: 192000000
    }
}
注:
1.’system_meomory’字段表示系统内存占用。
2.’npu_memory’表示NPU内部内存的使用情况。
3.’total_memory’是上述系统内存和NPU内部内存的和。
4.’maximun_allocation’是内存使用的峰值,单位是byte。表示模型从运行开始到结束内存的最大分配至,这是一个峰值。
5.’total_allcation’表示整个运行过程中分配的所有内存之和。

  对模型内存使用情况进行评估

memory_detail = rknn.eval_memory()


如mobilenet_v1,它在NNEWN AI硬件平台上运行时内存占用情况如下:

  1. System memory:
       maximum allocation : 41.53 MiB
       total allocation : 43.86 MiB
    NPU memory:
       maximum allocation : 34.53 MiB
       total allocation : 34.54 MiB
    Total memory:
       maximum allocation : 76.06 MiB
       total allocation : 78.40 MiB
    INFO: When evaluating memory usage, we need consider the size of model, current model size is: 4.10 MiB

10.查询SDK版本

APIGet_sdk_version
描述获取SDK API和驱动的版本号
参数
返回值Sdk_version: API和驱动版本信息。类型为字符串

  获取SDK版本信息

sdk_version = rknn.get_sdk_version()


  返回的SDK信息如下

  1. RKNN VERSION:
    API: 0.9.9 (2bf05e1 build: 2019-08-14 14:42:10)
    DRV: 0.9.9 (8509ec7 build: 2019-08-05 10:54:34)


热门文章推荐
热门产品推荐
  • RK3588核心板 | NXN-CORE-3588-BTB-5060-V2

    RK3588核心板 | NXN-CORE-3588-BTB-5060-V2

    核心板

    0.00

    0.00

  • RK3588核心板 | NXN-CORE-3588-BTB-6080-V2

    RK3588核心板 | NXN-CORE-3588-BTB-6080-V2

    核心板

    20000.00

    2799.00

  • RK3588核心板 | NXN-CORE-3588-MXM-7082-V2

    RK3588核心板 | NXN-CORE-3588-MXM-7082-V2

    核心板

    20000.00

    2799.00

  • RK3576核心板 | NXN-CORE-3576-260-5070-V1

    RK3576核心板 | NXN-CORE-3576-260-5070-V1

    核心板

    0.00

    0.00

  • RK3568核心板 | NXN-CORE-3568-MXM-5282-V2

    RK3568核心板 | NXN-CORE-3568-MXM-5282-V2

    核心板

    0.00

    0.00

  • RV1126核心板 | NXN-CORE-1126-BTB-4045-V2

    RV1126核心板 | NXN-CORE-1126-BTB-4045-V2

    核心板

    699.00

    699.00

  • 一种多通道视频采集及拼接显示的应用程序

    一种多通道视频采集及拼接显示的应用程序

    应用开发

    20000.00

    2799.00

  • 一种基于RK3588的通用型开发板

    一种基于RK3588的通用型开发板

    产品中心

    20000.00

    2799.00

  • 物联网云平台

    物联网云平台

    应用开发

    0.00

    0.00

Copyright © 2021-2024 福州牛新牛科技有限公司 All rights reserved. |