目录
2.2准备训练的label.txt和测试的label.txt
1.PPOCRLabel标注工具
PPOCRLabel标注工具就在PaddleOCR的github文件夹里面,可以github上的说明进行安装:https://github.com/PaddlePaddle/PaddleOCR/blob/release/2.0/PPOCRLabel/README_ch.md
安装完成之后利用工具对自己的数据集进行标注,标注完成之后主要得到如下内容。
Label.txt:这里面是图片路径名字,以及文字标签和矩形框的四个坐标,用于训练检测模型。注意是所有的图片都放到了一个txt里面,而不是一张图片对应一个txt。
rec_gt.txt:里面是每一个裁剪出来的子图以及对应的文字内容,用于训练识别模型。
crop_img:里面保存的是裁剪出来的子图。
2.训练文本检测模型
2.1准备训练图片数据和测试图片数据
这里我把文本检测训练数据全都放到det_train_images文件夹中,文本检测测试数据放到det_test_images文件夹中。
2.2准备训练的label.txt和测试的label.txt
这里我把训练图片对应的txt命名成det_train_label.txt,测试图片对应的txt命名成det_test_label.txt
2.3下载预训练模型
首先下载模型ba首先下载模型backbone的pretrain model,PaddleOCR的检测模型目前支持两种backbone,分别是MobileNetV3、ResNet50_vd, 您可以根据需求使用PaddleClas中的模型更换backbone。
cd PaddleOCR/
# 下载MobileNetV3的预训练模型
wget -P ./pretrain_models/ https://paddle-imagenet-models-name.bj.bcebos.com/MobileNetV3_large_x0_5_pretrained.tar
# 下载ResNet50的预训练模型
wget -P ./pretrain_models/ https://paddle-imagenet-models-name.bj.bcebos.com/ResNet50_vd_ssld_pretrained.tar
# 解压预训练模型文件,以MobileNetV3为例
tar -xf ./pretrain_models/MobileNetV3_large_x0_5_pretrained.tar ./pretrain_models/
# 注:正确解压backbone预训练权重文件后,文件夹下包含众多以网络层命名的权重文件,格式如下:
./pretrain_models/MobileNetV3_large_x0_5_pretrained/
└─ conv_last_bn_mean
└─ conv_last_bn_offset
└─ conv_last_bn_scale
└─ conv_last_bn_variance
└─ ......
上面如果用wget下载连接不上的话,可以直接把后面的网址复制到浏览器中,在浏览器中下载。
2.4修改配置文件
这里我们以MobileNetV3为例,需要修改configs/det/det_mv3_db.yml文件中的训练数据和测试数据路径为自己的路径,如果是使用的docker环境,那么修改路径的时候要注意修改成docke环境里面的路径。
Train:
dataset:
name: SimpleDataSet
data_dir: /paddle
label_file_list:
- /paddle/det_train_label.txt
2.5开始训练
如果您安装的是cpu版本,请将配置文件中的 use_gpu
字段修改为false。
python3 tools/train.py -c configs/det/det_mv3_db.yml -o Global.pretrain_weights=./pretrain_models/MobileNetV3_large_x0_5_pretrained/
上述指令中,通过-c 选择训练使用configs/det/det_db_mv3.yml配置文件。 有关配置文件的详细解释,请参考链接。
您也可以通过-o参数在不需要修改yml文件的情况下,改变训练的参数,比如,调整训练的学习率为0.0001
python3 tools/train.py -c configs/det/det_mv3_db.yml -o Optimizer.base_lr=0.0001
2.6断点训练
如果训练程序中断,如果希望加载训练中断的模型从而恢复训练,可以通过指定Global.checkpoints指定要加载的模型路径:
python3 tools/train.py -c configs/det/det_mv3_db.yml -o Global.checkpoints=./your/trained/model
注意:Global.checkpoints
的优先级高于Global.pretrain_weights
的优先级,即同时指定两个参数时,优先加载Global.checkpoints
指定的模型,如果Global.checkpoints
指定的模型路径有误,会加载Global.pretrain_weights
指定的模型。
2.7指标评估
python3 tools/eval.py -c configs/det/det_mv3_db.yml -o Global.checkpoints="./output/db_mv3/best_accuracy" PostProcess.box_thresh=0.6 PostProcess.unclip_ratio=1.5
上面的命令在后面的两个PostProcess的前面要加空格,官网教程里面没有空格,会报下面的错误。
Traceback (most recent call last):
File "tools/eval.py", line 70, in <module>
config, device, logger, vdl_writer = program.preprocess()
File "/paddle/PaddleOCR/tools/program.py", line 369, in preprocess
FLAGS = ArgsParser().parse_args()
File "/paddle/PaddleOCR/tools/program.py", line 49, in parse_args
args.opt = self._parse_opt(args.opt)
File "/paddle/PaddleOCR/tools/program.py", line 60, in _parse_opt
k, v = s.split('=')
ValueError: too many values to unpack (expected 2)
2.8测试检测结果
我用官网上给的下面的测试命令时报错:
python3 tools/infer_det.py -c configs/det/det_mv3_db.yml -o TestReader.infer_img="./doc/imgs_en/img_10.jpg" Global.checkpoints="./output/det_db/best_accuracy"
报如下的错误:
Traceback (most recent call last):
File "tools/infer_det.py", line 114, in <module>
config, device, logger, vdl_writer = program.preprocess()
File "/paddle/PaddleOCR/tools/program.py", line 371, in preprocess
merge_config(FLAGS.opt)
File "/paddle/PaddleOCR/tools/program.py", line 115, in merge_config
global_config.keys(), sub_keys[0])
AssertionError: the sub_keys can only be one of global_config: dict_keys(['Global', 'Architecture', 'Loss', 'Optimizer', 'PostProcess', 'Metric', 'Train', 'Eval']), but get: TestReader, please check your running command
大体看了一眼,貌似是不支持TestReader.infer_img="./doc/imgs_en/img_10.jpg"参数,于是我直接修改PaddleOCR/configs/det里面的det_mv3_db.yml配置文件里面的第17行的infer_img: doc/imgs_en/img_10.jpg,
infer_img: doc/imgs_en/img_10.jpg
save_res_path: ./output/det_db/predicts_db.txt
修改完PaddleOCR/configs/det里面的det_mv3_db.yml之后,把测试命令里面的TestReader.infer_img="./doc/imgs_en/img_10.jpg" 去掉。
python3 tools/infer_det.py -c configs/det/det_mv3_db.yml -o Global.checkpoints="./output/db_mv3/best_accuracy"
如果想对文件夹里面的所有图片进行测试,那么修改 PaddleOCR/configs/det里面的det_mv3_db.yml里面的infer_img: doc/imgs_en/img_10.jpg为infer_img: doc/imgs_en/即可。
3.训练文本识别模型
3.1数据准备
我们用PPOCRLable标注完之后会产生相应的子图以及txt文件,txt文件里面每一行是图片路径名字和这张图片的文字内容。
3.2准备字典
最后需要提供一个字典({word_dict_name}.txt),使模型在训练时,可以将所有出现的字符映射为字典的索引。因此字典需要包含所有希望被正确识别的字符,{word_dict_name}.txt需要写成如下格式,并以 utf-8
编码格式保存:
l
d
a
d
r
n
word_dict.txt 每行有一个单字,将字符与数字索引映射在一起,“and” 将被映射成 [2 5 1],ppocr/utils/ppocr_keys_v1.txt
是一个包含6623个字符的中文字典, ppocr/utils/ic15_dict.txt
是一个包含36个字符的英文字典, 这里我把ppocr_keys_v1.txt和ic15_dict.txt合成一个字典,并命名为chw_dict.txt。然后修改
configs/rec/rec_chinese_common_train_v2.0.yml文件中的字典路径为ppocr/utils/chw_dict.txt,
并将 character_type
设置为 ch。然后我们
希望支持识别”空格”类别, 于是将yml文件中的 use_space_char
字段设置为 True
。注意:use_space_char
仅在 character_type=ch
时生效。
# for data or label process
character_dict_path: ppocr/utils/chw_dict.txt
character_type: ch
max_text_length: 25
infer_mode: False
use_space_char: True
3.3下载预训练模型与配置文件
官网使用说明上只有一个模型的下载链接,我直接去github上面下载预训练模型,https://github.com/PaddlePaddle/PaddleOCR/blob/release/2.0/doc/doc_ch/models_list.md#ocr%E6%A8%A1%E5%9E%8B%E5%88%97%E8%A1%A8v202021%E5%B9%B41%E6%9C%8820%E6%97%A5%E6%9B%B4%E6%96%B0
下载自己想要的预训练模型,然后解压放到PaddleOCR/pretrain_models文件夹里面。同时下载对应的配置文件放到PaddleOCR/configs/rec文件夹里面。我这里使用的是rec_chinese_common_train_v2.0.yml以及对应的预训练模型。
中文识别模型
模型名称 | 模型简介 | 配置文件 | 推理模型大小 | 下载地址 |
---|---|---|---|---|
ch_ppocr_mobile_v2.0_rec | 原始超轻量模型,支持中英文、数字识别 | rec_chinese_lite_train_v2.0.yml | 3.71M | 推理模型 / 训练模型 / 预训练模型 |
ch_ppocr_server_v2.0_rec | 通用模型,支持中英文、数字识别 | rec_chinese_common_train_v2.0.yml | 94.8M | 推理模型 / 训练模型 / 预训练模型 |
说明: 训练模型
是基于预训练模型在真实数据与竖排合成文本数据上finetune得到的模型,在真实应用场景中有着更好的表现,预训练模型
则是直接基于全量真实数据与合成数据训练得到,更适合用于在自己的数据集上finetune。
直接基于全量真实数据与合成数据训练得到,更适合用于在自己的数据集上finetune。
英文识别模型
模型名称 | 模型简介 | 配置文件 | 推理模型大小 | 下载地址 |
---|---|---|---|---|
en_number_mobile_v2.0_rec | 原始超轻量模型,支持英文、数字识别 | rec_en_number_lite_train.yml | 2.56M | 推理模型 / 训练模型 |
3.4修改配置文件
需要修改./configs/rec /rec_chinese_common_train_v2.0.yml文件中的训练数据和测试数据路径为自己的路径,如果是使用的docker环境,那么修改路径的时候要注意修改成docke环境里面的路径。
Train:
dataset:
name: SimpleDataSet
data_dir: /paddle
label_file_list: ["/paddle/rec_gt_train.txt"]
transforms:
- DecodeImage: # load image
img_mode: BGR
channel_first: False
- RecAug:
- CTCLabelEncode: # Class handling label
- RecResizeImg:
image_shape: [3, 32, 320]
- KeepKeys:
keep_keys: ['image', 'label', 'length'] # dataloader will return list in this order
loader:
shuffle: True
batch_size_per_card: 256
drop_last: True
num_workers: 8
Eval:
dataset:
name: SimpleDataSet
data_dir: /paddle
label_file_list: ["/paddle/rec_gt_test.txt"]
transforms:
- DecodeImage: # load image
img_mode: BGR
channel_first: False
- CTCLabelEncode: # Class handling label
- RecResizeImg:
image_shape: [3, 32, 320]
- KeepKeys:
keep_keys: ['image', 'label', 'length'] # dataloader will return list in this order
下面是官网说明文档的修改例子:
Global:
...
# 修改 image_shape 以适应长文本
image_shape: [3, 32, 320]
...
# 修改字符类型
character_type: ch
# 添加自定义字典,如修改字典请将路径指向新字典
character_dict_path: ./ppocr/utils/ppocr_keys_v1.txt
# 训练时添加数据增强
distort: true
# 识别空格
use_space_char: true
...
# 修改reader类型
reader_yml: ./configs/rec/rec_chinese_reader.yml
...
...
Optimizer:
...
# 添加学习率衰减策略
decay:
function: cosine_decay
# 每个 epoch 包含 iter 数
step_each_epoch: 20
# 总共训练epoch数
total_epoch: 1000
3.5开始训练
# GPU训练 支持单卡,多卡训练,通过CUDA_VISIBLE_DEVICES指定卡号
export CUDA_VISIBLE_DEVICES=0,1,2,3
# 训练icdar15英文数据
python3 tools/train.py -c configs/rec/rec_chinese_lite_train_v2.0.yml
报错:
2021-03-26 03:19:23,583 - ERROR - DataLoader reader thread raised an exception!
Traceback (most recent call last):
File "tools/train.py", line 124, in <module>
main(config, device, logger, vdl_writer)
File "tools/train.py", line 97, in main
eval_class, pre_best_model_dict, logger, vdl_writer)
File "/paddle/PaddleOCR/tools/program.py", line 201, in train
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/local/lib/python3.7/dist-packages/paddle/fluid/dataloader/dataloader_iter.py", line 684, in _get_data
data = self._data_queue.get(timeout=self._timeout)
File "/usr/lib/python3.7/multiprocessing/queues.py", line 105, in get
raise Empty
_queue.Empty
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/lib/python3.7/threading.py", line 926, in _bootstrap_inner
self.run()
File "/usr/lib/python3.7/threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "/usr/local/lib/python3.7/dist-packages/paddle/fluid/dataloader/dataloader_iter.py", line 616, in _thread_loop
batch = self._get_data()
File "/usr/local/lib/python3.7/dist-packages/paddle/fluid/dataloader/dataloader_iter.py", line 700, in _get_data
"pids: {}".format(len(failed_workers), pids))
RuntimeError: DataLoader 8 workers exit unexpectedly, pids: 74939, 74940, 74941, 74942, 74943, 74944, 74945, 74946
for idx, batch in enumerate(train_dataloader):
File "/usr/local/lib/python3.7/dist-packages/paddle/fluid/dataloader/dataloader_iter.py", line 779, in __next__
data = self._reader.read_next_var_list()
SystemError: (Fatal) Blocking queue is killed because the data reader raises an exception.
[Hint: Expected killed_ != true, but received killed_:1 == true:1.] (at /paddle/paddle/fluid/operators/reader/blocking_queue.h:158)
把 rec_chinese_lite_train_v2.0.yml文件里面的bachsize由256改为64.然后发现还是报错。
Traceback (most recent call last):
File "tools/train.py", line 124, in <module>
main(config, device, logger, vdl_writer)
File "tools/train.py", line 97, in main
eval_class, pre_best_model_dict, logger, vdl_writer)
File "/paddle/PaddleOCR/tools/program.py", line 201, in train
for idx, batch in enumerate(train_dataloader):
File "/usr/local/lib/python3.7/dist-packages/paddle/fluid/dataloader/dataloader_iter.py", line 779, in __next__
data = self._reader.read_next_var_list()
File "/usr/local/lib/python3.7/dist-packages/paddle/fluid/multiprocess_utils.py", line 134, in __handler__
core._throw_error_if_process_failed()
SystemError: (Fatal) DataLoader process (pid 1. If run DataLoader by DataLoader.from_generator(...), queue capacity is set by from_generator(..., capacity=xx, ...).
2. If run DataLoader by DataLoader(dataset, ...), queue capacity is set as 2 times of the max value of num_workers and len(places).
3. If run by DataLoader(dataset, ..., use_shared_memory=True), set use_shared_memory=False for not using shared memory.) exited is killed by signal: 78129.
It may be caused by insufficient shared storage space. This problem usually occurs when using docker as a development environment.
Please use command `df -h` to check the storage space of `/dev/shm`. Shared storage space needs to be greater than (DataLoader Num * DataLoader queue capacity * 1 batch data size).
You can solve this problem by increasing the shared storage space or reducing the queue capacity appropriately.
Bus error (at /paddle/paddle/fluid/imperative/data_loader.cc:161)
从上面的错误提示看,是因为我这里用的是docker环境,然后docker里面的共享内存/dev/shm默认值是64m.
#docker环境中df -h
Filesystem Size Used Avail Use% Mounted on
overlay 3.5T 1.5T 1.9T 44% /
tmpfs 64M 0 64M 0% /dev
tmpfs 252G 0 252G 0% /sys/fs/cgroup
shm 64M 57M 7.6M 89% /dev/shm
/dev/sda2 3.5T 1.5T 1.9T 44% /paddle
tmpfs 252G 12K 252G 1% /proc/driver/nvidia
udev 252G 0 252G 0% /dev/nvidia0
tmpfs 252G 0 252G 0% /proc/acpi
tmpfs 252G 0 252G 0% /proc/scsi
tmpfs 252G 0 252G 0% /sys/firmware
#非docker环境中 df -h
Filesystem Size Used Avail Use% Mounted on
udev 252G 0 252G 0% /dev
tmpfs 51G 2.7M 51G 1% /run
/dev/sda2 3.5T 1.5T 1.9T 44% /
tmpfs 252G 0 252G 0% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 252G 0 252G 0% /sys/fs/cgroup
于是把当前docker容器删掉,然后再次创建docker容器时用--shm-size=252G 指定共享内存大小。
sudo nvidia-docker run --name ppocr -v $PWD:/paddle --shm-size=252G --network=host -itd paddlepaddle/paddle:2.0.1-gpu-cuda11.0-cudnn8 /bin/bash
具体docker命令见:https://blog.csdn.net/u013171226/article/details/115132594,设置完共享内存后,bachsize改回256也不再报错。
3.6评估
python3 tools/eval.py -c ./configs/rec/rec_chinese_lite_train_v2.0.yml -o Global.checkpoints=./output/rec_chinese_lite_v2.0/latest
3.7预测
python3 tools/infer_rec.py -c ./configs/rec/rec_chinese_common_train_v2.0.yml -o Global.checkpoints=./output/rec_chinese_common_v2.0/best_accuracy Global.infer_img=doc/13_crop_4.jpg
参考文献: