PaddleOCR数字仪表识别——3.(New)PaddleOCR迁移学习

安装
参考百度PaddleOCR的快速安装,记得提前安装gcc就行。(参考PaddleOCR数字仪表识别——3.paddleocr迁移学习3.1部分)

1. 数据准备

1.1 数据集

参考PaddleOCR数字仪表识别——2(New). textrenderer使用及修改使之符合PaddleOCR数据标准

1.2 字典

PaddleOCR提供了一些默认的字典,位置(PaddleOCR/ppocr/utils/dict/)比如

ppocr/utils/ppocr_keys_v1.txt 是一个包含6623个字符的中文字典,
ppocr/utils/ic15_dict.txt 是一个包含36个字符的英文字典,
ppocr/utils/dict/french_dict.txt 是一个包含118个字符的法文字典
ppocr/utils/dict/japan_dict.txt 是一个包含4399个字符的法文字典

字典的格式也很简单,就是一个txt文件,每行一个字符(会自动 id-char映射)

我的项目只需要进行数字识别,所以字典就是0-9这10个数字。然后把自己的文件放到上面同样的目录里去,这里存在一个坑

根据PaddleOCR Q&A部分
在这里插入图片描述
所以修改字典后,其实就不是迁移学习了,而是重新训练

2. 启动训练

2.1 确定模型和对应的配置文件

之前训练使用的预训练模型是:

模型 骨干网络 Avg Accuracy 模型存储命名
CRNN MobileNetV3 79.37% rec_mv3_none_bilstm_ctc

配置文件用的是:

配置文件 算法名称 backbone trans seq pred
rec_icdar15_train.yml CRNN Mobilenet_v3 large 0.5 None BiLSTM ctc

之前是2400张图,训练了1000次,在测试集上准确率都是1了。

2.1.1 选择的模型

根据 PaddleOCR-算法介绍部分的文档
PaddleOCR数字仪表识别——3.(New)PaddleOCR迁移学习_第1张图片
推荐使用CRNN(考虑到稳定性),还是使用CRNN,CRNN支持的配置文件也最多,这次用下面的这个试试看(骨干网络变了,准确率高了3%左右):

模型 骨干网络 Avg Accuracy 模型存储命名
CRNN Resnet34_vd 82.20% rec_r34_vd_none_bilstm_ctc

下载并解压该模型

cd PaddleOCR/
# 下载MobileNetV3的预训练模型
wget -P ./pretrain_models/ https://paddleocr.bj.bcebos.com/rec_r34_vd_none_bilstm_ctc.tar
# 解压模型参数
cd pretrain_models
tar -xf rec_r34_vd_none_bilstm_ctc.tar && rm -rf rec_r34_vd_none_bilstm_ctc.tar

查看解压后的文件夹,有三个文件

(py37) root@hsh:XXXX$ ls
best_accuracy.pdmodel  best_accuracy.pdopt  best_accuracy.pdparams

2.1.2 选择的配置文件

可选的配置文件有:

配置文件 算法名称 backbone trans seq pred
rec_chinese_common_train_v1.1.yml CRNN ResNet34_vd None BiLSTM ctc
rec_chinese_common_train.yml CRNN ResNet34_vd None BiLSTM ctc
rec_r34_vd_none_bilstm_ctc.yml CRNN Resnet34_vd None BiLSTM ctc

大概看一下三者的区别,确实挺多参数不一样的,选一个和自己最靠近的,这样改的少一点(反正模型都是那个)

参考:PaddleOCR-可选参数列表

最终决定选择rec_chinese_common_train_v1.1.yml这个,因为这个看起来略复杂一点,而且跟我之前使用的配置文件最后学习率那块比较像。

rec_chinese_common_train_v1.1.yml修改后如下
(注意 yml每个字段冒号后面加个空格 再跟着值 )
我这里只训练300轮

Global:
  use_gpu: false
  epoch_num: 300
  save_model_dir: ./output/rec_CRNN_r34
  image_shape: [3, 32, 200]
  eval_batch_step: 500
  max_text_length: 8
  character_dict_path: ./ppocr/utils/num_dict.txt
  distort: false #是否使用数据增强,只有gpu才支持,如果是cpu的话,写true也白搭,还会多给一个warning信息 
  reader_yml: ./configs/rec/rec_chinese_reader.yml
  # reader文件也要修改 后面再改
  pretrain_weights: ./pretrain_models/rec_r34_vd_none_bilstm_ctc/best_accuracy
  total_epoch: 300
  # total_epoch	总共迭代多少个epoch, cosine_decay/cosine_decay_warmup时有效	默认值1000	与Global.epoch_num 一致 

rec_chinese_reader.yml修改后如下

#trainreader
img_set_dir: ./train_data/num_data
label_file_path: ./train_data/num_data_02/train.txt
#evalreader
 img_set_dir: ./train_data/num_data
 label_file_path: ./train_data/num_data_02/test.txt

2.2 训练及评估

2.2.1 训练

> export CPU_NUM=1
> python3 tools/train.py -c configs/rec/ch_ppocr_v1.1/rec_chinese_common_train_v1.1.yml 2>&1 | tee train_rec.log
# 如果要查看完整的训练记录信息可以去这个log文件里看
# 然后再决定使用哪个模型去进行推理/测试

运行第二条命令后,会弹出一大堆提示说明信息
(这个模型比上次的要复杂许多,而且训练数据量翻了五倍。。从2400→10240 虽然训练次数从1000→300,但是每轮训练的时间变长了,从3-5分钟→35分钟,翻了7倍多。。)
出了一个训练结果就证明配置各种都没错,等它自己慢慢跑吧,关了。

然后还是按照之前训练时候使用screen的方式

screen -S train
# 然后在这里执行要训练的脚本
python3 XXX
# 然后
screen -d train #就是把这个会话从attached变成deattached 挂起
# 快捷键是 ctrl+a d 然后会提示类似下面的文字
[detached from 70971.train]
# 之后要恢复到这个会话就是
screen -r train 

# 训练结束要结束这个会话的话 进入这个会话中 输入
exit 

由于训练过程中命令行基本失效(输入无响应),所以还是用快捷键来完成。

快捷键 用途
ctrl+a 切换到之前显示的窗口
Ctrl+a d 暂时断开screen会话

最常用的就是
screen -d XXX挂起XX这个会话
screen -r XXX 恢复XX这个会话

2.2.2 运行过程

PaddleOCR数字仪表识别——3.(New)PaddleOCR迁移学习_第2张图片
速度不是一般的感人,哈哈哈。
PaddleOCR数字仪表识别——3.(New)PaddleOCR迁移学习_第3张图片
我想有台GPU服务器,一天过去了,哈哈哈
PaddleOCR数字仪表识别——3.(New)PaddleOCR迁移学习_第4张图片
两天了,才epoch10.。。。。要30呢,哎。。。但是开始有准确率了
算是个好事吧(希望后面会快一点???)
PaddleOCR数字仪表识别——3.(New)PaddleOCR迁移学习_第5张图片
这个准确率上升的速度,可怕,早知道就不训练300轮了,100轮可能都够了
PaddleOCR数字仪表识别——3.(New)PaddleOCR迁移学习_第6张图片
这个已经很低了。。。。基本可以考虑终止训练了,先把上面那个模型保存一下好了。
一直到epoch 29,acc都是1了,但是loss却慢慢变高了。。。上图可以看到epoch21的时候 loss才40多,但是到了epoch30的时候,loss就变成378多了,开始上升了,,,尴尬
打开目录才发现:原来不是覆盖式的保存,(只有best_accuracy这个文件是覆盖式保存,但是训练的会保存,每3个epoch保存一次 是由这个参数 save_epoch_step 设置模型保存间隔 3 控制的。)
PaddleOCR数字仪表识别——3.(New)PaddleOCR迁移学习_第7张图片
也是按照epoch次数保存的

2.2.3 问题

经过同事大佬指点后,大概发现了问题是:PaddleOCR如果修改了待识别的字符词典,即网络的最后一层分类数被修改,则根据PaddleOCR中的Q&A,其实网络就重新训练了,不是迁移训练了。所以对于CRNN网络,使用几千张图去训练一个模型,很容易就过拟合了,包括这次使用了2w张图片,其实也没差。
因为可以看到,其他那些被公开出来的文字识别模型都是几十万图片训练的。。。

所以要考虑的是:如何使用PaddleOCR实现真正的迁移训练。之后的内容参考
3. 我又来撞南墙了

2.3 预测部署

2.3.1 基于Python脚本预测引擎推理

主要涉及到模型的转换,checkpoint模型转换成inference模型,推理会更快,主要参考PaddleOCR文档-基于Python预测引擎推理

3. 我又来撞南墙了

3.1 心理建设

  • 根据如何评价百度开源的深度学习框架 Paddle?目测下来,给好评的都是白嫖GPU算力和简单使用的,给差评的都是自己用起来不方便的,情况不对就弃坑,期望PaddlePaddle一直在发展。

  • 根据一文带你看懂PaddleHub :paddlehub是支持预训练模型的Fine-Tune的,但是目前官网上支持Fine-Tune的模型里并没有PaddleOCR的。

