RKNPU入门与实践 ---- 混合量化

2024-08-29 10:36

本文主要是介绍RKNPU入门与实践 ---- 混合量化,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

前言

一、混合量化

1.1 概念介绍 

1.1.1 hybrid_quantization_step1

1.1.2 hybrid_quantization_step2

二、实际编写程序 

2.1混合量化第一阶段 

2.2 混合量化第二阶段 

三、混合量化第一步接口参数proposal

前言

为什么要进行混合量化?
答案:提高模型每一层精度,提高模型精度 
从博文:
RKNPU2从入门到实践 --- 【6】模型评估----量化精度分析-CSDN博客我们得到了量化精度,如下图所示,下图表示的是连板推理时模型的量化精度,我们以input.25这一层为例,发现该层的runtime_error中的golden_err【计算的是上一层的输出层,也即input.25当前层的精度】只有0.930068,这是比较小的。

那对于这种问题,该如何处理呢?
这就需要混合量化来优化这个精度了。

一、混合量化

1.1 概念介绍 

1.1.1 hybrid_quantization_step1

混合量化第一阶段

      使用混合量化功能时,第一阶段调用的主要接口是 hybrid_quantization_step1,用于生成临时 模 型 文 件 ( {model_name}.model ) 、 数 据 文 件 ( {model_name}.data ) 和 量 化 配 置 文 件({model_name}.quantization.cfg)。接口详情如下:

1.1.2 hybrid_quantization_step2

混合量化第二阶段

用于使用混合量化功能时生成 RKNN 模型,接口详情如下: 

举例如下:

二、实际编写程序 

创建项目文件夹,以及相应的文件,并将相关资料放入项目文件夹中,如下图所示。 


在step1.py文件中,先写入如下代码:

from rknn.api import RKNNif __name__ == '__main__':# 第一步:创建RKNN对象rknn = RKNN()# 第二步:配置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]])# 最后一步:释放RKNN对象rknn.release()

2.1混合量化第一阶段 

根据流程图,第四步为混合量化的step1,对应的代码为:

添入step1代码后的整体代码如下:

from rknn.api import RKNNif __name__ == '__main__':# 第一步:创建RKNN对象rknn = RKNN()# 第二步:配置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]])# 使用hybrid_quantization_step1 接口进行混合量化的第一步rknn.hybrid_quantization_step1(dataset='dataset.txt', # 表示模型量化所需要的数据集rknn_batch_size=-1, # 表示自动调整模型输入batch数量proposal=False, # 默认为False。设置为True,可以自动产生混合量化的配置建议值proposal_dataset_size=1)# 最后一步:释放RKNN对象rknn.release()

接下来运行该程序:
 得到如下图:

我们要对得到的resnet18.quantization.cfg文件进行修改。 该文件内容如下所示:

      修改的地方为该文件的第一行,即custom_quantize_layers:{},将input.25层由量化层转换为非量化层,如下所示:

2.2 混合量化第二阶段 

 在step2.py文件中编写程序:

from rknn.api import RKNNif __name__ == '__main__':# 创建RKNN对象rknn = RKNN()# 直接调用hybrid_quantization_step2接口进行混合量化的第二个步骤rknn.hybrid_quantization_step2(model_input='resnet18.model',# 表示第一步生成的模型文件data_input='resnet18.data', #表示第一步生成的配置文件model_quantization_cfg='resnet18.quantization.cfg' # 表示第一步生成的量化配置文件)# 使用量化精度分析接口评估混合量化后的RKNN模型rknn.accuracy_analysis(inputs=['./space_shuttle_224.jpg'],output_dir='./snapshot',target='rk3588')# 调用RKNN模型导出接口(方便后续模型部署)rknn.export_rknn(export_path='./resnet18.rknn')#释放RKNN对象rknn.release()

运行step2.py程序: 

此处有bug,后续更新!!

上图来自于:06_RKNN 模型评估-量化精度分析_哔哩哔哩_bilibili
可以看到,input.25层的golden_err从原来的0.930068变为了现在的0.999746。精度变高。
将经过混合量化和没有经过混合量化的进行对比,这里贴出没有经过混合量化的精度信息截图。

      我们从上图中可以看到,input.25这一层的下一层是142层,但是在经过混合量化之后,我们发现input.25层的下一层并不是142层,而是input.25__int8,这一层在input.25层和142层中间,这是为什么呢?这会带来什么样的后果呢?
      由于142层的输入类型为int8类型,而input.25已经变为float16类型,故浮点数转换为int8类型,因此才会有input.25__int8这一层的出现。我们看到,input.25__int8层的golden_err只有0.930005。因此,这么一操作,精度不增反减了,那该如何补救呢?
      我们干脆直接跳过input.25__int8这一层,因此修改.cfg文件,如下图所示:

