PaddleOCR基于PPOCRv4的垂类场景模型微调——手写文字识别

PaddleOCR手写文字识别

    • 一. 项目背景
    • 二. 环境配置
    • 三. 数据构造
    • 四. 模型微调
    • 五. 串联推理
    • 六. 注意事项
    • 七. 参考文献

光学字符识别(Optical Character Recognition, OCR),ORC是指对包含文本资料的图像文件进行分析识别处理,获取文字及版面信息的技术,检测图像中的文本资料,并且识别出文本的内容。

在这里插入图片描述
PaddleOCR提供的PP-OCR系列模型在通用场景中性能优异,能够解决绝大多数情况下的检测与识别问题。在垂类场景中,如果希望获取更优的模型效果,可以通过模型微调的方法,进一步提升PP-OCR系列检测与识别模型的精度。

一. 项目背景

目前先进的OCR模型在打印体的识别上已经能获得比较好的效果,但由于手写体的风格各异,提高手写体的识别精度具有比较高的挑战。因此需要基于手写数据微调预训练模型,从而提高手写文字的识别效果。

在这里插入图片描述

二. 环境配置

1. 安装PaddlePaddle 2.0
在官网上找到对应版本的PaddlePaddle进行安装。

2.克隆PaddleOCR repo代码
【推荐】git clone https://github.com/PaddlePaddle/PaddleOCR

如果因为网络问题无法pull成功,也可选择使用码云上的托管:git clone https://gitee.com/paddlepaddle/PaddleOCR

注:码云托管代码可能无法实时同步本github项目更新,存在3~5天延时,请优先使用推荐方式。

3. 安装第三方库

cd PaddleOCR
pip3 install -r requirements.txt

三. 数据构造

AIstudio上有开源的手写OCR识别数据集:https://aistudio.baidu.com/datasetdetail/102884,由中科院手写数据集及网上开源数据组合而成。训练共24w,测试1.7w,可直接使用paddleOCR训练。

在实际的场景中,我们往往有针对特定场景的数据,因此需要对数据进行标注和分割。PPOCRLabel内置了OCR模型,可以辅助标注。
PPOCRLabel官方文档:https://github.com/PaddlePaddle/PaddleOCR/blob/release/2.7/PPOCRLabel/README_ch.md

1. 安装与运行PPOCRLabel

Windows

pip install PPOCRLabel  # 安装

# 选择标签模式来启动
PPOCRLabel --lang ch  # 启动【普通模式】,用于打【检测+识别】场景的标签
PPOCRLabel --lang ch --kie True  # 启动 【KIE 模式】,用于打【检测+识别+关键字提取】场景的标签

Ubuntu Linux

pip3 install PPOCRLabel
pip3 install trash-cli

# 选择标签模式来启动
PPOCRLabel --lang ch  # 启动【普通模式】,用于打【检测+识别】场景的标签
PPOCRLabel --lang ch --kie True  # 启动 【KIE 模式】,用于打【检测+识别+关键字提取】场景的标签

MacOS

pip3 install PPOCRLabel
pip3 install opencv-contrib-python-headless==4.2.0.32 # 如果下载过慢请添加"-i https://mirror.baidu.com/pypi/simple"

# 选择标签模式来启动
PPOCRLabel --lang ch  # 启动【普通模式】,用于打【检测+识别】场景的标签
PPOCRLabel --lang ch --kie True  # 启动 【KIE 模式】,用于打【检测+识别+关键字提取】场景的标签

2. 基于PPOCRLabel的数据标注

下面以五张图片为例介绍一下数据标注过程,首先点击文件->打开目录打开图片所在的文件夹。
在这里插入图片描述
点击PaddleOCR->选择模型选择模型语言(每次打开软件都需要选择),点击自动标注
在这里插入图片描述
然后对识别不准确的部分进行手动调整,可以调整检测框,也可以调整右侧的识别结果。比如图片中的“沧海桑田”识别有误,则我们人为进行修改。调整完毕后点击确认按钮保存。

3. 导出标注结果
点击文件按钮,可以看到导出标记结果导出识别结果两项,分别用于导出文本检测的标签和文本识别的标签。导出后文件内容如图所示:
在这里插入图片描述
请勿手动更改其中内容,否则会引起程序出现异常

