可以参考自己以前做过的:
PaddleOCR数字仪表识别——3.(New)PaddleOCR迁移学习
PaddleOCR文字识别的文档:
github.com/PaddlePaddl…
参考PaddleOCR文档(和之前第一次试验的时候差距不大):
github.com/PaddlePaddl…
自己之前的博客:
PaddleOCR数字仪表识别——2(New). textrenderer使用及修改使之符合PaddleOCR数据标准
如果不确定中间那堆空格是不是
\t
,建议使用sublime text查看一下,空格是点点和
\t
(制表符)是一个横线
最后,训练集和测试集的数量是24600:4600张,文件结构和之前的保持一致,如下(文件名和标签之间使用
\t
制表符隔开,制表符的长度可能不那么一致,不影响。)
将数据文件进行压缩,上传(不然通过sublime的SFTP文件夹传非常慢),
将train_data文件夹进行压缩(就是上面那样的文件结构),zip格式
上传至服务器的PaddleOCR文件夹中
unzip train_data.zip
rm
-rf
test
OCR模型列表(这里有大量的预训练模型,是百度自研算法的预训练模型):
github.com/PaddlePaddl…
预训练模型列表(是一些常见算法的预训练模型):
github.com/PaddlePaddl…
从这里下载的内容解压后就是三个文件(符合训练模型和预训练模型,
注意,这里是PaddleOCR1.0版本的模型!
)
配置文件列表(没有特别针对配置文件文件作用的说明,自己看看吧):
github.com/PaddlePaddl…
配置文件参数文档:
github.com/PaddlePaddl…
我的选择以及选择的理由
场景:都是英文、数字、符号,文字长度有限,而且形变不是非常大,从这个角度来说,其实CTC和Attention都可以,但是考虑到Attention存在注意力漂移的问题,还是采用传统的CTC好了。
备选项有以下几个:
配置文件其实看了两个,内容大致相似,比如:
config/rec/multi_languages/rec_en_lite_train.yml
和
configs/rec/ch_ppocr_v1.1/rec_chinese_common_train_v1.1.yml
前者是
en_ppocr_mobile_v1.1_rec 原始超轻量模型,支持英文、数字识别 2M
模型的配置文件,后者是
ch_ppocr_server_v1.1_rec 通用模型,支持中英文、数字识别 105M
的配置文件。
反正先搞起来,多试验试验就好了。
cd PaddleOCR/
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
可以看到,解压完之后有三个文件,
|- rec_r34_vd_none_bilstm_ctc
|- best_accuracy.pdmodel
|- best_accuracy.pdopt
|- best_accuracy.pdparams
github上clone的PaddleOCR本来就有config
文件夹,所以不需要再额外进行下载,需要复制一份,改成自己的。
对应于下载的预训练模型的配置文件是:github.com/PaddlePaddl…
考虑到以前训练配置文件乱改,效果不太好。这次就不乱改了,既然这个预训练模型对应的就是这个配置文件,那就尽量保持一致,改改字典和数据集位置,预训练模型位置就好了。
解释其中一些配置项目:
save_model_dir: ./output/rec/r34_vd_none_bilstm_ctc/
pretrained_model: ./pretrain_models/rec_r34_vd_none_bilstm_ctc/best_accuracy
character_dict_path: ./ppocr/utils/eng.txt
character_type: ch
另外,由于这个预训练模型对应的配置文件采取的读文件方式是IMDBReader,而不是示例中的SimpleReader,参考Windows10制作LMDB详细教程以及What Is Wrong With Scene Text Recognition Model Comparisons? Dataset and Model Analysis,后面这个网站是PaddleOCR下载IMDB类型的dataset的地方,结合以前最开始的imdb格式的mnist数据集,可知这种格式不常用,需要换一个配置文件进行配置。
但是通过比较SimpleReader和IMDBReader,这两者的配置其实差不多,就是路径(数据集的文件组织方式不一样),所以直接将配置文件中读取数据的方式由IMDBReader改为SimpleReader。
Train:
dataset:
name: SimpleDataSet
data_dir: ./train_data/
label_file_list: ["./train_data/train.txt"]
transforms:
- DecodeImage:
img_mode: BGR
channel_first: False
- CTCLabelEncode:
- RecResizeImg:
image_shape: [3, 32, 256]
- KeepKeys:
keep_keys: ['image', 'label', 'length']
loader:
shuffle: True
batch_size_per_card: 256
drop_last: True
num_workers: 8
先测试一下,能不能正确运行,然后再考虑使用screen这个工具将运行放到后台,防止退出ssh之后进程中断。
2020年12月那会还是这样的运行方式
export CUDA_VISIBLE_DEVICES=0
python3.7 tools/train.py -c configs/rec/rec_r34_vd_none_bilstm_ctc.yml 2>&1 | tee train_rec.log
20201年4月已经更新成这个样子了,看架势是多了分布式
python3.7 -m paddle.distributed.launch --gpus '0' tools/train.py -c configs/rec/rec_r34_vd_none_bilstm_ctc.yml
每次都会打印特别多的信息,看着都头疼。。。
使用上述两种运行命令都报错了。都是与cuda相关的错误
Cuda error(100)
,该提示表示没有这个GPU
首先运行在docker中运行nvidia-smi
查看这个docker里有没有cuda,由于我的docker使用的是整个服务器的第三个GPU,所以export CUDA_VISIBLE_DEVICES=3
这里的序号是3,但是从下图可以看到,由于在创建容器时只绑定了一个GPU,虽然在服务器的物理序号是3,但是对于docker容器来说,就是0,所以改为export CUDA_VISIBLE_DEVICES=0
不再报cuda错误,提示
ImportError: No module named 'imgaug'
,然后突然想起来,这个docker里有很多python版本,应该是使用python3.7去运行
似乎没有找到很好的解决方案,只看到了docker容器下的screen:
参考: Persistent screen session inside Docker container
GPU确实比CPU快了许多,很快准确率就很高了。。。
看了下配置文件,就72个epoch,也不是很多。。一些训练的基本信息
训练时间:2021.4.16 15:47到17:38,一个小时差不多。。。真快
准确率变化:最后基本一直在1附近。
最后运行结果可以看下,准确率巨高,也不知道效果咋样,试试吧。
使用 PaddleOCR 训练好的模型,可以通过以下脚本进行快速预测。
默认预测图片存储在 infer_img 里,通过 -o Global.checkpoints 指定权重:
python3.7 tools/infer_rec.py -c configs/rec/rec_r34_vd_none_bilstm_ctc.yml -o Global.checkpoints=pretrain_models/rec_r34_vd_none_bilstm_ctc/best_accuracy Global.infer_img=doc/imgs_words/en/word_1.png
python3.7 tools/infer_rec.py -c configs/rec/rec_r34_vd_none_bilstm_ctc.yml -o Global.checkpoints=output/rec/r34_vd_none_bilstm_ctc/best_accuracy Global.infer_img=train_data/test/EXP1_crop_55.jpg
目前看来,感觉还不错,比直接预测的在符号方面要好一些。
直接使用PaddleOCR可以得到一些结果,使用PaddleOCRLabel也可以得到一些标记结果。
之前直接使用PaddleOCR的wheel来进行预测时,可以看到,其实也是下载了一些模型。在docker中打开这个目录,可以看到
模型文件是这个样子的,比较之前迁移训练/预训练模型的:
考虑进行转换,参考gitee-PaddleOCR-基于Python预测引擎推理或者github-识别模型转inference模型
也就是说,训练后的模型可以转换为推理模型(注意:上面是PaddleOCR2.0的模型)
建议使用的是release2.0
,因为PaddleOCR的wheel使用用的就是2.0方式转换后的推理模型,而默认是develop
版本。
使用如下代码:
python3 tools/export_model.py
-c configs/rec/ch_ppocr_v2.0/rec_chinese_lite_train_v2.0.yml
-o Global.pretrained_model=./ch_lite/ch_ppocr_mobile_v2.0_rec_train/best_accuracy
Global.load_static_weights=False
Global.save_inference_dir=./inference/rec_crnn/
注意:如果是在自己的数据集上训练的模型,并且调整了中文字符的字典文件,请注意修改配置文件中的character_dict_path是否是所需要的字典文件。(还是要注意配置文件配置对!)
我实际使用的转换命令:
python3.7 tools/export_model.py -c configs/rec/rec_r34_vd_none_bilstm_ctc.yml -o Global.pretrained_model=output/rec/r34_vd_none_bilstm_ctc/best_accuracy Global.load_static_weights=False Global.save_inference_dir=./inference/rec_crnn/
转换成功后,可以看到如下三个文件,和PaddleOCR的wheel用的一样,哈哈。
/inference/cls/
├── inference.pdiparams
├── inference.pdiparams.info
└── inference.pdmodel
依然是参考:基于Python预测引擎推理
python3 tools/infer/predict_rec.py
--image_dir="./doc/imgs_words_en/word_336.png"
--rec_model_dir="./your inference model"
--rec_image_shape="3, 32, 100"
--rec_char_type="ch"
--rec_char_dict_path="your text dict path"
尤其要注意,对于自定义文本识别字典,需要通过--rec_char_dict_path
这个参数指定自定义的文本字典路径。
之前在docker中安装好paddleocr的时候使用以下代码测试过
from paddleocr import PaddleOCR, draw_ocr
ocr = PaddleOCR(use_angle_cls=True, lang="ch")
查看PaddleOCR
这个类文件(就在PaddleOCR的一级目录下:PaddleOCR\paddleocr.py
)的定义,主要看其中的parse_args
函数可以知道:
ocr = PaddleOCR(rec_model_dir="PaddleOCR/inference/rec_crnn",
lang="ch",
rec_char_dict_path="PaddleOCR/ppocr/utils/dict/eng.txt",
对比一下,直接用paddleocr的package识别结果
使用迁移训练后的结果,摄氏度符号,括号符号确实有所改善了。
进一步修改一些参数,
关于det_db_unclip_ratio
参数,参考识别模型框出来的位置太紧凑,会丢失边缘的文字信息,导致识别错误
可以在命令中加入 --det_db_unclip_ratio ,参数定义位置,这个参数是检测后处理时控制文本框大小的,默认1.6,可以尝试改成2.5或者更大,反之,如果觉得文本框不够紧凑,也可以把该参数调小。
关于配置文件里面检测的阈值设置么?
det_limit_side_len:预测时图像resize的长边尺寸
det_db_thresh: 用于二值化输出图的阈值
det_db_box_thresh:用于过滤文本框的阈值,低于此阈值的文本框不要
det_db_unclip_ratio: 文本框扩张的系数,关系到文本框的大小
关于文档场景中,使用DB模型会出现整行漏检的情况应该怎么解决?
可以在预测时调小 det_db_box_thresh 阈值,默认为0.5, 可调小至0.3观察效果。
ocr = PaddleOCR(rec_model_dir="PaddleOCR/inference/rec_crnn",
lang="ch",
rec_char_dict_path="PaddleOCR/ppocr/utils/dict/eng.txt",
rec_image_shape="3, 32, 256",
det_db_unclip_ratio=2.5,
det_db_box_thresh=0.7
之前运行都可以正常进行,但是后来stop了一次docker,再start之后去运行,出现
无语,真的是lj,搜到的很多也都无法解决问题,
运行pridict_system文件报错:list index out of range
在进行文本检测、识别串联推理时,出现错误
测试了一下,直接使用以下预测方式还是OK的
python3.7 tools/infer_rec.py -c configs/rec/rec_r34_vd_none_bilstm_ctc.yml -o Global.checkpoints=output/rec/r34_vd_none_bilstm_ctc/best_accuracy Global.infer_img=train_data/test/EXP1_crop_55.jpg
所以问题应该还是出在转换后的模型和词典上,认真看了一下,发现,自己之前的inference生产的地方和paddleOCR目录其实不在一起。
可以通过运行程序时打印的参数,可以看到这个目录其实是相对于根目录,而不是我当前程序运行的目录
所以需要修改正确字符集字典文件的路径以及自己训练的推理模型的路径(我的都是在/ws/PaddleOCR
这个文件夹里,而不是和ws同级的这个PaddleOCR
文件夹)
之前的数据2.4w张,有很多符号,还是字体不太好,不是特别靠近场景字体,可以考虑使用没有符号的字体,专门针对英语数字进行一次训练。
英语大写+小写52个字母,数字10个字母,62个字母,62*500=3.1w张图片,再和之前的2.46w张一起,重新迁移学习一边。