RKNPU2从入门到实践 --- 【5】一、加载非RKNN模型(以pt模型为例)进行模型评估【(1)在rknntoolkit2模拟器上推理测试(2)连板推理】二、RKNN模型【(1)连板推理】

前言

注:本次实验所使用的平台是x86机器上的Ubuntu 20.04虚拟系统,开发板为瑞芯微RK3588,开发板上面的系统为Ubuntu22.04。 
在进行本博文的实验前,你需要确保你的虚拟系统上已经搭建好了rknntoolkit2的环境。

任务:
【1】
      1. 将非RKNN模型转换为RKNN模型,即构建RKNN模型,进而进行模型在rknntoolkit2模拟器上的推理测试,最终完成图像的分类工作。
      2. 连板推理,将模型加载到RKNPU上进行推理测试。
本次所用到的模型为resnet18.pt(pytorch)。
【2】
      1. 将RKNN模型加载到RKNPU上进行推理测试,RKNN模型连板推理测试。
       

模型运行方式如下图所示: 

图1 模型运行方式判断图

图2 加载RKNN模型进行模型推理流程图
图3 加载非RKNN模型进行模型推理流程图

在pycharm中新建一个名为inference_learning文件夹,在该文件夹中创建一个名为inference_pytorch.py 的python文件,如下图所示:

将所需要的资料复制到inference_learning文件夹中,如下图所示:

模型文件:

dataset.txt是RKNN模型量化矫正数据集。

      我们将会按照 加载非RKNN模型进行模型推理流程图 进行逐步编写代码,最终模型能够成功推理图片。

一、非RKNN模型推理步骤 

1.1 RKNN模型构建步骤

前五步和最后一步代码请参考博主的这篇博文:RKNPU2从入门到实践 --- 【4】RKNN 模型构建【使用pycharm一步一步搭建RKNN模型】-CSDN博客

前五步和最后一步的代码如下: 

from rknn.api import RKNN

if __name__ == '__main__':
    # 第一步:创建RKNN对象 
    rknn = RKNN(verbose=True)
    
    # 第二步:配置RKNN对象参数
    rknn.config(
        mean_values=[[123.675,116.28,103.53]],
        std_values=[[58.395,58.395,58.395]],
        target_platform='rk3588'
        # 其余参数保持默认即可
    )
    
    # 第三步:调用load_pytorch接口导入pt模型
    rknn.load_pytorch(model='./resnet18.pt',input_size_list=[[1,3,224,224]])
    
    # 第四步:调用build接口构建RKNN模型
    rknn.build(
        do_quantization=True, # 表示开启rknn模型量化
        dataset='dataset.txt', # 量化所用到的数据集
    )
    
    # 第五步:导出rknn模型
    rknn.export_rknn(export_path='./resnet.rknn')
    
   
    # 最后一步:释放RKNN对象
    rknn.release()

以上代码完成了以下流程:
      创建RKNN对象 -> 调用config接口配置RKNN对象的相关参数 -> 调用 load_pytorch 接口导入pt模型 -> 调用build接口构建RKNN模型 -> 调用 export_rknn 接口导出RKNN模型->......【省略步骤将会在下面介绍】-> 调用release方法释放RKNN对象。
导出RKNN模型步骤在模型推理阶段不是很需要,该步骤可要可不要。
      接下来我们会学习上述步骤中省略步骤的内容,请看1.2小节。

1.2 省略的步骤

1.2.1 初始化运行时环境

1.2.1.1概念介绍

      在模型推理或性能评估之前,必须先初始化运行时环境,明确模型的运行平台(具体的目 标硬件平台或软件模拟器)。

1.2.1.2 实际演示

第六步所需代码如下所示: 

整体代码如下所示:

from rknn.api import RKNN

if __name__ == '__main__':
    # 第一步:创建RKNN对象 
    rknn = RKNN(verbose=True)
    
    # 第二步:配置RKNN对象参数
    rknn.config(
        mean_values=[[123.675,116.28,103.53]],
        std_values=[[58.395,58.395,58.395]],
        target_platform='rk3588'
        # 其余参数保持默认即可
    )
    
    # 第三步:调用load_pytorch接口导入pt模型
    rknn.load_pytorch(model='./resnet18.pt',input_size_list=[[1,3,224,224]])
    
    # 第四步:调用build接口构建RKNN模型
    rknn.build(
        do_quantization=True, # 表示开启rknn模型量化
        dataset='dataset.txt', # 量化所用到的数据集
    )
    
    # 第五步:导出rknn模型
    rknn.export_rknn(export_path='./resnet.rknn')
    
    # 第六步:调用 init_runtime 接口初始化运行时环境
    rknn.init_runtime(
        target=None ,# target 表示rknn模型运行平台,默认为None,表示运行在模拟器上
        device_id=None,
    )
    
    # 最后一步:释放RKNN对象
    rknn.release()