文件名说明
Label.txt检测标签,可直接用于PPOCR检测模型训练。用户每确认5张检测结果后,程序会进行自动写入。当用户关闭应用程序或切换文件路径后同样会进行写入。
fileState.txt图片状态标记文件,保存当前文件夹下已经被用户手动确认过的图片名称。
Cache.cach缓存文件,保存模型自动识别的结果。
rec_gt.txt识别标签。可直接用于PPOCR识别模型训练。需用户手动点击菜单栏“文件” - "导出识别结果"后产生。
crop_img识别数据。按照检测框切割后的图片。与rec_gt.txt同时产生。

4. 数据集划分

cd ./PPOCRLabel # 将目录切换到PPOCRLabel文件夹下
python gen_ocr_train_val_test.py --trainValTestRatio 6:2:2 --datasetRootPath ../train_data

参数说明:

  • trainValTestRatio 是训练集、验证集、测试集的图像数量划分比例,根据实际情况设定,默认是6:2:2

  • datasetRootPath 是PPOCRLabel标注的完整数据集存放路径。默认路径是 PaddleOCR/train_data 分割数据集前应有如下结构:

|-train_data
  |-crop_img
    |- word_001_crop_0.png
    |- word_002_crop_0.jpg
    |- word_003_crop_0.jpg
    | ...
  | Label.txt
  | rec_gt.txt
  |- word_001.png
  |- word_002.jpg
  |- word_003.jpg
  | ...

在运行前,需要修改gen_ocr_train_val_test.py中第42行:

 imagePath = os.path.join(dataAbsPath, "{}\\{}".format(args.recImageDirName, imageName))

修改为:

 imagePath = os.path.join(dataAbsPath, "{}/{}".format(args.recImageDirName, imageName))

否则图片读取时会报路径错误。

运行结束后,train_data文件夹中会出现名为detrec的文件夹中,文件夹中分别存放文本检测文本识别对应的图片和分割后的训练集、验证集和验证集列表。

|-train_data
  | ...
  |-det
    |- train
        |- 训练集图片
    |- val
        |- 验证集图片
    |- test
        |- 测试集图片
    |- train.txt
    |- val.txt
    |- test.txt
  |-rec
    | ...
  | ...

至此,数据集就已经构建完成,根据不同的任务可直接使用paddleOCR训练。

四. 模型微调

OCR识别主要分为三个部分,分别是文本检测文本方向分类文本识别。PPOCR模型在文本检测和文本方向分类已经能达到比较好的效果,因此本文仅针对文本识别进行微调,另外两个任务的微调方法与之相同。本案例采用开源的手写OCR识别数据集:https://aistudio.baidu.com/datasetdetail/102884

1.下载预训练模型
可使用的模型参考模型列表,本文采用PPOCRv4作为预训练模型:

在这里插入图片描述

cd PaddleOCR
# 使用该指令下载需要的预训练模型
wget -P ./pretrained_models/ https://paddleocr.bj.bcebos.com/PP-OCRv4/chinese/ch_PP-OCRv4_rec_train.tar
# 解压预训练模型文件
tar -xf ./pretrained_models/ch_PP-OCRv4_rec_train.tar -C pretrained_models

2.参数配置
由上图可得,该模型所对应的配置文件为ch_PP-OCRv4_rec_distill.yml,但是在运行时发生错误,测试后发现该模型所对应的配置文件实际为ch_PP-OCRv4_rec.yml

主要修改训练轮数学习率参相关参数,设置预训练模型路径设置数据集路径。 另外,batch_size可根据自己机器显存大小进行调整。 具体修改如下几个地方:

  epoch_num: 100 # 训练epoch数
  save_model_dir: ./output/ch_PP-OCR_v4_rec
  save_epoch_step: 10
  eval_batch_step: [0, 100] # 评估间隔,每隔100step评估一次
  pretrained_model: ./pretrained_models/ch_PP-OCRv4_rec_train/student  # 预训练模型路径


  lr:
    name: Cosine # 修改学习率衰减策略为Cosine
    learning_rate: 0.0001 # 修改fine-tune的学习率
    warmup_epoch: 2 # 修改warmup轮数

