从训练成生成的our.pt到our.onnx再到our.rknn模型转换流程(RK3588全)

  • 本文是在前一篇文章的基础上完成的,《yolov8s.pt转换成onxx再转换成rknn模型用于RK3588》,这篇文章,可以转换成功,但是转换后推理结果慢而且乱画框,怀疑是版本太高,与板子版本不匹配。
  • 最后决定在板子提供的硬件文档中,找到了部分转换方法,并结合自己在网上搜的内容,成功完成模型转换,并在板子上进行验证。

our.pt转换成our.onnx

这步转换需要用到瑞芯微提供的转换工具

下载airockchip_yolov5

下载地址:https://github.com/airockchip/yolov5

  • 该工具的作用如README_rkopt.md 文件中所述
    在这里插入图片描述

  • 导出onnx的命令是python export.py --rknpu --weight yolov5s.pt,yolov5s.pt是模型权重

  • ultralytics_yolov5官方的不同之处
    在这里插入图片描述

    • 总结:为了能将yolov5用在硬件上,瑞芯微提供了这个转换工具,与ultralytics_yolov5官方提供的网络结构有以下三个不同点
      • 优化 focus/SPPF块,以求在相同的结果下获得更好的性能
      • 更改输出节点,从模型中删除post_process。(模型中的后处理块不利于量化)
      • 使用ReLU代替SiLU作为激活层(仅在训练新模型时有效),该代码在yolov5-master\models\common.py中体现出来。只有用这个代码进行训练的时候,这个激活函数才会被修改。

    在这里插入图片描述

  • 本工具是基于https://github.com/ultralytics/yolov5/releases/tag/v7.0改的,该句来自README_rkopt.md 文件中Source部分的描述。
    在这里插入图片描述

  • 本次演示中使用的pt文件是我们自己训练生成的,名为our.pt

创建模型转换环境

大家买板子的时候,厂家都会提供很多文档,其中应该也包含着模型转换的流程,在我们的文档只提供有onnx转rknn的流程(也许有全流程,但我没找到),文档一般都会说明模型转换的环境,如下图所示:

  • 我们的文档名称为: Rockchip_User_Guide_RKNN_Toolkit2_CN-1.5.0.pdf
  • 位于虚拟机路径:/home/tronlong/RK3588/rk3588_linux_release_v1.2.1/external/rknn-toolkit2/doc
    在这里插入图片描述
    注:但是在实际转换中,有的版本不一样其实也可以
    使用lsb_release -a查看虚拟机版本
    在这里插入图片描述
    这里可以看到我们的虚拟机版本是Ubuntu20.04版本,所以我们需要装左边对应的版本。
在虚拟机中安装环境
打开终端依次执行如下命令
  • 安装Python3 工具及依赖库

    sudo apt-get install python3 python3-dev python3-pip
    sudo apt-get install libxslt1-dev zlib1g zlib1g-dev libglib2.0-0 libsm6 libgl1-mesa-glx libprotobuf-dev gcc
    

    在这里插入图片描述
    在这里插入图片描述

  • 安装virtualenv工具

    sudo apt install virtualenv
    

    在这里插入图片描述

  • 创建虚拟环境

    • 在桌面打开终端执行:virtualenv -p /usr/bin/python3 convert_model ,可以看到我的python版本是3.8.10,符合要求的python为3.8版本,创建的虚拟环境的nameconvert_model
      在这里插入图片描述

    • 进入创建的虚拟环境

      source convert_model/bin/activate
      

      在这里插入图片描述

      注: 我把虚拟创建到桌面了,上述命令仅在桌面打开终端时可以用,不然就需要改路径(执行的是convert_model/bin/activate文件)
      在这里插入图片描述

    • 进入LinuxSDK源码rknn-toolkit2/目录
      cd /home/tronlong/RK3588/rk3588_linux_release_v1.2.1/external/rknn-toolkit2/
      在这里插入图片描述

    • 安装 依赖库,我的python版本是3.8.10,所以这里执行命令

       pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple -r doc/requirements_cp38-1.5.0.txt
      

      安装cp38的txt
      在这里插入图片描述
      在这里插入图片描述

    • 接下来安装 RKNN-Toolkit2

      pip3 install packages/rknn_toolkit2-1.5.0+1fa95b5c-cp38-cp38-linux_x86_64.whl
      

      在这里插入图片描述

  • 参考Rockchip_User_Guide_RKNN_Toolkit2_CN-1.5.0.pdf文档中的3.1.1 通过pip install命令安装 部分

  • 参考Rockchip_User_Guide_RKNN_Toolkit2_CN-1.5.0.pdf文档中的3.1.1 通过pip install命令安装 部分

