采用rknn-toolkit导出rknn模型并部署在rock3a-rk3568芯片 上全流程

news2024/11/26 16:25:07

因工作需要,需要将目标检测模型 部署在开发板上。在走了很多弯路后 找到一个成功的案例并记载下来

这里说一下我现有的硬件设备 。

我是购买的RADXA的rock3a开发板 搭载的soc是rk3568

这是开发板的正面图,因为瑞芯微针对计算机视觉中的目标检测模型有一套自己的前向推理框架,所以我就着眼于搭载rockchip的开发板rock3a

目标检测模型 这里采用的是yolo模型  由于原生yolov5模型里面有一些 算子 可能在模型转换时不支持,这里采用瑞芯微官方推荐的yolov5,链接在下面:

GitHub - airockchip/yolov5: YOLOv5 in PyTorch > ONNX > CoreML > TFLite

下载好源代码后,需要修改一个地方:

修改的代码我这里贴出来

def forward(self, x):
        z = []  # inference output
        for i in range(self.nl):
            if os.getenv('RKNN_model_hack', '0') != '0':
                z.append(torch.sigmoid(self.m[i](x[i])))
                continue

            x[i] = self.m[i](x[i])  # conv
            '''
            bs, _, ny, nx = x[i].shape  # x(bs,255,20,20) to x(bs,3,20,20,85)
            x[i] = x[i].view(bs, self.na, self.no, ny, nx).permute(0, 1, 3, 4, 2).contiguous()

            if not self.training:  # inference
                if self.onnx_dynamic or self.grid[i].shape[2:4] != x[i].shape[2:4]:
                    self.grid[i], self.anchor_grid[i] = self._make_grid(nx, ny, i)

                y = x[i].sigmoid()
                if self.inplace:
                    y[..., 0:2] = (y[..., 0:2] * 2 + self.grid[i]) * self.stride[i]  # xy
                    y[..., 2:4] = (y[..., 2:4] * 2) ** 2 * self.anchor_grid[i]  # wh
                else:  # for YOLOv5 on AWS Inferentia https://github.com/ultralytics/yolov5/pull/2953
                    xy, wh, conf = y.split((2, 2, self.nc + 1), 4)  # y.tensor_split((2, 4, 5), 4)  # torch 1.8.0
                    xy = (xy * 2 + self.grid[i]) * self.stride[i]  # xy
                    wh = (wh * 2) ** 2 * self.anchor_grid[i]  # wh
                    y = torch.cat((xy, wh, conf), 4)
                z.append(y.view(bs, -1, self.no))

        if os.getenv('RKNN_model_hack', '0') != '0':
            return z

        return x if self.training else (torch.cat(z, 1),) if self.export else (torch.cat(z, 1), x)
        '''
        return x[0],x[1],x[2]

 然后 根据自己的数据集 训练一版模型 ,训练过程这里不赘述。

这里将训练好的模型yolov5s.pt 转化为onnx模型

转化命令为 :

python3   export.py --weights yolov5s.pt --img 640 --batch 1 --opset 12 --include onnx

转化完后 需要用Netron软件打开模型的可视化界面

记下 图中 的三个框里面的节点名称,这三个节点是网络的输出节点

 新建一个 python文件 onnx2rknn.py  该文件是仿制test.py文件编写的

文件内容为

from rknn.api import RKNN

ONNX_MODEL = 'yolov5s.onnx'
platform = "rk3568"
RKNN_MODEL = 'yolov5s_{}_out_opt.rknn'.format(platform)

if __name__ == '__main__':

    add_perm = False # 如果设置成True,则将模型输入layout修改成NHWC
    # Create RKNN object
    rknn = RKNN(verbose=True)

    # pre-process config
    print('--> config model')
    rknn.config(mean_values=[[0, 0, 0]], std_values=[[255, 255, 255]],  target_platform=platform,
                )
    print('done')

    # Load tensorflow model
    print('--> Loading model')
    ret = rknn.load_onnx(model=ONNX_MODEL,outputs=['output', '327', '328'])# 这里一定要根据onnx模型修改
    if ret != 0:
        print('Load onnx model failed!')
        exit(ret)
    print('done')

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

    # rknn.export_rknn_precompile_model(RKNN_MODEL)
    rknn.export_rknn(RKNN_MODEL)

    rknn.release()

