RGB/INT8 输入注意事项

01 技术背景

在大多数情况下,我们都推荐用户在编译处理图像任务的模型时,将 input_type_rt 参数配置 nv12,这是考虑到视频通路传来的数据通常都是 nv12 类型,这样配置可以最大化地节约耗时,提高全流程的处理效率。

但在前期的算法验证阶段,往往用户更希望模型能直接读取 rgb/bgr 数据,以更加直观地检查量化效果。在这种使用场景下,往往需要对图像数据做一些专门的处理,否则会产生错误的输出结果。

本教程会详细介绍如何在 input_type_rt 配置 rgb/bgr 时,正确地处理输入数据。

02 工具链环境

hbdk                      3.49.15
horizon-nn                1.1.0
horizon_tc_ui             1.24.3

03 模型说明

这次作为范例使用的模型是 mixvpr,这是一个视觉场景识别算法,输入为 1x3x320x320 的图像,输出是 1x512 的全局描述子。

onnx 模型的输入输出的具体信息如下图所示:

yaml 配置情况如下,浮点模型由 rgb 训练,且希望验证 rgb 输入的效果,因此 input_type_rt 和 input_type_train 都配置为 rgb,同时 input_layout_rt 和 input_layout_train 都配置为 NCHW,也配置了 mean 和 scale 参数。

model_parameters:onnx_model: "mix.onnx"march: "bayes-e"working_dir: 'model_output'output_model_file_prefix: 'mix'
input_parameters:input_type_rt: 'rgb'input_layout_rt: 'NCHW'input_type_train: 'rgb'input_layout_train: 'NCHW'norm_type: 'data_mean_and_scale'mean_value: 123.675 116.280 103.530scale_value: 0.01712475 0.01750700 0.01742919
calibration_parameters:cal_data_dir: './calibration_data_rgb_f32'cal_data_type: 'float32'
compiler_parameters:optimize_level: 'O3'

模型的原始输入为一张 320x320 的彩色 png 图像,pytorch 浮点模型的推理结果如下,可作为量化效果的参考:

模型编译完成后,可以运行 hb_perf mix.bin,查看生成的 png 图,了解 bin 模型的子图结构:

04 推理 quantized.onnx

首先我们需要确认 quantized.onnx 的输入情况,该模型的输入 shape 为 1x3x320x320,数据类型为 int8,并且色彩空间应当是 rgb 类型(对应 input_type_rt)。

但我们知道,opencv 读图后,得到的数据是 bgr,hwc,uint8,且 3 维的,因此需要做一些预处理,才可以得到正确的输入数据。

从读图到预处理到推理 quantized.onnx 的完整代码,及详细注释如下:

from horizon_tc_ui import HB_ONNXRuntime
import numpy as np
import cv2def read_img(input_name):# opencv读图,此时数据是bgr,hwc,uint8,且3维的data = cv2.imread("image.png")# 将bgr转换为rgbdata = cv2.cvtColor(data, cv2.COLOR_BGR2RGB)# 将hwc转换为chwdata = np.transpose(data,(2,0,1))# 将3x320x320转换为1x3x320x320,也就是将chw转换为nchwdata = data[np.newaxis,:,:,:]print(data)# 将uint8的数据,在数值上-128并且转换为int8data = (data - 128).astype(np.int8)# 保存此时的数据,可以作为bin模型的输入data.tofile("rgb_128_int8.bin") print(data)return datadef main(): sess = HB_ONNXRuntime(model_file="./mix_quantized_model.onnx")input_names = [input.name for input in sess.get_inputs()]output_names = [output.name for output in sess.get_outputs()]feed_dict = dict()for input_name in input_names:feed_dict[input_name] = read_img(input_name)outputs = sess.run(output_names, feed_dict)  # 保存推理结果,用于对比正确性   print(outputs[0][0])np.savetxt('output_onnx.txt', outputs[0][0])if __name__ == '__main__':main()

推理完成后查看输出结果,发现和浮点输出较为接近,说明该推理结果可靠。