开始转换
  • 切换路径到瑞芯微提供的转换工具,如下图所示,我的路径是在
    /home/tronlong/RK3588/rk3588_linux_release_v1.2.1/airockchip_yolov5/yolov5-master在这里插入图片描述
    在这里插入图片描述

    • 然后修改models/yolo.py文件中的Detect类中的forward方法为
       def forward(self, x):
              z = []  # inference output
              for i in range(self.nl):
                  x[i] = self.m[i](x[i]) # conv
              return x
      
      注: 经过实验发现,如果不修改原来的forward方法,推理结果会乱画框。
      在这里插入图片描述
  • cd切换到export.py所在的目录下,执行命令 python export.py --rknpu --weight our.pt 这里的our.pt是我们训练生成的pt。
    在这里插入图片描述
    注: 在运行的过程中,也会有缺少库或者版本不匹配的问题,这个时候针对下载就行了。

    • 有时库下载不下来,这个需要使用国内镜像下载,网上搜索即可。
      • 例如:pip3 install ipython -i https://pypi.tuna.tsinghua.edu.cn/simple
        其中的-i https://pypi.tuna.tsinghua.edu.cn/simple就是添加镜像的意思

      • 后边有我创建好的环境库文件requirements.txt,可以按照那个创建环境。具体做法:进入创建好的虚拟环境,执行pip install -r requirements.txt

    在这里插入图片描述在这里插入图片描述

  • 最后成功运行,即可生成our.onnx文件
    使用netron软件可以查看生成的onnx网络结构
    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述

our.onnx生成our.rknn

  • 切换到airockchip_yolov5/onnx_rknn目录下
    cd ../onnx_rknn/
    

在这里插入图片描述

  • 需要修改以下3个地方,我的platform是rk3588,保持不变,onnx存放位置在onnx_models文件夹,rknn_models存放生成的rknn模型,该文件夹可以不用创建,代码检查没有该文件夹则会自行创建
    在这里插入图片描述
  • 完整代码如下所示:

import cv2
import numpy as np

from rknn.api import RKNN
import os

if __name__ == '__main__':

    platform = 'rk3588'
    Width = 640
    Height = 640

    MODEL_PATH = './onnx_models/our.onnx'
    NEED_BUILD_MODEL = True


    # Create RKNN object
    rknn = RKNN()

    OUT_DIR = "rknn_models"
    RKNN_MODEL_PATH = './rknn_models/our.rknn'

    if NEED_BUILD_MODEL:
        DATASET = './dataset.txt'
        rknn.config(mean_values=[[0, 0, 0]], std_values=[
                    [255, 255, 255]], target_platform=platform)
        # Load model
        print('--> Loading model')
        ret = rknn.load_onnx(MODEL_PATH)
        if ret != 0:
            print('load model failed!')
            exit(ret)
        print('done')

        # Build model
        print('--> Building model')
        ret = rknn.build(do_quantization=True, dataset=DATASET)
        if ret != 0:
            print('build model failed.')
            exit(ret)
        print('done')

        # Export rknn model
        if not os.path.exists(OUT_DIR):
            os.mkdir(OUT_DIR)
        print('--> Export RKNN model: {}'.format(RKNN_MODEL_PATH))
        ret = rknn.export_rknn(RKNN_MODEL_PATH)
        if ret != 0:
            print('Export rknn model failed.')
            exit(ret)
        print('done')
    else:
        ret = rknn.load_rknn(RKNN_MODEL_PATH)

    rknn.release()

  • 在终端输入 python3 onnx2rknn.py,模型转换成功。
    在这里插入图片描述
    在这里插入图片描述
  • 使用netron软件可以查看生成的rknn网络结构
    在这里插入图片描述

在rk3588板子上的运行效果

在这里插入图片描述

requirement.txt

