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文件夹里面,可以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

参考文献:

    https://www.bookstack.cn/read/PaddleOCR/detection.md

    https://www.bookstack.cn/read/PaddleOCR/recognition.md

猜你喜欢

转载自blog.csdn.net/u013171226/article/details/115179480
今日推荐