PaddleOCR简介

PaddleOCR分为文本检测、文本识别和方向分类器三部分,其中文本检测有三个模型,分别是MobileNetV3、ResNet18_vd和ResNet50,其中最常使用的是MobileNetV3模型,整体比较小,适合应用于手机端。文本识别只有一个MobileNetV3预训练模型。方向分类器使用默认的模型。

环境配置

PaddleOCR2.0的配置环境

PaddleOCR2.0的配置环境为:

  • PaddlePaddle 2.0.0
  • Python 3.7
  • glibc 2.23
  • cuDNN 7.6+(GPU)

其中,PaddlePaddle可以使用2.0.*

Docker

如果使用docker运行,可以直接使用paddlepaddle/paddle:2.0.1-gpu-cuda11.0-cudnn8镜像,根据个人使用习惯,可以更换,但是paddlepaddle的版本和cudnn版本不能低于PaddleOCR2.0的配置环境。

数据集

其中,文本检测和文本识别使用的都是icdar2015数据集,方向分类器的数据集需自备

icdar2015数据集可以从官网下载,首次下载需注册。

文本检测

文本检测的icdar2015数据集的标注文件下载:

wget -P ./train_data/  https://paddleocr.bj.bcebos.com/dataset/train_icdar2015_label.txt
wget -P ./train_data/  https://paddleocr.bj.bcebos.com/dataset/test_icdar2015_label.txt

也可以使用PaddleOCR提供的数据格式转换脚本,将官网的label转换为支持的数据格式。转换数据工具为ppocr/utils/gen_label.py

# 将官网下载的标签文件转换为 train_icdar2015_label.txt
python gen_label.py --mode="det" --root_path="icdar_c4_train_imgs/"  \
                    --input_path="ch4_training_localization_transcription_gt" \
                    --output_label="train_icdar2015_label.txt"

解压数据集和下载标注文件后,放在PaddleOCR/train_data文件中,文件目录为:

/PaddleOCR/train_data/icdar2015/text_localization/
  └─ icdar_c4_train_imgs/         icdar数据集的训练数据
  └─ ch4_test_images/             icdar数据集的测试数据
  └─ train_icdar2015_label.txt    icdar数据集的训练标注
  └─ test_icdar2015_label.txt     icdar数据集的测试标注

如果不按照这个格式,需要在后面的配置文件中配置

使用自己的数据集

标注文件格式如下,中间用"\t"分隔:

" 图像文件名                    json.dumps编码的图像标注信息"
ch4_test_images/img_61.jpg    [{"transcription": "MASA", "points": [[310, 104], [416, 141], [418, 216], [312, 179]]}, {...}]

json.dumps编码前的图像标注信息是包含多个字典的list,字典中的 points 表示文本框的四个点的坐标(x, y),从左上角的点开始顺时针排列。 transcription 表示当前文本框的文字,当其内容为“###”时,表示该文本框无效,在训练时会跳过。

如果您想在其他数据集上训练,可以按照上述形式构建标注文件

文本识别

文本识别的数据集也可以参考DTRB,下载benchmark所需的lmdb格式数据集。如果希望复现SRN的论文标准,需要下载离线增广数据,提取码: y3ry。增广数据是由MJSynth和SynthText做旋转和扰动得到的。数据下载完成后请解压到 {your_path}/PaddleOCR/train_data/data_lmdb_release/training/ 路径下。

PaddleOCR提供了一份用于训练icdar2015数据集的标签文件:

# 训练集标签
wget -P ./train_data/ic15_data  https://paddleocr.bj.bcebos.com/dataset/rec_gt_train.txt
# 测试集标签
wget -P ./train_data/ic15_data  https://paddleocr.bj.bcebos.com/dataset/rec_gt_test.txt

PaddleOCR也提供了数据格式转换文本,可以将官网label转换支持的数据格式。数据转换工具在ppocr/utils/gen_label.py

# 将官网下载的标签文件转换为 rec_gt_label.txt
python gen_label.py --mode="rec" --input_path="{path/of/origin/label}" --output_label="rec_gt_label.txt"
使用自己的数据集

默认请将图片路径和图片标签用 \t 分割,如用其他方式分割将造成训练报错。

" 图像文件名                 图像标注信息 "

train_data/train_0001.jpg   简单可依赖
train_data/train_0002.jpg   用科技让复杂的世界更简单

最终训练集的文件结构为:

|-train_data
    |-ic15_data
        |- rec_gt_train.txt
        |- train
            |- word_001.png
            |- word_002.jpg
            |- word_003.jpg
            | ...

测试集的文件结构为:

|-train_data
    |-ic15_data
        |- rec_gt_test.txt
        |- test
            |- word_001.jpg
            |- word_002.jpg
            |- word_003.jpg
            | ...
字典

文本检测与文本识别相比还需要一个字典文件({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/utils/dict/french_dict.txt 是一个包含118个字符的法文字典

ppocr/utils/dict/japan_dict.txt 是一个包含4399个字符的日文字典

ppocr/utils/dict/korean_dict.txt 是一个包含3636个字符的韩文字典

ppocr/utils/dict/german_dict.txt 是一个包含131个字符的德文字典

ppocr/utils/dict/en_dict.txt 是一个包含63个字符的英文字典

您可以按需使用。

目前的多语言模型仍处在demo阶段,会持续优化模型并补充语种。

自定义字典

如需自定义dic文件,请在 configs/rec/rec_icdar15_train.yml 中添加 character_dict_path 字段, 指向您的字典路径。 并将 character_type 设置为 ch

添加空格类别

如果希望支持识别"空格"类别, 请将yml文件中的 use_space_char 字段设置为 True

文本角度分类

请按如下步骤设置数据集:

训练数据的默认存储路径是 PaddleOCR/train_data/cls,如果您的磁盘上已有数据集,只需创建软链接至数据集目录:

ln -sf <path/to/dataset> <path/to/paddle_ocr>/train_data/cls/dataset

请参考下文组织您的数据。

  • 训练集

首先请将训练图片放入同一个文件夹(train_images),并用一个txt文件(cls_gt_train.txt)记录图片路径和标签。

注意: 默认请将图片路径和图片标签用 \t 分割,如用其他方式分割将造成训练报错

0和180分别表示图片的角度为0度和180度

" 图像文件名                 图像标注信息 "
train/word_001.jpg   0
train/word_002.jpg   180

最终训练集应有如下文件结构:

|-train_data
    |-cls
        |- cls_gt_train.txt
        |- train
            |- word_001.png
            |- word_002.jpg
            |- word_003.jpg
            | ...
  • 测试集

同训练集类似,测试集也需要提供一个包含所有图片的文件夹(test)和一个cls_gt_test.txt,测试集的结构如下所示:

|-train_data
    |-cls
        |- cls_gt_test.txt
        |- test
            |- word_001.jpg
            |- word_002.jpg
            |- word_003.jpg
            | ...

文本检测

训练

模型准备

首先下载模型backbone的pretrain model,PaddleOCR的检测模型目前支持两种backbone,分别是MobileNetV3、ResNet_vd系列, 您可以根据需求使用PaddleClas中的模型更换backbone。

cd PaddleOCR/
# 下载MobileNetV3的预训练模型
wget -P ./pretrain_models/ https://paddle-imagenet-models-name.bj.bcebos.com/MobileNetV3_large_x0_5_pretrained.tar
# 或,下载ResNet18_vd的预训练模型
wget -P ./pretrain_models/ https://paddle-imagenet-models-name.bj.bcebos.com/ResNet18_vd_pretrained.tar
# 或,下载ResNet50_vd的预训练模型
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
  └─ ......
启动训练
# 单机单卡训练 mv3_db 模型
python3 tools/train.py -c configs/det/det_mv3_db.yml \
     -o Global.pretrain_weights=./pretrain_models/MobileNetV3_large_x0_5_pretrained/
# 单机多卡训练,通过 --gpus 参数设置使用的GPU ID
python3 -m paddle.distributed.launch --gpus '0,1,2,3' tools/train.py -c configs/det/det_mv3_db.yml \
     -o Global.pretrain_weights=./pretrain_models/MobileNetV3_large_x0_5_pretrained/

如果安装的是cpu版本,请将配置文件中的use_gpu字段修改为false

训练参数

  • -m 配置paddle

    • –gpus 使用的GPU
  • -c 选择配置文件

  • -o 配置配置文件中的内容

    • pretrain_weights: 使用的模型目录
    • Optimizer.base_lr: 训练时的学习率
断点训练

如果训练程序中断,如果希望加载训练中断的模型从而恢复训练,可以通过指定Global.checkpoints指定要加载的模型路径(如./output/det_r50_vd/latest):

python3 tools/train.py -c configs/det/det_mv3_db.yml -o Global.checkpoints=./output/det_mv3_vd/latest

注意Global.checkpoints的优先级高于Global.pretrain_weights的优先级,即同时指定两个参数时,优先加载Global.checkpoints指定的模型,如果Global.checkpoints指定的模型路径有误,会加载Global.pretrain_weights指定的模型。

指标评估

PaddleOCR计算三个OCR检测相关的指标,分别是:Precision、Recall、Hmean。

运行如下代码,根据配置文件det_db_mv3.ymlsave_res_path指定的测试集检测结果文件,计算评估指标。

评估时设置后处理参数box_thresh=0.5unclip_ratio=1.5,使用不同数据集、不同模型训练,可调整这两个参数进行优化 训练中模型参数默认保存在Global.save_model_dir目录下。在评估指标时,需要设置Global.pretrained_model指向保存的参数文件。

python3 tools/eval.py -c configs/det/det_mv3_db.yml  -o Global.pretrained_model="./output/det_mv3_vd/best_accuracy" PostProcess.box_thresh=0.5 PostProcess.unclip_ratio=1.5
  • 注:box_threshunclip_ratio是DB后处理所需要的参数,在评估EAST模型时不需要设置

测试检测效果

测试单张图像的检测效果

python3 tools/infer_det.py -c configs/det/det_mv3_db.yml -o Global.infer_img="./doc/imgs_en/img_10.jpg" Global.pretrained_model="./output/det_db/best_accuracy" Global.load_static_weights=false

测试DB模型时,调整后处理阈值,

python3 tools/infer_det.py -c configs/det/det_mv3_db.yml -o Global.infer_img="./doc/imgs_en/img_10.jpg" Global.pretrained_model="./output/det_db/best_accuracy" Global.load_static_weights=false PostProcess.box_thresh=0.6 PostProcess.unclip_ratio=1.5

测试文件夹下所有图像的检测效果

python3 tools/infer_det.py -c configs/det/det_mv3_db.yml -o Global.infer_img="./doc/imgs_en/" Global.pretrained_model="./output/det_db/best_accuracy" Global.load_static_weights=false

文本识别

启动训练

PaddleOCR提供了训练脚本、评估脚本和预测脚本,本节将以 CRNN 识别模型为例:

首先下载pretrain model,您可以下载训练好的模型在 icdar2015 数据上进行finetune

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

开始训练:

如果您安装的是cpu版本,请将配置文件中的 use_gpu 字段修改为false

# GPU训练 支持单卡,多卡训练,通过--gpus参数指定卡号
# 训练icdar15英文数据 训练日志会自动保存为 "{save_model_dir}" 下的train.log
python3 -m paddle.distributed.launch --gpus '0,1,2,3'  tools/train.py -c configs/rec/rec_icdar15_train.yml
  • 数据增强

PaddleOCR提供了多种数据增强方式,如果您希望在训练时加入扰动,请在配置文件中设置 distort: true

默认的扰动方式有:颜色空间转换(cvtColor)、模糊(blur)、抖动(jitter)、噪声(Gasuss noise)、随机切割(random crop)、透视(perspective)、颜色反转(reverse)。

训练过程中每种扰动方式以50%的概率被选择,具体代码实现请参考:img_tools.py

由于OpenCV的兼容性问题,扰动操作暂时只支持Linux

  • 训练

PaddleOCR支持训练和评估交替进行, 可以在 configs/rec/rec_icdar15_train.yml 中修改 eval_batch_step 设置评估频率,默认每500个iter评估一次。评估过程中默认将最佳acc模型,保存为 output/rec_CRNN/best_accuracy

如果验证集很大,测试将会比较耗时,建议减少评估次数,或训练完再进行评估。

其他模型配置请参考PaddleOCR github

评估

评估数据集可以通过 configs/rec/rec_icdar15_train.yml 修改Eval中的 label_file_path 设置。

# GPU 评估, Global.pretrained_model 为待测权重
python3 -m paddle.distributed.launch --gpus '0' tools/eval.py -c configs/rec/rec_icdar15_train.yml -o Global.pretrained_model={path/to/weights}/best_accuracy
预测
  • 训练引擎的预测

使用 PaddleOCR 训练好的模型,可以通过以下脚本进行快速预测。

默认预测图片存储在 infer_img 里,通过 -o Global.pretrained_model 指定权重:

# 预测英文结果
python3 tools/infer_rec.py -c configs/rec/rec_icdar15_train.yml -o Global.pretrained_model={path/to/weights}/best_accuracy Global.load_static_weights=false Global.infer_img=doc/imgs_words/en/word_1.png

预测使用的配置文件必须与训练一致,如您通过 python3 tools/train.py -c configs/rec/ch_ppocr_v2.0/rec_chinese_lite_train_v2.0.yml 完成了中文模型的训练, 您可以使用如下命令进行中文模型预测。

# 预测中文结果
python3 tools/infer_rec.py -c configs/rec/ch_ppocr_v2.0/rec_chinese_lite_train_v2.0.yml -o Global.pretrained_model={path/to/weights}/best_accuracy Global.load_static_weights=false Global.infer_img=doc/imgs_words/ch/word_1.jpg

文本角度分类

训练

启动训练

将准备好的txt文件和图片文件夹路径分别写入配置文件的 Train/Eval.dataset.label_file_listTrain/Eval.dataset.data_dir 字段下,Train/Eval.dataset.data_dir字段下的路径和文件里记载的图片名构成了图片的绝对路径。

PaddleOCR提供了训练脚本、评估脚本和预测脚本。

开始训练:

如果您安装的是cpu版本,请将配置文件中的 use_gpu 字段修改为false

# GPU训练 支持单卡,多卡训练,通过 '--gpus' 指定卡号。
# 启动训练,下面的命令已经写入train.sh文件中,只需修改文件里的配置文件路径即可
python3 -m paddle.distributed.launch --gpus '0,1,2,3,4,5,6,7'  tools/train.py -c configs/cls/cls_mv3.yml
数据增强

PaddleOCR提供了多种数据增强方式,如果您希望在训练时加入扰动,请在配置文件中取消Train.dataset.transforms下的RecAugRandAugment字段的注释。

默认的扰动方式有:颜色空间转换(cvtColor)、模糊(blur)、抖动(jitter)、噪声(Gasuss noise)、随机切割(random crop)、透视(perspective)、颜色反转(reverse),随机数据增强(RandAugment)。

训练过程中除随机数据增强外每种扰动方式以50%的概率被选择,具体代码实现请参考: rec_img_aug.py randaugment.py

由于OpenCV的兼容性问题,扰动操作暂时只支持linux

训练

PaddleOCR支持训练和评估交替进行, 可以在 configs/cls/cls_mv3.yml 中修改 eval_batch_step 设置评估频率,默认每1000个iter评估一次。训练过程中将会保存如下内容:

├── best_accuracy.pdopt # 最佳模型的优化器参数
├── best_accuracy.pdparams # 最佳模型的参数
├── best_accuracy.states # 最佳模型的指标和epoch等信息
├── config.yml # 本次实验的配置文件
├── latest.pdopt # 最新模型的优化器参数
├── latest.pdparams # 最新模型的参数
├── latest.states # 最新模型的指标和epoch等信息
└── train.log # 训练日志

如果验证集很大,测试将会比较耗时,建议减少评估次数,或训练完再进行评估。

注意,预测/评估时的配置文件请务必与训练一致

评估

评估数据集可以通过修改configs/cls/cls_mv3.yml文件里的Eval.dataset.label_file_list 字段设置。

export CUDA_VISIBLE_DEVICES=0
# GPU 评估, Global.checkpoints 为待测权重
python3 tools/eval.py -c configs/cls/cls_mv3.yml -o Global.checkpoints={path/to/weights}/best_accuracy

预测

  • 训练引擎的预测

使用 PaddleOCR 训练好的模型,可以通过以下脚本进行快速预测。

通过 Global.infer_img 指定预测图片或文件夹路径,通过 Global.checkpoints 指定权重:

# 预测分类结果
python3 tools/infer_cls.py -c configs/cls/cls_mv3.yml -o Global.pretrained_model={path/to/weights}/best_accuracy Global.load_static_weights=false Global.infer_img=doc/imgs_words/ch/word_1.jpg

配置文件说明

Global

字段用途默认值备注
use_gpu设置代码是否在gpu运行true\
epoch_num最大训练epoch数500\
log_smooth_windowlog队列长度,每次打印输出队列里的中间值20\
print_batch_step设置打印log间隔10\
save_model_dir设置模型保存路径output/{算法名称}\
save_epoch_step设置模型保存间隔3\
eval_batch_step设置模型评估间隔2000 或 [1000, 2000]2000 表示每2000次迭代评估一次,[1000, 2000]表示从1000次迭代开始,每2000次评估一次
cal_metric_during_train设置是否在训练过程中评估指标,此时评估的是模型在当前batch下的指标true\
load_static_weights设置预训练模型是否是静态图模式保存(目前仅检测算法需要)true\
pretrained_model设置加载预训练模型路径./pretrain_models/CRNN/best_accuracy\
checkpoints加载模型参数路径None用于中断后加载参数继续训练
use_visualdl设置是否启用visualdl进行可视化log展示False教程地址
infer_img设置预测图像路径或文件夹路径./infer_img|
character_dict_path设置字典路径./ppocr/utils/ppocr_keys_v1.txt\
max_text_length设置文本最大长度25\
character_type设置字符类型chen/ch, en时将使用默认dict,ch时使用自定义dict
use_space_char设置是否识别空格True仅在 character_type=ch 时支持空格
label_list设置方向分类器支持的角度[‘0’,‘180’]仅在方向分类器中生效
save_res_path设置检测模型的结果保存地址./output/det_db/predicts_db.txt仅在检测模型中生效

Optimizer (ppocr/optimizer)

字段用途默认值备注
name优化器类名Adam目前支持Momentum,Adam,RMSProp, 见ppocr/optimizer/optimizer.py
beta1设置一阶矩估计的指数衰减率0.9\
beta2设置二阶矩估计的指数衰减率0.999\
clip_norm所允许的二范数最大值\
lr设置学习率decay方式-\
name学习率decay类名Cosine目前支持Linear,Cosine,Step,Piecewise, 见ppocr/optimizer/learning_rate.py
learning_rate基础学习率0.001\
regularizer设置网络正则化方式-\
name正则化类名L2目前支持L1,L2, 见ppocr/optimizer/regularizer.py
factor学习率衰减系数0.00004\

Architecture (ppocr/modeling)

在ppocr中,网络被划分为Transform,Backbone,Neck和Head四个阶段

字段用途默认值备注
model_type网络类型rec目前支持rec,det,cls
algorithm模型名称CRNN支持列表见algorithm_overview
Transform设置变换方式-目前仅rec类型的算法支持, 具体见ppocr/modeling/transform
name变换方式类名TPS目前支持TPS
num_fiducialTPS控制点数20上下边各十个
loc_lr定位网络学习率0.1\
model_name定位网络大小small目前支持small,large
Backbone设置网络backbone类名-具体见ppocr/modeling/backbones
namebackbone类名ResNet目前支持MobileNetV3,ResNet
layersresnet层数34支持18,34,50,101,152,200
model_nameMobileNetV3 网络大小small支持small,large
Neck设置网络neck-具体见ppocr/modeling/necks
nameneck类名SequenceEncoder目前支持SequenceEncoder,DBFPN
encoder_typeSequenceEncoder编码器类型rnn支持reshape,fc,rnn
hidden_sizernn内部单元数48\
out_channelsDBFPN输出通道数256\
Head设置网络Head-具体见ppocr/modeling/heads
namehead类名CTCHead目前支持CTCHead,DBHead,ClsHead
fc_decayCTCHead正则化系数0.0004\
kDBHead二值化系数50\
class_dimClsHead输出分类数2\

Loss (ppocr/losses)

字段用途默认值备注
name网络loss类名CTCLoss目前支持CTCLoss,DBLoss,ClsLoss
balance_lossDBLossloss中是否对正负样本数量进行均衡(使用OHEM)True\
ohem_ratioDBLossloss中的OHEM的负正样本比例3\
main_loss_typeDBLossloss中shrink_map所采用的的lossDiceLoss支持DiceLoss,BCELoss
alphaDBLossloss中shrink_map_loss的系数5\
betaDBLossloss中threshold_map_loss的系数10\

PostProcess (ppocr/postprocess)

字段用途默认值备注
name后处理类名CTCLabelDecode目前支持CTCLoss,AttnLabelDecode,DBPostProcess,ClsPostProcess
threshDBPostProcess中分割图进行二值化的阈值0.3\
box_threshDBPostProcess中对输出框进行过滤的阈值,低于此阈值的框不会输出0.7\
max_candidatesDBPostProcess中输出的最大文本框数量1000
unclip_ratioDBPostProcess中对文本框进行放大的比例2.0\

Metric (ppocr/metrics)

字段用途默认值备注
name指标评估方法名称CTCLabelDecode目前支持DetMetric,RecMetric,ClsMetric
main_indicator主要指标,用于选取最优模型acc对于检测方法为hmean,识别和分类方法为acc

Dataset (ppocr/data)

字段用途默认值备注
dataset每次迭代返回一个样本--
namedataset类名SimpleDataSet目前支持SimpleDataSetLMDBDateSet
data_dir数据集图片存放路径./train_data\
label_file_list数据标签路径["./train_data/train_list.txt"]dataset为LMDBDateSet时不需要此参数
ratio_list数据集的比例[1.0]若label_file_list中有两个train_list,且ratio_list为[0.4,0.6],则从train_list1中采样40%,从train_list2中采样60%组合整个dataset
transforms对图片和标签进行变换的方法列表[DecodeImage,CTCLabelEncode,RecResizeImg,KeepKeys]ppocr/data/imaug
loaderdataloader相关-
shuffle每个epoch是否将数据集顺序打乱True\
batch_size_per_card训练时单卡batch size256\
drop_last是否丢弃因数据集样本数不能被 batch_size 整除而产生的最后一个不完整的mini-batchTrue\
num_workers用于加载数据的子进程个数,若为0即为不开启子进程,在主进程中进行数据加载8

错误解决方案

当文本识别使用ResNet50时,会出现DataLoader reader thread raised an exception!

将配置文件的train loader batch_size_per_card改为8即可

本人博客 https://xiaoxiablogs.top

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