[-0.05279211  0.01489008 -0.02978017 -0.03113381 -0.07580406  0.02707288-0.05143847 -0.06091398 -0.01489008 -0.0216583   0.06226762 -0.115065540.01759737  0.         -0.01082915 -0.00406093  0.00406093  0.04331661-0.00270729  0.05820669 -0.0121828  -0.01489008  0.11777283 -0.12454105......-0.00270729 -0.01489008  0.05414576 -0.01895102 -0.01353644 -0.06362127-0.02842652  0.02030466  0.08121864 -0.01759737 -0.08121864  0.00541458-0.05279211  0.00541458  0.0676822  -0.04196296  0.04737754 -0.05956033-0.05956033  0.0893405 ]

需要特别强调的是 uint8 转换 int8 的方法,代码中写的是 data=(data-128)。astype(np.int8),如果用户不写,那么 HB_ONNXRuntime 会自动做这一操作(相关处理如下图),得到的推理结果是完全一样的。

但如果用户误写成了 data=data-128,或者 data=data.astype(np.int8),那么将得到完全错误的推理结果,这是因为 uint8 转 int8 有两种方法。

方法 1(正确):在数值上,所有数据全部 -128,对应上文代码中的 data=(data-128)。astype(np.int8)

方法 2(错误):在数值上,0 到 127 的值不变,128 到 255 的值 -256,对应 data=data.astype(np.int8)

如果用户只写了 data=data-128,那么此时的数据类型还是 uint8,HB_ONNXRuntime 会继续做 data=(data-128)。astype(np.int8)操作,这两个操作就等效成了 data=data.astype(np.int8)

方法 2 处理后,得到的推理结果也是完全错误的,和浮点输出对不上

[-0.03068066  0.01534323 -0.01227575 -0.03222021 -0.07364288  0.0.02301195 -0.05062512  0.00766871 -0.04755764 -0.01534323 -0.07364288-0.01534323 -0.01994446  0.04602389  0.00306749 -0.02301195  0.02147820.          0.06290087  0.02761317 -0.02914692  0.10585728 -0.0675021......0.01534323 -0.01841072 -0.02761317  0.02301195  0.02454569 -0.02147820.02761317 -0.02914692  0.01380949 -0.02301195  0.01687698 -0.04755764-0.04755764  0.03835518  0.07671037 -0.03988893  0.01227575 -0.019944460.0352877   0.01841072  0.03988893 -0.05983339  0.         -0.01534323-0.01534323  0.06290087]

因此请务必确保,在 uint8 转 int8 这一步,使用 data=(data-128)。astype(np.int8),或者不转,让 HB_ONNXRuntime 自动执行这一操作。

05 推理 bin

可以借助 hrt_model_exec 的 infer 功能推理模型,hrt_model_exec 的源码已经开放,用户可以直接参考/package/board/hrt_tools/src/hrt_model_exec 目录。

hrt_model_exec infer --model-file mix.bin --input-file rgb_128_int8.bin --enable_dump true --dump_format txt

其中--input-file 的 rgb_128_int8.bin,就是刚才推理 quantized.onnx 时,保存的预处理后的输入文件。对于 hrt_model_exec 工具来说,推理 RGB 输入且为 int8 的模型,不能直接给 png 图像作为输入数据,而需要提前做好预处理,保存成二进制文件再提供给模型。

对于 rgb_128_int8.bin 输入,模型的推理结果如下,和 quantized.onnx 的输出结果完全一致。

-0.052792113 
0.014890083 
-0.029780166 
-0.031133810 
-0.075804062 
0.027072879 
-0.051438469 
-0.060913976 
-0.014890083 
-0.021658303 
......
-0.081218638 
0.005414576 
-0.052792113 
0.005414576 
0.067682199 
-0.041962963 
0.047377538 
-0.059560332 
-0.059560332 
0.089340501 

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

海波龙系统HFM的数据表和各维度取值方法

数据表包括DCE表、DCN表、DCT表 DCE表格存储和值以及相关的日记账调整。 DCN表格存储价值维度剩余成员的数据。 DCT表格存储日记账调整。当日记账被过账时,数据值流向DCE和/或DCN表格。 表的命名格式:APPNAME_[表][场景][年份] 例如:APPNAME_DCE_1_2024, APPNAE应用,DCE表…

.NET9 - Swagger平替Scalar详解(四)

本文分享Swagger中常用功能在Scalar中的使用,包括版本说明、接口分类、接口及参数描述、枚举类型、文件上传和JWT认证等,并提供相关代码示例和效果展示,以及可能遇到的问题和解决方案。书接上回,上一章介绍了Swagger代替品Scalar,在使用中遇到不少问题,今天单独分享一下之…