并将该文件放置于rknn-toolkit工作目录下

我的目录是/home/rock/workspace/rknn-toolkit2-1.4.0/examples/onnx/yolov5

也就是example目录下的onnx专栏的yolov5子目录 

 注意 需要在onnx2rknn.py文件中 注明 模型运行的目标平台 我的目标平台是rk3568 

另外需要将上一步 netron 查看的输出部分的三个节点 在onnx2rknn.py文件中注明

也就是如下截图所示

 python3 onnx2rknn.py 运行该文件后 生成的rknn模型 

将该模型 传输到开发板上

注意,这里有一个容易忽略的地方 我的rknn-toolkit的版本是1.4.0

如果我的开发板librknnrt.so 动态库的版本是1.3.0 就会报错 这里版本一定要对应上

在开发板上运行模型 进行单张图片的目标检测 ,运行结果如下图所示

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/143459.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java IO流 - 缓冲流的详细使用介绍

文章目录缓冲流缓冲流概述字节缓冲流字符缓存流缓冲流 缓冲流概述 缓冲流介绍: 缓冲流也称为高效流、或者高级流。之前学习的字节流和字符流可以称为原始流。 作用:缓冲流自带缓冲区、可以提高原始字节流、字符流读写数据的性能 缓冲流分为: 字节缓存输入流、字节…

做个测试工具

这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注…

uniapp中引入vant Weapp

Vant Weapp官:https://vant-contrib.gitee.io/vant-weapp/#/home 步骤一:下载vant组件插件 从github上下载该插件https://github.com/youzan/vant-weapp 只要这个dist文件夹,把dist重命名为vant; 步骤二: 与pages…

301-295- 至少有 K 个重复字符的最长子串-0105

题解 本题使用分治策略,如果某个字符的出现次数小于k,则用它将数组分开,再把每个子数组组委参数递归执行.如果都大于k,则将该字符串的长度返回. 用一个字符分割,往深了分割各子字符串,这个字符分割完成,使用另一个字符进行分割,而不是一次用多个字符进行分割.这个题递归有些绕…

电脑怎么重装系统?小白也能轻松掌握这些方法

重新安装计算机系统有两种原因:一种是计算机系统可以正常使用,但是电脑比较卡,为了提高它的运行速度,所以想要通过重新安装系统来解决这个问题;另一种原因是计算机系统文件丢失,系统出现蓝屏,或…

MQ概念简介

队列管理器 队列管理器是MQ系统中最上层的一个概念,由它为我们提供基于队列的消息服务。 2) 消息 在MQ中,我们把应用程序交由MQ传输的数据定义为消息,我们可以定义消息的内容并对消息进行广义的理解,比如:用户的各种类…

机器学习100天(二十九):029 K折交叉验证

机器学习100天,今天讲的是:K 折交叉验证! 《机器学习100天》完整目录:目录 机器学习中,我们常会遇到一个问题,就是超参数的选择,超参数就是机器学习算法中的调优参数,比如上一节 K 近邻算法中的 K 值。K 折交叉验证就是帮助我们选择最优的超参数。 首先,介绍一下简…

FPGA并行计算可编程芯片

玩转Zynq可以使用Vivado创建一个FPGA工程。什么是FPGA前言自FPGA诞生以来,FPGA(现场可编程门阵列)就引起了人们的关注。在1980年代中期,Ross Freeman和他的同事从Zilog购买了该技术,并创建了Xilinx,目标是A…

基于Java+SpringBoot+vue+node.js实现自行车租赁平台管理系统

基于JavaSpringBootvuenode.js实现自行车租赁平台管理系统 博主介绍:5年java开发经验,专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 超级帅帅吴 欢迎点赞 收藏 ⭐留言 文末获取源码联系方式 文章目录基于JavaSp…