Train:
  dataset:
    name: SimpleDataSet
    data_dir: ./train_data # 训练集图片路径
    ext_op_transform_idx: 1
    label_file_list:
    - ./train_data/chineseocr-data/rec_hand_line_all_label_train.txt # 训练集标签
    - ./train_data/handwrite/HWDB2.0Train_label.txt
    - ./train_data/handwrite/HWDB2.1Train_label.txt
    - ./train_data/handwrite/HWDB2.2Train_label.txt
    - ./train_data/handwrite/hwdb_ic13/handwriting_hwdb_train_labels.txt
    - ./train_data/handwrite/HW_Chinese/train_hw.txt

Eval:
  dataset:
    name: SimpleDataSet
    data_dir: ./train_data # 测试集图片路径
    label_file_list:
    - ./train_data/chineseocr-data/rec_hand_line_all_label_val.txt # 测试集标签
    - ./train_data/handwrite/HWDB2.0Test_label.txt
    - ./train_data/handwrite/HWDB2.1Test_label.txt
    - ./train_data/handwrite/HWDB2.2Test_label.txt
    - ./train_data/handwrite/hwdb_ic13/handwriting_hwdb_val_labels.txt
    - ./train_data/handwrite/HW_Chinese/test_hw.txt

由于数据集大多是长文本,因此需要注释掉下面的数据增广策略,以便训练出更好的模型。

- RecConAug:
    prob: 0.5
    ext_data_num: 2
    image_shape: [48, 320, 3]

3.模型训练
我们使用上面修改好的配置文件configs/rec/PP-OCRv4/ch_PP-OCRv4_rec.yml,预训练模型,数据集路径,学习率,训练轮数等都已经设置完毕后,可以使用下面命令开始训练:

# 开始训练识别模型
python3 tools/train.py -c configs/rec/PP-OCRv4/ch_PP-OCRv4_rec.yml

如果训练中断,可采用checkpoints恢复训练:

# 开始训练识别模型
python3 tools/train.py -c configs/rec/PP-OCRv4/ch_PP-OCRv4_rec.yml -o Global.checkpoints="./output/rec_ppocr_v4/best_accuracy"

4.模型验证
验证模型在验证集上的效果:

python3 tools/eval.py -c configs/rec/PP-OCRv4/ch_PP-OCRv4_rec.yml -o Global.pretrained_model="./output/rec_ppocr_v4/best_accuracy"

5.模型导出
将训练模型导出为推理模型:

python3 tools/export_model.py -c configs/rec/PP-OCRv4/ch_PP-OCRv4_rec.yml -o Global.pretrained_model="./output/rec_ppocr_v4/best_accuracy" Global.save_inference_dir="./inference/ch_PP-OCRv4_rec/"

在这里插入图片描述
6.模型推理

python3 tools/infer/predict_rec.py --image_dir="./train_data/handwrite/HWDB2.0Test_images/104-P16_4.jpg" --rec_model_dir="./inference/ch_PP-OCRv4_rec/"

五. 串联推理

模型推理部分官方文档:基于Python引擎的PP-OCR模型库推理

在分别得到文本检测文本方向分类文本识别的推理模型后,即可将三者串联起来进行模型推理。

在执行预测时,需要通过参数image_dir指定单张图像或者图像集合的路径,也支持PDF文件、参数det_model_dir,cls_model_dirrec_model_dir分别指定检测,方向分类和识别的inference模型路径。参数use_angle_cls用于控制是否启用方向分类模型。use_mp表示是否使用多进程(Paddle Inference并不是线程安全,建议使用多进程)。total_process_num表示在使用多进程时的进程数。可视化识别结果默认保存到 ./inference_results 文件夹里面。

在本案例中我们只微调了识别模型,因此在模型库中下载了基于PPOCRv4的文本检测和方向分类的推理模型。