1.2.2 opencv 导入RKNN模型推理的图片

      在进行调用inference接口进行模型推理之前,我们需要用opencv来获取要推理的图片。图片为 前言 部分的飞船,如下图所示。

该部分代码如下所示:

      在上述代码中,使用cv2.cvtColor进行数据格式的转化的原因是,使用opencv(cv2)打开的图片格式为BGR格式,而我们此次的模型为resnet18模型,该模型喂入的图片格式为RGB格式的,因此需要转换一下。 

      接下来便进入到模型推理部分,请看1.2.3小节。

1.2.3 模型推理

1.2.3.1 概念介绍

在进行模型推理前,必须先构建或加载一个 RKNN 模型。

1.2.3.2 实际演示

该部分代码如下:

 该部分代码添入后整体代码如下:

from rknn.api import RKNN
import cv2
if __name__ == '__main__':
    # 第一步:创建RKNN对象 
    rknn = RKNN(verbose=True)
    
    # 第二步:配置RKNN对象参数
    rknn.config(
        mean_values=[[123.675,116.28,103.53]],
        std_values=[[58.395,58.395,58.395]],
        target_platform='rk3588'
        # 其余参数保持默认即可
    )
    
    # 第三步:调用load_pytorch接口导入pt模型
    rknn.load_pytorch(model='./resnet18.pt',input_size_list=[[1,3,224,224]])
    
    # 第四步:调用build接口构建RKNN模型
    rknn.build(
        do_quantization=True, # 表示开启rknn模型量化
        dataset='dataset.txt', # 量化所用到的数据集
    )
    
    # 第五步:导出rknn模型
    rknn.export_rknn(export_path='./resnet.rknn')
    
    # 第六步:调用 init_runtime 接口初始化运行时环境
    rknn.init_runtime(
        target=None ,# target 表示rknn模型运行平台,默认为None,表示运行在模拟器上
        device_id=None,
    )
    
    # 使用opencv获取要推理的图片数据
    img = cv2.imread(
        filename='./space_shuttle_224.jpg',  #filename 表示要读取的图片路径
    )
    
    # cvtColor 数据格式化转化
    cv2.cvtColor(
        src=img, # 表示要转换的数据
        code=cv2.COLOR_BGR2RGB, # code表示转换码
    )
    
    # 第七步:调用 inference 接口进行推理测试
    outputs = rknn.inference(
        inputs=[img], # 表示要推理的数据
        data_format='nhwc', # 表示要推理的数据模式
    )
    
    
    # 最后一步:释放RKNN对象
    rknn.release()

      至此,我们完成了RKNN模型的推理阶段,但最终步骤还没有结束,因为outputs还不是我们一般看到的分类概率值。需要将outputs进行处理。
      因此,接下来请看1.3小节。 

1.3 后处理部分

后处理的代码如下所示:

import numpy as np


def show_outputs(output):
    output_sorted = sorted(output, reverse=True)
    top5_str = '\n-----TOP 5-----\n'
    for i in range(5):
        value = output_sorted[i]
        index = np.where(output == value)
        for j in range(len(index)):
            if (i + j) >= 5:
                break
            if value > 0:
                topi = '{}: {}\n'.format(index[j], value)
            else:
                topi = '-1: 0.0\n'
            top5_str += topi
    print(top5_str)


def show_perfs(perfs):
    perfs = 'perfs: {}\n'.format(perfs)
    print(perfs)


def softmax(x):
    return np.exp(x)/sum(np.exp(x))



show_outputs(softmax(np.array(outputs[0][0])))

添入后整体代码如下: 

from rknn.api import RKNN
import cv2
import numpy as np

def show_outputs(output):
    output_sorted = sorted(output, reverse=True)
    top5_str = '\n-----TOP 5-----\n'
    for i in range(5):
        value = output_sorted[i]
        index = np.where(output == value)
        for j in range(len(index)):
            if (i + j) >= 5:
                break
            if value > 0:
                topi = '{}: {}\n'.format(index[j], value)
            else:
                topi = '-1: 0.0\n'
            top5_str += topi
    print(top5_str)