加入的 '142': float16 表示将input.25层的输出层,即142层由量化层变为非量化层。
然后重新运行step2.py程序,得到(下图是将终端打印信息拷贝到记事本中,便于观察):

可以看到,input.25 层周围的精度值都变高了,这也就证明了混合量化效果有效。
以上是对 resnet18.pt 模型的某一层进行混合量化。若对模型进行更多层的混合量化,那么模型的效果会大大提高。

三、混合量化第一步接口参数proposal

      在上面,proposal这个参数的取值为False,导致了我们在混合量化第二阶段修改.cfg文件时需要手动去修改。
      那么我们将这个参数取值设置为True,又会有怎样的变化呢?

随后运行step1.py程序,得到:

我们来看看.cfg文件有什么变化:

      我们发现.cfg文件中的custom_quantize_layers由proposal取值为False时的空变为了proposal取值为True时的好多内容。
这相当于是手动筛选精度差的层变为了自动筛选精度差的层。何乐而不为呢? 

这篇关于RKNPU入门与实践 ---- 混合量化的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1117613

相关文章

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

基于MySQL Binlog的Elasticsearch数据同步实践

一、为什么要做 随着马蜂窝的逐渐发展,我们的业务数据越来越多,单纯使用 MySQL 已经不能满足我们的数据查询需求,例如对于商品、订单等数据的多维度检索。 使用 Elasticsearch 存储业务数据可以很好的解决我们业务中的搜索需求。而数据进行异构存储后,随之而来的就是数据同步的问题。 二、现有方法及问题 对于数据同步,我们目前的解决方案是建立数据中间表。把需要检索的业务数据,统一放到一张M

数论入门整理(updating)

一、gcd lcm 基础中的基础,一般用来处理计算第一步什么的,分数化简之类。 LL gcd(LL a, LL b) { return b ? gcd(b, a % b) : a; } <pre name="code" class="cpp">LL lcm(LL a, LL b){LL c = gcd(a, b);return a / c * b;} 例题:

Java 创建图形用户界面(GUI)入门指南(Swing库 JFrame 类)概述

概述 基本概念 Java Swing 的架构 Java Swing 是一个为 Java 设计的 GUI 工具包,是 JAVA 基础类的一部分,基于 Java AWT 构建,提供了一系列轻量级、可定制的图形用户界面(GUI)组件。 与 AWT 相比,Swing 提供了许多比 AWT 更好的屏幕显示元素,更加灵活和可定制,具有更好的跨平台性能。 组件和容器 Java Swing 提供了许多

【IPV6从入门到起飞】5-1 IPV6+Home Assistant(搭建基本环境)

【IPV6从入门到起飞】5-1 IPV6+Home Assistant #搭建基本环境 1 背景2 docker下载 hass3 创建容器4 浏览器访问 hass5 手机APP远程访问hass6 更多玩法 1 背景 既然电脑可以IPV6入站,手机流量可以访问IPV6网络的服务,为什么不在电脑搭建Home Assistant(hass),来控制你的设备呢?@智能家居 @万物互联

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

poj 2104 and hdu 2665 划分树模板入门题

题意: 给一个数组n(1e5)个数,给一个范围(fr, to, k),求这个范围中第k大的数。 解析: 划分树入门。 bing神的模板。 坑爹的地方是把-l 看成了-1........ 一直re。 代码: poj 2104: #include <iostream>#include <cstdio>#include <cstdlib>#include <al

MySQL-CRUD入门1

文章目录 认识配置文件client节点mysql节点mysqld节点 数据的添加(Create)添加一行数据添加多行数据两种添加数据的效率对比 数据的查询(Retrieve)全列查询指定列查询查询中带有表达式关于字面量关于as重命名 临时表引入distinct去重order by 排序关于NULL 认识配置文件 在我们的MySQL服务安装好了之后, 会有一个配置文件, 也就

音视频入门基础:WAV专题(10)——FFmpeg源码中计算WAV音频文件每个packet的pts、dts的实现

一、引言 从文章《音视频入门基础:WAV专题(6)——通过FFprobe显示WAV音频文件每个数据包的信息》中我们可以知道,通过FFprobe命令可以打印WAV音频文件每个packet(也称为数据包或多媒体包)的信息,这些信息包含该packet的pts、dts: 打印出来的“pts”实际是AVPacket结构体中的成员变量pts,是以AVStream->time_base为单位的显

C语言指针入门 《C语言非常道》

C语言指针入门 《C语言非常道》 作为一个程序员,我接触 C 语言有十年了。有的朋友让我推荐 C 语言的参考书,我不敢乱推荐,尤其是国内作者写的书,往往七拼八凑,漏洞百出。 但是,李忠老师的《C语言非常道》值得一读。对了,李老师有个官网,网址是: 李忠老师官网 最棒的是,有配套的教学视频,可以试看。 试看点这里 接下来言归正传,讲解指针。以下内容很多都参考了李忠老师的《C语言非