# 使用方向分类器
python3 tools/infer/predict_system.py --image_dir="./train_data/handwrite/HWDB2.0Test_images/" --det_model_dir="./ch_PP-OCRv4_det_infer/" --cls_model_dir="./ch_ppocr_mobile_v2.0_cls_infer/" --rec_model_dir="./inference/ch_PP-OCRv4_rec/" --use_angle_cls=true

六. 注意事项

模型微调的注意事项和技巧参考:模型微调

在微调过程中,由于无法加载最后一层FC的参数,在迭代初期acc=0是正常的情况,不必担心,加载预训练模型依然可以加快模型收敛。

七. 参考文献

PaddleOCR官方文档
Paddle-OCR根据垂直类场景自定义数据微调PP-OCRv4模型
OCR手写文字识别

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux x86_64 平台下系统调用的实现

文章目录 前言一、简介二、Defining a syscall with SYSCALL_DEFINEn()2.1 SYSCALL_METADATA2.2 __SYSCALL_DEFINEx 三、Syscall table entries四、x86_64 syscall invocation参考资料 前言 本文来自 https://lwn.net/Articles/604287/ 一、简介 系统调用(system…

Unity 角色控制(初版)

角色控制器组件,当然是将组件放在角色上了。 using System.Collections; using System.Collections.Generic; using UnityEngine;public class c1 : MonoBehaviour {// 获取角色控制器private CharacterController player;void Start(){// 加载角色控制器player …

【物联网】stm32芯片结构组成,固件库、启动过程、时钟系统、GPIO、NVIC、DMA、UART以及看门狗电路的全面详解

一、stm32的介绍 1、概述 stm32: ST:指意法半导体 M:指定微处理器 32:表示计算机处理器位数 与ARM关系:采用ARM推出cortex-A,R,M三系中的M系列,其架构主要基于ARMv7-M实现 ARM分成三个系列: Cortex-A&…

机器人工具箱学习(二)

一、机械臂及运动学 1.1 机械臂构成 机械臂多采用关节式机械结构,一般具有6个自由度,其中3个用来确定末端执行器的位置,另外3个则用来确定末端执行装置的方向(姿态)。   如图所示,一个机械臂是由一组可做相对运动的关节连接的连…

Spring中Bean的作用域、实例化方式、生命周期、循环依赖问题

Spring中Bean的作用域、实例化方式、生命周期、循环依赖问题 一、Bean的作用域1.singleton2.prototype3.其他scope值 二、Bean的实例化方式1.通过构造方法实例化2.通过简单工厂模式实例化3.通过factory-bean实例化4.通过FactoryBean接口实例化5.BeanFactory和FactoryBean的区别…

http【详解】状态码,方法,接口设计 —— RestfuI API,头部 —— headers,缓存

http 状态码 1xx 服务器收到请求 2xx 请求成功 200 成功 3xx 重定向(目标服务器返回另一个服务器的地址,浏览器会自动去访问另一个服务器) 常见应用场景:搜索引擎,短网址 301 永久重定向 (常用于已停服的…

05-prometheus的联邦模式-分布式监控

一、联邦模式概述 1,架构介绍 由于,在大型企业中,被监控项目比较多,多到一台prometheus服务无法承载其大量的监控数据的传输,所以,联邦模式应运而生,它同等于zabbix监控的分布式,就…

Web前端---表格和表单

1.表格概述 表格标记&#xff1a;<table></table> 表格标题标记&#xff1a;<caption></caption> 表头&#xff1a;<th></th>------heading 行标记&#xff1a;<tr></tr>-----r是row 列标记&#xff1a;<td></t…

2024年计算语言学与自然语言处理国际会议(CLNLP 2024) | Ei、Scopus双检索

会议简介 Brief Introduction 2024年计算语言学与自然语言处理国际会议(CLNLP 2024) 会议时间&#xff1a;2024年7月19日-21日 召开地点&#xff1a;中国银川 大会官网&#xff1a;www.clnlp.org CLNLP 2024将围绕“计算语言学与自然语言处理”的最新研究领域而展开&#xff0c…

用FPGA CORDIC IP核实现信号的相位检测,计算相位角

用FPGA CORDIC IP核实现信号的相位检测 1.matlab仿真 波形仿真代码&#xff1a; 代码功能&#xff1a;生成一个点频信号s&#xff0c;求出s的实部和虚部&#xff1b;并且结算相位角atan2。画出图形&#xff0c;并且将Q和I数据写入文件中。 %代码功能&#xff1a;生成一个点…

Linux 之一:Linux 简介、客户端、安装

Linux简介 Linux 内核最初只是由芬兰人林纳斯托瓦兹&#xff08;Linus Torvalds&#xff09;在赫尔辛基大学上学时出于个人爱好而编写的。 Linux&#xff0c;全称GNU/Linux&#xff0c;是一种免费使用和自由传播的类UNIX操作系统&#xff0c;其内核由林纳斯本纳第克特托瓦兹于…

Java 反射详解:动态创建实例、调用方法和访问字段

“一般情况下&#xff0c;我们在使用某个类之前已经确定它到底是个什么类了&#xff0c;拿到手就直接可以使用 new 关键字来调用构造方法进行初始化&#xff0c;之后使用这个类的对象来进行操作。” Writer writer new Writer(); writer.setName("少年");像上面这个…

HTTP常用状态码详解

目录 1xx - 信息性状态码 2xx - 成功状态码 3xx - 重定向状态码 4xx - 客户端错误状态码 5xx - 服务器错误状态码 总结 HTTP&#xff08;Hypertext Transfer Protocol&#xff09;是一种用于传输超文本的应用层协议。在HTTP通信中&#xff0c;服务器和客户端之间会通过状态…

使用华为云云函数functiongraph

之前使用腾讯云serverless&#xff0c;但是突然开始收费了。所以改用functiongraph 首先登陆华为云。 目录 1.登录华为云 2.在控制台找到functiongraph并开通 3.添加依赖包&#xff1a; 3.1 制作依赖包 3.2引入依赖包 4.发送请求 4.1直接发送 4.1.1uri 4.1.2 请求头…

使用word写论文或项目书时,插入图片显示不完整或随文字移动解决办法

一、背景 虽然我们写科技论文时可以用Latex进行排版&#xff0c;但在写项目书或硕士论文时&#xff0c;一般给的模板都是word类型&#xff0c;所以我们还是不能放弃word的使用。但在word中插入图片时&#xff0c;会出现图片显示不完整情况&#xff0c;如下图所示&#xff0c;具…

单调队列(347. 前 K 个高频元素239. 滑动窗口最大值)

单调队列和单调栈其实差不多,就是维护一个区间单调的队列或者是栈,单调队列就是我们所说的大顶堆小顶堆, //升序队列 小顶堆 great 小到大 priority_queue <int,vector<int>,greater<int> > pri_que; //降序队列 大顶堆 less 大到小 默认 priority_qu…

xss.haozi.me:0x01

<textarea></textarea> 标签是不可以写入javascript代码的 所以我们要把textarea标签给闭合掉 这样就成功了 </textarea><script>alert(1)</script>

【Java设计模式】四、原型设计模式

文章目录 1、原型设计模式2、深克隆和浅克隆 1、原型设计模式 说明&#xff1a; 用一个原型对象&#xff0c;创建和原型对象相同的对象&#xff0c;以能够保证创建对象的性能是创建大量相同对象的最佳方式 使用场景&#xff1a; 对象的创建非常复杂&#xff0c;可以使用原型…

神经网络结构——CNN、RNN、LSTM、Transformer !!

文章目录 前言 一、什么是CNN 网络结构 解决问题 工作原理 实际应用 二、什么是RNN 网络结构 解决问题 工作原理 应用场景 三、什么是LSTM 网络结构 解决问题 工作原理 应用场景 四、什么是Transformer 网络结构 解决问题 工作原理 BERT GPT 前言 本文将从什么是CNN&#xff1…

使用 Footprint Analytics 提升 Web3 项目的空投活动

作者&#xff1a;stellafootprint.network 空投已成为 Web3 项目提升知名度、激励早期贡献者并吸引新用户的核心策略。尽管空投的概念一目了然——即向各类钱包免费发放代币&#xff0c;但要成功实施却需要周密的执行和战略规划。单纯的代币分发并非万全之策。在许多的空投后&a…
最新文章