PPOCRV3文本识别模型精度损失问题解决

news2024/11/15 23:46:02

PPOCRV3文本识别模型精度损失问题解决

  • 1. 得到可用的ncnn模型
    • 2. 先看问题
    • 3. 快速解决
    • 4. 问题分析
    • 5. 最终效果
    • 6. 结语

1. 得到可用的ncnn模型

paddleocr文本识别模型(ch_PPOCRv3_rec_infer)转ncnn模型,我参考了这位大神的博客,基本包括了我遇到的所有问题,是一篇很好的文章:https://blog.csdn.net/qq_29543997/article/details/128923330,博客中提到转换的模型存在精度损失,也是基于该问题引出这篇博客。

2. 先看问题

在得到ncnn模型后,使用同一张图像,使用onnx模型和ncnn模型分别在paddleocr工程和ncnn工程上运行看识别结果, 发现精度损失在10-4,按理说onnx转ncnn仅是数据架构的转换,误差不会这么大:
在这里插入图片描述

3. 快速解决

尝试更换ncnn编译库,重新测试模型精度损失。下面内容是个人排查问题的方法,有兴趣的可以看看。

4. 问题分析

分析方法:分析onnx模型和ncnn模型各层的输入结果,比对损失(过程还是蛮痛苦的)。

  1. onnx模型各层输出打印:https://blog.csdn.net/xefei/article/details/126489861
  2. ncnn模型各层输出打印:这个挺简单的,改一下输出blob名称就好。

最终发现ncnn模型中将paddle推理模型中的AdaptiveAvgPool层(onnx不支持)和其之后的卷积层替换为了GlogalAvgPool和InnerProduct层,对ncnn的.param文件修改后,该部分的精度损失由[10-4,10-3],降到[0,10-6]。

  1. paddle推理模型对应源码:PaddleOCR/ppocr/modeling/backbones/det_mobilenet_v3.py中的"class SEModule(nn.Layer):"
  2. param文件文件介绍:https://blog.csdn.net/m0_37264397/article/details/124184227#t1
  3. ncnn官网各层参数介绍:https://github.com/Tencent/ncnn/wiki/operators

param文件修改内容如下:

# 前两行
# 修改前
7767517
251 289
# 修改后
7767517
253 291

# 修改GlogalAvgPool和InnerProduct层(2处)
# 修改前
Pooling                         p2o.GlobalAveragePool.0  1 1 batch_norm_50.tmp_4_splitncnn_1 p2o.GlobalAveragePool.1 0=1 4=1
InnerProduct             p2o.Conv.24              				1 1 p2o.GlobalAveragePool.1 relu_2.tmp_0 0=64 1=1 2=16384 9=1
InnerProduct             p2o.Conv.25             				1 1 relu_2.tmp_0 conv2d_110.tmp_0 0=256 1=1 2=16384
# 修改后
Pooling                  		p2o.GlobalAveragePool.0  1 1 batch_norm_50.tmp_4_splitncnn_1 p2o.GlobalAveragePool.1 0=1 7=1 8=1 5=1
Convolution              p2o.Conv.24              			  1 1 p2o.GlobalAveragePool.1 conv2d_120.tmp_0 0=64 1=1 5=1 6=16384 9=1
ReLU                     		p20.ReLU.1               				  1 1 conv2d_120.tmp_0 relu_2.tmp_0
Convolution              p2o.Conv.25            				  1 1 relu_2.tmp_0 conv2d_110.tmp_0 0=256 1=1 5=1 6=16384

# 修改前
Pooling                  		p2o.GlobalAveragePool.2  1 1 batch_norm_52.tmp_4_splitncnn_1 p2o.GlobalAveragePool.3 0=1 4=1
InnerProduct             p2o.Conv.28              			  1 1 p2o.GlobalAveragePool.3 relu_3.tmp_0 0=128 1=1 2=65536 9=1
InnerProduct             p2o.Conv.29           				  1 1 relu_3.tmp_0 conv2d_113.tmp_0 0=512 1=1 2=65536
# 修改后
Pooling                  		p2o.GlobalAveragePool.2  1 1 batch_norm_52.tmp_4_splitncnn_1 p2o.GlobalAveragePool.3 0=1 7=1 8=1 5=1
Convolution              p2o.Conv.28              			  1 1 p2o.GlobalAveragePool.3 conv2d_121.tmp_0 0=128 1=1 5=1 6=65536 9=1
ReLU                     		p20.ReLU.2               			  	  1 1 conv2d_121.tmp_0 relu_3.tmp_0
Convolution              p2o.Conv.29              			  1 1 relu_3.tmp_0 conv2d_113.tmp_0 0=512 1=1 5=1 6=65536

修改前后param的网络结构如下:
在这里插入图片描述
经过以上修改得到的模型仍有误差,接着往下逐层分析,最终确认注意力机制中的InnerProduct层(全连接层)导致的精度损失,经过分析,甚至手动计算ncnn模型该层的输出,得到的输出结果与onnx结果精度损失很小。直接怀疑ncnn编译库内部计算存在问题,实在没办法了,尝试更换一版ncnn的编译库,没想到精度损失直接降到0~10-5。至于到底是ncnn版本问题,还是编译过程中出了问题就不得而知。

  1. 获取ncnn模型各层权重:https://github.com/Tencent/ncnn/issues/4666#issuecomment-1521638902
  2. 获取onnx模型各层权重: 直接用netron打开,点击某一层,右侧可以看到其weights和bias, 且能够保存下来。

5. 最终效果

在这里插入图片描述

上面是对短文本的识别效果,误差还是有10-5,不过对于长文本误差则是在0到10-7,可能是因为短文本图像补边造成的差异,需要进一步确认。

6. 结语

至此来看,自己前面改AdaptiveAvgPool层和InnerProduct层好像没用,白折腾了,直接换ncnn编译库可能就好了。不过经过这么折腾学了不多东西,记录下来作为后备之需。

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

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

相关文章

操作系统八股文知识点汇总

1. 程序编译过程 gcc HelloWorld.c -E -o HelloWorld.i 预处理:加入头文件,替换宏。gcc HelloWorld.c -S -c -o HelloWorld.s 编译:包含预处理,将 C 程序转换成汇编程序。gcc HelloWorld.c -c -o HelloWorld.o 汇编:包…

在linux下搭建clash服务

下载clash并配置 clash安装包 一般下载名称中带clash-linux-amd64的包 下载完用gunzip解压,解压后重命名或者链接到系统环境变量目录都行 下载配置信息 wget -O config.yaml [订阅链接] wget -O Country.mmdb https://www.sub-speeder.com/client-download/Coun…

深元边缘计算盒子在社区的应用,提高社区的安全性和生活质量

近年来,随着人工智能技术的不断发展和普及,越来越多的社区开始应用边缘计算盒子AI视觉分析技术,以提高社区的安全性和管理效率。本文将介绍边缘计算盒子AI视觉分析技术在社区中的应用及其优势。 一、边缘计算盒子AI视觉在社区中的应用 1.安防…

uniapp中实现自定义导航栏

整个小程序默认配置存在系统内置导航和tabbar,项目中需求存在自定义的导航。 uniapp中vue封装组件(顶部导航、底部tabbar),按照vue的相关语法使用。 在page.json文件中修改配置: 自定义导航组件: 给自定义…

PLM听过很多遍,却依旧不知道是什么?看完这篇你就懂

上周参加展会,很多客户在现场了解到e企拆图解决方案后,向我们咨询了很多问题,发现有几个名词经常被提及,比如PLM、PDM、BOM等。随着技术的爆炸发展,新的名词概念也与日俱增,对于这些名词,可能我…

工贸企业重大事故隐患判定标准,自2023年5月15日起施行

应急管理部发布了《工贸企业重大事故隐患判定标准》(自2023年5月15日起施行),适用于判定冶金、有色、建材、机械、轻工、纺织、烟草、商贸等工贸企业重大事故隐患。新修改的安全生产法对建立健全重大事故隐患治理督办制度、督促生产经营单位消…

关于ffmpeg的使用过程中遇到的点(php)

有段日子没更新,最近使用ffmepg,这里记录一下 我这边就直说一下我工作中遇到的注意事项和使用方法,就不太详细说了 首先是安装的问题,windwos的话比较简单,官网下载安装文件,解压之后。设置环境变量 系统…

【react全家桶学习】react中组件定义及state属性(超详/必看)

函数式组件定义及特点 定义&#xff08;核心就是一个函数&#xff0c;返回虚拟dom&#xff09;&#xff1a; import React from reactexport default function index() {return <div>index</div> }特点&#xff1a; 1、适用于【简单组件】的定义2、是一个函数&a…

【三维重建】NeRF原理+代码讲解

文章目录 一、技术原理1.概览2.基于神经辐射场&#xff08;Neural Radiance Field&#xff09;的体素渲染算法3.体素渲染算法4.位置信息编码&#xff08;Positional encoding&#xff09;5.多层级体素采样 二、代码讲解1.数据读入2.创建nerf1.计算焦距focal与其他设置2.get_emb…

1690_Python中的复数数据类型

全部学习汇总&#xff1a;GreyZhang/python_basic: My learning notes about python. (github.com) 之前总结的知识中设计的数据类型有整形、浮点、字符串等&#xff0c;这些类型表示的都是一个单独的独立数据对象。在Python有也有表示复数改变的数据类型&#xff0c;也就是下…

Gradio入门到进阶全网最详细教程[二]:快速搭建AI算法可视化部署演示(侧重参数详解和案例实践)

常用的两款AI可视化交互应用比较&#xff1a; Gradio Gradio的优势在于易用性&#xff0c;代码结构相比Streamlit简单&#xff0c;只需简单定义输入和输出接口即可快速构建简单的交互页面&#xff0c;更轻松部署模型。适合场景相对简单&#xff0c;想要快速部署应用的开发者。 …

千云物流 -测试服务器准备 -iotdb,redis

服务器准备 准备CentOS-7-x86_64-DVD-2009.iso镜像 链接&#xff1a;https://pan.baidu.com/s/1rNkfoeHOuYv0OmitWVDNsQ?pwdjanl 提取码&#xff1a;janl 安装服务器需要的命令yum update yum install net-tools.x86_64 -y yum install zip unzip -y ## 安装jdk到当前机器&am…

MySQL查看索引语句:SHOW INDEX 详细讲解

概述&#xff1a; SHOW INDEX语句是MySQL中用于查看表索引信息的语句。它提供了有关表中索引的详细信息&#xff0c;包括索引名称、索引类型、关联的列等。以下是SHOW INDEX的详细说明&#xff1a; 语法&#xff1a; SHOW INDEX FROM table_name [FROM db_name] [WHERE cond…

python海龟库教学

海龟库&#xff1a; 海龟绘图 “小海龟”turtle是Python语言中一个很流行的绘制图像的函数库&#xff0c;想象一个小乌龟&#xff0c;在一个横轴为x、纵轴为y的坐标系原点&#xff0c;(0,0)位置开始&#xff0c;它根据一组函数指令的控制&#xff0c;在这个平面坐标系中移动&…

Visual Studio调试的10个技巧

https://www.cnblogs.com/darrenji/p/3900023.html#e 本篇体验Visual Studio的10个调试技巧&#xff0c;包括&#xff1a; 1、插入断点和断点管理2、查看变量信息3、逐语句F11&#xff0c;逐过程F10&#xff0c;跳出ShiftF114、查看堆栈信息5、设置下一条执行语句6、调试时修改…

API接口的自我阐述

API&#xff08;Application Programming Interface&#xff09;&#xff0c;翻译为应用程序接口&#xff0c;是一套定义程序之间如何通讯的接口。API可以实现软件的可重用性、可维护性和互操作性&#xff0c;同时也可以提升软件的性能和安全性。API接口是一个软件系统中的重要…

案例2:Java图书商城系统设计与实现开题报告

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

XPM_CDC_HANDSHAKE(UG974)

Parameterized Macro: Bus Synchronizer with Full Handshake&#xff08;参数化宏&#xff1a;具有完全握手的总线同步器&#xff09; MACRO_GROUP: XPMMACRO_SUBGROUP: XPM_CDCFamilies: UltraScale, UltraScale 1、 Introduction&#xff08;介绍&#xff09; 此…

ChatGPT国内可用版-国内chatGPT哪个软件好用

国内chatGPT哪个软件最好用 国内对接ChatGPT软件&#xff0c;让智能的对话变得更加简单便捷&#xff01;ChatGPT是由OpenAI公司开发的最新一代自然语言处理技术&#xff0c;为聊天机器人赋予了更加真实、流畅、智能的语言表达能力。 我们是国内一家专注于人工智能和自然语言处…

手撕源码(一)HashMap(JDK8)

目录 1.使用示例2.new HashMap<>() 解析2.1 加载因子2.2 构造方法 3.put() 解析3.1 原始put(k, v)3.2 计算哈希1&#xff09;为什么要进行二次hash&#xff1f;2&#xff09;二次hash计算示例&#xff1a;3&#xff09;为什么使用 (length-1)&hash 而不是 hash%lengt…