PaddleOCR训练自己的数据集
目录
1.PPOCRLabel标注工具
2.训练文本检测模型
2.1准备训练图片数据和测试图片数据
2.2准备训练的label.txt和测试的label.txt
2.3下载预训练模型
2.4修改配置文件
2.5开始训练
2.6断点训练
2.7指标评估
2.8测试检测结果
3.训练文本识别模型
3.1数据准备
3.2准备字典
3.3下载预训练模型与配置文件
3.4修改配置文件
3.5开始训练
3.6评估
3.7预测
1.PPOCRLabel标注工具
PPOCRLabel注释标记工具位于PaddleOCR内侧的GitHub文件夹中。你可以通过查看官方文档完成安装:https://github.com/PaddlePaddle/PaddleOCR/blob/release/2.0/PPOCRLabel/README_ch.md
在安装完成后借助相关工具对数据集进行标记处理,在标记完成后主要获取了以下信息
在安装完成后通过特定的标注工具对数据集进行标记处理,在标记完成后主要获得了以下数据
在安装完成后运用相应的标注工具对数据集进行标记处理,在标记完成后主要获取了以下信息

这里面包含图片路径名称、文字标签以及矩形框的四个坐标点等信息,并用于训练检测模型。值得注意的是,并非每个图片单独对应一个文本文件而是全部存储在一个文本文件中
rec_gt.txt中包含每个被裁剪出的子图及其对应的文字内容,并旨在用于训练识别模型
crop_img:里面保存的是裁剪出来的子图。
2.训练文本检测模型
2.1准备训练图片数据和测试图片数据
这里我将所有训练样本集归入det_train_images文件夹中存放,并将所有测试样本集归入det_test_images文件夹中存放。
2.2准备训练的label.txt和测试的label.txt
在这里, 我将训练图像的标注文件命名为 det_train_label.txt. 同样地, 在测试阶段的图像标注文件则被命名为 det_test_label.txt.
2.3下载预训练模型
第一步操作:获取模型 backbone 的预训练权重。PaddleOCR 的检测模块目前已配备两种 backbone 选项:MobileNetV3 和 ResNet50_vd。建议您根据具体需求选择并替换 PaddleClas 中的主干网络配置
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修改配置文件
在此案例中说明:为了实现模型的有效训练与验证目标,在配置文件中对训练数据与测试数据的存储位置进行相应的设置至关重要。建议将 configs/det/det_mv3_db.yml 文件中的训练数据和测试数据路径字段赋值为自己的实际存储位置信息,并确保配置参数与模型架构相匹配。特别提醒,在进行 docker 环境配置时,请确保所有相关路径设置均基于 docker 容器内部的逻辑架构完成,并在容器运行状态下验证配置的有效性。
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选项,在无需修改配置文件的情况下进行参数调整。例如,在调整学习率时,请将其设置为0.0001。
python3 tools/train.py -c configs/det/det_mv3_db.yml -o Optimizer.base_lr=0.0001
2.6断点训练
当训练程序出现中断时
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
大致扫了一眼后发现该方法不支持 infer_img 参数设置为 "./doc/imgs_en/img_10.jpg" 的情况。或许是官网说明存在问题,请将命令修改为以下形式。
python3 tools/infer_det.py -c configs/det/det_mv3_db.yml -o Global.checkpoints="./output/det_db/best_accuracy" Global.infer_img="./doc/imgs_en/img_10.jpg"
另外,可以在上面的tools/infer_det.py里面增加代码,把检测出来的子图裁剪出来并保存,增加代码如下(中间为增加的代码,前后是原来的代码):
def draw_det_res(dt_boxes, config, img, img_name):
if len(dt_boxes) > 0:
import cv2
src_im = img
for box in dt_boxes:
box = box.astype(np.int32).reshape((-1, 1, 2))
cv2.polylines(src_im, [box], True, color=(255, 255, 0), thickness=2)
save_det_path = os.path.dirname(config['Global'][
'save_res_path']) + "/det_results/"
if not os.path.exists(save_det_path):
os.makedirs(save_det_path)
save_path = os.path.join(save_det_path, os.path.basename(img_name))
#增加代码把检测出来的图裁剪出子图并保存,
print("-------------------------------------------------------box:", box)
print("box[0][0]:",box[0][0])
print("box[2][0]:",box[2][0])
x1 = box[0][0][0]
x2 = box[2][0][0]
y1 = box[0][0][1]
y2 = box[2][0][1]
print("x1,x2,y1,y2:", x1,x2,y1,y2)
imgSon = img[y1:y2, x1:x2]
debug_path = os.path.splitext(save_path)[0] + "_crop.jpg"
cv2.imwrite(debug_path, imgSon)
cv2.imwrite(save_path, src_im)
logger.info("The detected Image saved in {}".format(save_path))
3.训练文本识别模型
3.1数据准备
我们完成PPOCRLable标注后会生成相应的子图以及txt文件,在这些txt文件中每一条记录都包含图片路径名称及其对应的文字描述。
3.2准备字典
最后必须为模型提供一个映射关系表单体({word_dict_name}.txt),以便模型在训练过程中能够准确识别并对应所有的字符集合。为此必须包含所有希望被正确识别的字符。该文件应按照以下格式编写,并以 UTF-8 编码方式存储:
l
d
a
d
r
n
以下是按照指定规则对原文的改写内容
# 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网站获取相应的文件包;该资源位于...原样保留位置
获取所需的预训练模型后解压至指定目录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 | 推理模型 / 训练模型 / 预训练模型 |
说明:
该模型通过整合高质量真实样本与人工合成的数据进行系统训练后获得,并且特别适合在特定领域开展的细粒度分类任务中进行微调优化。
英文识别模型
| 模型名称 | 模型简介 | 配置文件 | 推理模型大小 | 下载地址 |
|---|---|---|---|---|
| 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容器的话,则需要特别注意将这些路径调整为Docker环境中相应的存储目录,以避免地址冲突并确保程序能够正常运行。
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中将batch_size的值调整为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运行的环境中,默认情况下设置在"/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容器时,请配置共享内存大小为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命令请参考:docker命令_获取镜像,创建容器,启动容器,进入容器,退出容器,停止容器,列出镜像,删除镜像_cumtchw-博客;设置完成后将共享内存大小恢复为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
参考文献:
模型训练与评估 - 文本识别 - 《PaddleOCR 使用教程》 - 书栈网 · BookStack
模型的训练与评估流程 - 文本识别技术 - 作为《PaddleOCR使用教程》的学习资源 - 书栈网 · BookStack