秒懂Java为什么只有值传递

在Java语言中,数据类型分为基本数据类型和引用数据类型。 基本数据类型(如int、double、char等)的值直接保存在栈上。这些类型的变量在栈内存中有固定的大小,并且值是直接存储在这些变量中的,数据的传递为值传递,这个好理解。以下以引用数据类型来讲解。 引用和实例化对象…

几何校准 和 ros环境下标定Balser相机

几何校准 基本概念 内参数内参数是相机内部的参数,与相机的位置无关,由镜头和感光元器件的特性决定。 包括:主距,主点,畸变参数畸变参数 径向畸变:正和负径向畸变[@] 正径向畸变 (桶形畸变):在这种畸变中,图像中心附近的点会向外移动,图像看起来像是从中心向外膨胀,尤…

datax的安装与使用

1、datax简介概述 DataX 是阿里巴巴集团内被广泛使用的离线数据同步工具/平台,实现包括 MySQL、Oracle、SqlServer、Postgre、HDFS、Hive、ADS、HBase、TableStore(OTS)、MaxCompute(ODPS)、DRDS 等各种异构数据源之间高效的数据同步功能。支持的数据源2、架构 为了解决异构数…

Ollma本地部署Qwen2.5 14B(不使用docker)

部署机器硬件情况: 内存 :32GB 显卡 :3060 为什么不使用docker: 1.网上教程大多以docker为主 2.安装docker的时间太长,在等待的时候顺便尝试一下不用docker的部署 1.安装Ollama 下载地址:https://ollama.com/ 下载好之后默认安装即可。Ollama常用命令 【跟docker差不多,初…

[题解]2024/11/26 模拟赛

校内自命题模拟赛,密码:校OJ地址 http://___.__._.__:____/ 补全pencil 挺板的,点\(u\)的答案是\(dis(1,u)+dis(u,n)\),边\(e=(u,v)\)的答案是\(\min(dis(1,u)+dis(v,n),dis(1,v)+dis(u,n))+w(e)\)。其中\(dis(u,v)\)表示\(u\)到\(v\)的最短路。 从\(1\)和\(n\)各跑一次Dij…

【Autodesk Revit 2025下载与安装】

1、安装包 「Revit 2025」: 链接:https://pan.quark.cn/s/9342ceb1f179 提取码:WmPW 2、安装教程(建议关闭杀毒软件) 1) 双击Setup.exe安装,弹窗安装对话框2) 勾选‘我同意。。’,点击下一步3) 选择软件安装路径,建议C盘之外进行安装,点击安装4) …

CyclicBarrier的介绍

CyclicBarrier的介绍概要CyclicBarrier(循环栅栏/循环屏障)是java.util.concurrent工具类里的一个工具,它是Java提供的一种特定场景下的多线程之间进行交互的使用方法。CyclicBarrier 作用是让一组线程相互等待,当达到一个共同点时,所有之前等待的线程再继续执行,且 Cycl…

Eplan 2024下载与安装

1、安装包EPLAN Electric2024: 链接:https://pan.quark.cn/s/d44ddafa837a 提取码:FpKb 2、安装教程(建议关闭杀毒软件) 1) 解压下载的文件,查看文件目录2) 找到host文件并修改计算机本地host,文件位置(C:\Windows\System32\drivers\etc)3) 拖拽文件…

AI+若依

AI+若依https://www.bilibili.com/video/BV1pf421B71v/?spm_id_from=333.337.search-card.all.click&vd_source=b1acc63fa6d7d73e53111f9e1153f990若依扫盲通义灵码(AI)CRM客户关系管理系统(后台管理系统)选型与搭建:技术选型,环境搭建,框架整合(AI凉凉)设计:基…

ETL数据采集之Sqoop的安装部署及操作

ETL数据采集 数据采集也叫数据集成 ,我们常说的爬虫也是数据采集的一种方式 。 常用的数据采集工具分为两大类:离线数据采集(批量数据采集),实时数据采集(增量数据采集),这次我们分别来学习一下这俩种采集方式的常用工具 离线数据采集 常用工具有Sqoop、DataX、Kettle …