def show_perfs(perfs):
    perfs = 'perfs: {}\n'.format(perfs)
    print(perfs)


def softmax(x):
    return np.exp(x)/sum(np.exp(x))

if __name__ == '__main__':
    # 第一步:创建RKNN对象 
    rknn = RKNN(verbose=True)
    
    # 第二步:配置RKNN对象参数
    rknn.config(
        mean_values=[[123.675,116.28,103.53]],
        std_values=[[58.395,58.395,58.395]],
        target_platform='rk3588'
        # 其余参数保持默认即可
    )
    
    # 第三步:调用load_pytorch接口导入pt模型
    rknn.load_pytorch(model='./resnet18.pt',input_size_list=[[1,3,224,224]])
    
    # 第四步:调用build接口构建RKNN模型
    rknn.build(
        do_quantization=True, # 表示开启rknn模型量化
        dataset='dataset.txt', # 量化所用到的数据集
    )
    
    # 第五步:导出rknn模型
    rknn.export_rknn(export_path='./resnet.rknn')
    
    # 第六步:调用 init_runtime 接口初始化运行时环境
    rknn.init_runtime(
        target=None ,# target 表示rknn模型运行平台,默认为None,表示运行在模拟器上
        device_id=None,
    )
    
    # 使用opencv获取要推理的图片数据
    img = cv2.imread(
        filename='./space_shuttle_224.jpg',  #filename 表示要读取的图片路径
    )
    
    # cvtColor 数据格式化转化
    cv2.cvtColor(
        src=img, # 表示要转换的数据
        code=cv2.COLOR_BGR2RGB, # code表示转换码
    )
    
    # 第七步:调用 inference 接口进行推理测试
    outputs = rknn.inference(
        inputs=[img], # 表示要推理的数据
        data_format='nhwc', # 表示要推理的数据模式
    )
    # 对outputs进行后处理
    show_outputs(softmax(np.array(outputs[0][0])))
    
    # 最后一步:释放RKNN对象
    rknn.release()

至此,一个完整的推理程序就编写完成了。
我们来运行上述代码:
导出rknn模型。

运行结束后给出概率前五名排列如下图所示:

可以看到概率最大的为812号,概率值为0.9995219....
那么我们来检查以下812号到底是什么?
我们查看标签,得知812号正是航天飞船,模型推理成功。

二、非RKNN模型连板推理

      修改上述代码,只需将 init_runtime接口中的target参数由None取值改为rk3588取值,表示将模型加载到RKNPU上进行推理测试。修改后的总体代码如下:

from rknn.api import RKNN
import cv2
import numpy as np

def show_outputs(output):
    output_sorted = sorted(output, reverse=True)
    top5_str = '\n-----TOP 5-----\n'
    for i in range(5):
        value = output_sorted[i]
        index = np.where(output == value)
        for j in range(len(index)):
            if (i + j) >= 5:
                break
            if value > 0:
                topi = '{}: {}\n'.format(index[j], value)
            else:
                topi = '-1: 0.0\n'
            top5_str += topi
    print(top5_str)


def show_perfs(perfs):
    perfs = 'perfs: {}\n'.format(perfs)
    print(perfs)


def softmax(x):
    return np.exp(x)/sum(np.exp(x))

if __name__ == '__main__':
    # 第一步:创建RKNN对象 
    rknn = RKNN(verbose=True)
    
    # 第二步:配置RKNN对象参数
    rknn.config(
        mean_values=[[123.675,116.28,103.53]],
        std_values=[[58.395,58.395,58.395]],
        target_platform='rk3588'
        # 其余参数保持默认即可
    )
    
    # 第三步:调用load_pytorch接口导入pt模型
    rknn.load_pytorch(model='./resnet18.pt',input_size_list=[[1,3,224,224]])
    
    # 第四步:调用build接口构建RKNN模型
    rknn.build(
        do_quantization=True, # 表示开启rknn模型量化
        dataset='dataset.txt', # 量化所用到的数据集
    )
    
    # 第五步:导出rknn模型
    rknn.export_rknn(export_path='./resnet.rknn')
    
    # 第六步:调用 init_runtime 接口初始化运行时环境
    rknn.init_runtime(
        target='rk3588' ,# target 表示rknn模型运行平台,默认为None,表示运行在模拟器上
        device_id=None,
    )
    
    # 使用opencv获取要推理的图片数据
    img = cv2.imread(
        filename='./space_shuttle_224.jpg',  #filename 表示要读取的图片路径
    )
    
    # cvtColor 数据格式化转化
    cv2.cvtColor(
        src=img, # 表示要转换的数据
        code=cv2.COLOR_BGR2RGB, # code表示转换码
    )
    
    # 第七步:调用 inference 接口进行推理测试
    outputs = rknn.inference(
        inputs=[img], # 表示要推理的数据
        data_format='nhwc', # 表示要推理的数据模式
    )
    # 对outputs进行后处理
    show_outputs(softmax(np.array(outputs[0][0])))
    
    # 最后一步:释放RKNN对象
    rknn.release()

    开发板系统启动之后,我们将开发板连接到虚拟机 Ubuntu20.04 上。 如下图所示:

点击确定后,则会进行连接。连接成功后,会在Ubuntu虚拟系统任务栏中出现一个手机的标识,如下图所示:

 在程序运行前,需要保证Ubuntu虚拟机安装了adb,若没有安装,则使用指令 sudo apt-get install adb 进行安装。
如下图所示:

确保开发板的adb已经成功连接到Ubuntu虚拟系统上。

在终端输入 adb devices 指令也能查看开发板的id号。

接下来使用MobaXterm软件通过串口进行调试。如下所示:

开发板启动之后运行rknn_server服务,如下所示:

若发现运行rknn_server服务失败,请参考博主的博文:更新RK3588开发板的rknn_server和librknnrt.so【这篇文章是RKNPU2从入门到实践 --- 【5】的配套文章】-CSDN博客然后回到Ubuntu20.04虚拟系统中重新运行修改后的程序,如下图所示:

得到结果,发现连板推理得到的结果与在rknntoolkit2模拟器上运行的结果相似。

至此,连板推理成功。

三、RKNN模型推理测试

RKNN模型只能进行连板推理,步骤非常简单,如下:
      将 inference_pytorch.py 文件复制一份并重新命名,得到 inference_rknn.py ,代码目前保持一致。
 
由于是直接加载的RKNN模型,所以就不需要RKNN模型的参数配置、加载非RKNN模型、构建RKNN模型,即不需要如下代码:

然后添加 load_rknn 接口直接加载RKNN 模型,如下所示:

其余地方均不需修改。得到的最终代码为:

from rknn.api import RKNN
import cv2
import numpy as np

def show_outputs(output):
    output_sorted = sorted(output, reverse=True)
    top5_str = '\n-----TOP 5-----\n'
    for i in range(5):
        value = output_sorted[i]
        index = np.where(output == value)
        for j in range(len(index)):
            if (i + j) >= 5:
                break
            if value > 0:
                topi = '{}: {}\n'.format(index[j], value)
            else:
                topi = '-1: 0.0\n'
            top5_str += topi
    print(top5_str)


def show_perfs(perfs):
    perfs = 'perfs: {}\n'.format(perfs)
    print(perfs)


def softmax(x):
    return np.exp(x)/sum(np.exp(x))

if __name__ == '__main__':
    # 第一步:创建RKNN对象
    rknn = RKNN(verbose=True)

    # 调用 load_rknn 接口直接加载RKNN模型
    rknn.load_rknn(path='./resnet.rknn') # path 表示加载的RKNN模型路径
    # 第五步:导出rknn模型
    rknn.export_rknn(export_path='./resnet.rknn')

    # 第六步:调用 init_runtime 接口初始化运行时环境
    rknn.init_runtime(
        target='rk3588' ,# target 表示rknn模型运行平台,默认为None,表示运行在模拟器上
        device_id=None,
    )

    # 使用opencv获取要推理的图片数据
    img = cv2.imread(
        filename='./space_shuttle_224.jpg',  #filename 表示要读取的图片路径
    )

    # cvtColor 数据格式化转化
    cv2.cvtColor(
        src=img, # 表示要转换的数据
        code=cv2.COLOR_BGR2RGB, # code表示转换码
    )

    # 第七步:调用 inference 接口进行推理测试
    outputs = rknn.inference(
        inputs=[img], # 表示要推理的数据
        data_format='nhwc', # 表示要推理的数据模式
    )
    # 对outputs进行后处理
    show_outputs(softmax(np.array(outputs[0][0])))

    # 最后一步:释放RKNN对象
    rknn.release()

然后运行程序,得到:

至此,RKNN模型连板推理成功。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值