netmap: UDP 协议栈的实现

文章目录1、获取以太网数据1.1、netmap 原理1.2、netmap 环境搭建2、udp 协议栈的实现2.1、以太网帧2.2、ip 协议2.3、udp 协议2.4、问题分析3、ARP 协议的实现4、icmp 协议的实现5、netmap 代码实现1、获取以太网数据 自定义协议栈,需要获取原始的以太网数据&…

第50问:从连接判断应用访问数据库的异常行为

问 我发现应用有一根访问数据库的连接有异常流量,如何判断是应用哪个逻辑导致了异常行为 实验 先起锅烧一个数据库实例: 我们用 mysqlslap 作为应用: 假设在 MySQL 中,我们认为这根连接有异常流量: 通过 ss 找到这根…

阿里一面 | 说说你对 MySQL 死锁的理解

1、什么是死锁? 死锁指的是在两个或两个以上不同的进程或线程中,由于存在共同资源的竞争或进程(或线程)间的通讯而导致各个线程间相互挂起等待,如果没有外力作用,最终会引发整个系统崩溃。 2、Mysql出现死…

cordova-Toast的使用 -官方插件和自定义插件

前言:cordova是使用前端技术来开发app,可以节省成本和快速发布。不需要了解原生app开发 加载web的方式,可以兼容生成Android、ios以及浏览器等各种平台的项目 前文:cordova开发流程 一、官方提示浮动框 cordova-plugin-x-toast 1.cordova pl…

二、GtkApplication and GtkApplicationWindow

1 GtkApplication 1.1 GtkApplication and g_application_run 人们编写编程代码来开发应用程序。什么是应用程序?应用程序是使用库运行的软件,其中包括操作系统、框架等。在GTK 4编程中,GTK应用程序是使用GTK库运行的程序(或可执行程序)。 编写GtkAp…

屏幕录制有快捷键吗?录屏快捷键ctrl加什么

我们日常使用的电脑是自带录屏功能,可以方便我们将玩游戏的精彩画面,或者是电影某个片段给录制下来。为了不错过这些精彩片段,可以使用录屏快捷键录制。那电脑录屏快捷键ctrl加什么?今天本文就简单地给大家介绍电脑录屏快捷键&…

【错误记录】IntelliJ IDEA 编译 Java 文件报错 ( 错误: 非法字符: ‘\ufeff‘ )

文章目录一、报错信息二、修改方案一、报错信息 报错信息 : D:\002_Project\003_Java_Work\Xxx\src\main\java\cn\Xxx.java:1: 错误: 非法字符: \ufeff package xxx;出现该问题的原因是 IntelliJ IDEA 在创建文件时 , 为文件添加了 BOM 隐藏字符 , 这是 文件的 字…

(七)汇编语言——更灵活的定位内存地址的方法

目录 and和or ASCII码 [bxidata] SI和DI寄存器 [bxsi]和[bxdi] [bxsiidata]和[bxdiidata] 总结 例子(双重循环的解决方案) 我们知道,对于汇编来说,内存是极为重要的,所以,能精准且巧妙地定位内存地…

进程间通信——信号

目录 1 概念 2 信号类型 linux的基本信号类型 操作 常用的信号 3 怎么操作信号 signal kill raise alarm pause 注意 范例1(自己用信号发送书写sleep函数实现定时炸弹) 范例2(用信号发送书写功能检测用户是否输入,如…

OAuth2.0协议流程与授权模式、协议流程

什么是OAuth2.0OAuth(Open Authorization)是一个关于授权(authorization)的开放网络标准,允许用户授权第三方应用访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方移动应用或分…

Java 如何优雅的导出 Excel

前言 公司项目最近有一个需要:报表导出。整个系统下来,起码超过一百张报表需要导出。这个时候如何优雅的实现报表导出,释放生产力就显得很重要了。下面主要给大家分享一下该工具类的使用方法与实现思路。 实现的功能点 对于每个报表都相同…