absl-py==0.15.0
asttokens==2.4.1
astunparse==1.6.3
backcall==0.2.0
cachetools==4.2.4
certifi==2024.8.30
charset-normalizer==2.0.12
clang==5.0
contourpy==1.1.1
cycler==0.12.1
decorator==5.1.1
executing==2.1.0
fast-histogram==0.11
flatbuffers==1.12
fonttools==4.55.0
gast==0.4.0
google-auth==1.35.0
google-auth-oauthlib==0.4.6
google-pasta==0.2.0
grpcio==1.67.1
h5py==3.1.0
idna==3.10
importlib-metadata==8.5.0
importlib-resources==6.4.5
ipython==8.12.3
jedi==0.19.2
keras==2.6.0
Keras-Preprocessing==1.1.2
kiwisolver==1.4.7
Markdown==3.7
MarkupSafe==2.1.5
matplotlib==3.7.5
matplotlib-inline==0.1.7
numpy==1.20.3
oauthlib==3.2.2
onnx==1.10.0
onnxoptimizer==0.2.7
onnxruntime==1.10.0
opencv-python==4.5.5.64
opt-einsum==3.3.0
packaging==24.2
pandas==2.0.3
parso==0.8.4
pexpect==4.9.0
pickleshare==0.7.5
Pillow==7.0.0
prompt-toolkit==3.0.48
protobuf==3.12.2
psutil==5.9.0
ptyprocess==0.7.0
pure-eval==0.2.3
pyasn1==0.6.1
pyasn1-modules==0.4.1
pygments==2.18.0
pyparsing==3.1.4
python-dateutil==2.9.0.post0
pytz==2024.2
PyYAML==6.0.2
requests==2.27.1
requests-oauthlib==2.0.0
rknn-toolkit2==1.5.0+1fa95b5c
rsa==4.9
ruamel.yaml==0.17.4
ruamel.yaml.clib==0.2.8
scipy==1.5.4
seaborn==0.13.2
six==1.15.0
stack-data==0.6.3
tensorboard==2.6.0
tensorboard-data-server==0.6.1
tensorboard-plugin-wit==1.8.1
tensorflow==2.6.2
tensorflow-estimator==2.6.0
termcolor==1.1.0
torch==1.10.1
torchvision==0.11.2
tqdm==4.64.0
traitlets==5.14.3
typing-extensions==3.7.4.3
tzdata==2024.2
urllib3==1.26.20
wcwidth==0.2.13
werkzeug==3.0.6
wrapt==1.12.1
zipp==3.20.2

### 将ONNX模型转换RKNN格式的方法 将ONNX模型转换RKNN格式通常需要借助Rockchip官方提供的 **RKNN Toolkit** 工具包。以下是关于该过程的具体说明以及相关工具的使用方法。 #### RKNN Toolkit简介 RKNN Toolkit 是 Rockchip 提供的一个用于优化和部署神经网络模型至其硬件平台(如RK3588系列芯片)的开发套件。它支持多种主流框架的模型导入,其中包括 ONNX 格式的模型[^1]。 #### 转换流程概述 整个转换流程可以分为以下几个部分: 1. 安装 RKNN Toolkit 用户需先安装适用于目标系统的 RKNN Toolkit 版本。对于 Linux 平台,可以通过 pip 或者 Docker 的方式完成安装。 2. 准备环境与资源文件 确保拥有待转换ONNX 文件,并将其放置于指定的工作目录下。如果涉及图像输入,则还需准备对应的测试数据集或样本图片[^3]。 3. 编写脚本实现自动化操作 利用 Python API 接口编写一段简单的程序来执行具体的加载、配置及导出动作。 #### 实际代码示例 以下展示了一段完整的Python脚本来演示如何通过RKNN Toolkit把名为`best-sim.onnx`的ONNX模型RKNN格式: ```python import rknn.api as rknn_api def convert_onnx_to_rknn(onnx_model_path, output_rknn_path): # 初始化RKNN实例 rknn = rknn_api.RKNN() try: print('Loading ONNX Model...') ret = rknn.load_onnx(model=onnx_model_path) if ret != 0: raise Exception("Failed to load model.") print('Configuring RKNN Parameters...') rknn.config(channel_mean_value='0 0 0 1', reorder_channel='0 1 2') print('Building RKNN Model...') ret = rknn.build(do_quantization=True, dataset='./DATASET.txt') if ret != 0: raise Exception("Build failed!") print(f'Saving RKNN Model into {output_rknn_path}') rknn.export_rknn(path=output_rknn_path) finally: rknn.release() if __name__ == '__main__': onnx_file = 'best-sim.onnx' rknn_output = 'best-sim.rknn' convert_onnx_to_rknn(onnx_file, rknn_output) ``` 此段代码实现了从读取给定路径下的 `best-sim.onnx`, 经过一系列参数调整之后保存最终产物为同名但扩展名为`.rknn`的新文档形式[^2]. #### 注意事项 - 在实际应用过程中可能还需要额外设置量化选项(`do_quantization`)以及其他高级特性以便更好地适配特定设备性能需求. - 数据预处理阶段所使用的均值标准化向量(`channel_mean_value`)应依据原训练集中定义的标准来进行设定. ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱叨叨的小嘟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值