3.2 挖掘Github信息

  • github-PaddleHub:稍微看了下github上的issue,很多人也反映迁移学习/Fine-Tune的效果很差。。果然还是因为这个是假的迁移学习,其实是重新训练的,数据量小根本满足不了那么复杂的模型。
  • Github上的问题,一个一个检查(百度确实回复的很及时,但是没有解决根本问题,态度是好的,结果。。。。)
    1. 关于识别中预训练模型问题 #910:我的配置文件里指明了预训练模型了,训练的时候也确实读了,但是。。。。前面的层确实是没有冻结,是重新训练的。

    2. 如何对检测模型finetune,比如冻结前面的层或某些层使用小的学习率学习?:这个问题好啊,虽然我还是看不懂,可能要多试试。PaddleOCR数字仪表识别——3.(New)PaddleOCR迁移学习_第8张图片PaddleOCR数字仪表识别——3.(New)PaddleOCR迁移学习_第9张图片

    3. 关于CRNN 识别模型在 icdar2015 数据集训练问题 #1001:反正没有下文了。。

    4. SRN训练从epoch0到epoch1时loss突然变大很多,正常吗?
      #861
      PaddleOCR数字仪表识别——3.(New)PaddleOCR迁移学习_第10张图片

    5. 我用srn的配置文件进行训练,训练acc已经到93,但是验证acc是0,这是怎么回事呢 #853 看了下我的,我训练的测试集到1 训练集0.98了,上面这个哥们可能配置有问题。
      在这里插入图片描述

    6. 如何通过hub serving 的方式使用1.1版本的推理模型? #825PaddleOCR数字仪表识别——3.(New)PaddleOCR迁移学习_第11张图片

    7. 是否可以使用paddlehub的fintune接口对paddleOCR的超轻量模型进行finetune #823:所以这个paddleHub似乎用的人多一些
      PaddleOCR数字仪表识别——3.(New)PaddleOCR迁移学习_第12张图片

    8. 中文训练速度问题#819:这其实就是经验呀,训练样本如果够复杂,就不需要太多的distort数据增强。
      PaddleOCR数字仪表识别——3.(New)PaddleOCR迁移学习_第13张图片

    9. 关于识别率的问题 #787
      PaddleOCR数字仪表识别——3.(New)PaddleOCR迁移学习_第14张图片
      PaddleOCR数字仪表识别——3.(New)PaddleOCR迁移学习_第15张图片

    10. gpu测试和cpu测试结果不一样 #684:这个说到了部署,集成的HubServing

    11. 通用中文识别模型数据问题 #656: 在这里插入图片描述

    12. 未转为inference的识别模型识别效果完美。但一转为inference之后用predict_rec识别就出现大量的nan
      :感觉这几个工程师天天在改BUG,哈哈哈
      PaddleOCR数字仪表识别——3.(New)PaddleOCR迁移学习_第16张图片

    13. 识别训练数据集不平衡问题 #876:所以用这个项目的人里也是有一些大佬的。。。PaddleOCR数字仪表识别——3.(New)PaddleOCR迁移学习_第17张图片

    14. 模型推理生成的图片与正确图不一致 #869:大家的错误真的是可爱
      PaddleOCR数字仪表识别——3.(New)PaddleOCR迁移学习_第18张图片

    15. 模型转换前后效果相差巨大 #862PaddleOCR数字仪表识别——3.(New)PaddleOCR迁移学习_第19张图片

    16. 请问如果我只需要识别出超过图片一定比例的文字, 应该修改模型的那些参数呢 #846:只是需要负责项目的人告诉我们修改相应功能实现的代码在哪里PaddleOCR数字仪表识别——3.(New)PaddleOCR迁移学习_第20张图片PaddleOCR数字仪表识别——3.(New)PaddleOCR迁移学习_第21张图片

    17. How to visual the model structure #845PaddleOCR数字仪表识别——3.(New)PaddleOCR迁移学习_第22张图片

    18. 语义词典纠错 #837::人在解答面对自己花功夫思考的问题时,回复总是详尽可靠的。PaddleOCR数字仪表识别——3.(New)PaddleOCR迁移学习_第23张图片

    19. 【请教】检测和识别面板上的数字效果很差。 #709:这个人的场景和我的很相似,PaddleOCR数字仪表识别——3.(New)PaddleOCR迁移学习_第24张图片

    20. 分别对检测和识别模型进行finetune后,如何使用paddleocr.py文件完成测试呢? #702PaddleOCR数字仪表识别——3.(New)PaddleOCR迁移学习_第25张图片


  • PaddleHub教程合集

  • 目前可以找到的关于PaddleOCR训练的东西:

    • X死路 AI studio-PaddleOCR:中文场景文字识别:这个干的事情基本和我之前一样,只是全部在jupyter上,看起来比我清晰很多,哎。
      • 试试看好了,看在百度提供的GPU上跑一边要多久,然后报错了。。。即便用GPU,算了
    • 惊喜Surprise-Paddle2.0-OCR实现验证码识别(CTC):不是迁移学习,1w长图片,训练出的模型,虽然生产的是验证码图片,但是贵在数量多啊。 虽然验证码图片也是从别人网站爬的,但是给我了一点启发,与其用那个textRenderer,还不如我自己写一个呢,封装可能没那么好,但是起码我改或者加功能都很方便。
      • 自己试了试,感觉还不错 https://aistudio.baidu.com/aistudio/usercenter

感触

Github上的维护人员测试了一些模型,发布上去了,但是用户自己疏忽不按照操作,出了一些需要复现才明白的错误,去问,服务真的是件很难的事情哦。况且神经网络就是黑盒,难道不只能说一些可能的结果吗?

  1. 提问者中文,回复就是中文,提问者英文,回复就是英文,真是难为程序员了。

你可能感兴趣的:(#,OCR数字仪表识别,项目实战)