【人工智能学习之PaddleOCR训练教程】

news2024/10/12 13:43:58

具体的训练教程:

准备数据集

OCR数据集

(以下文字转载官方文档ocr_datasets)

  • 1. 文本检测
    • 1.1 PaddleOCR 文字检测数据格式
    • 1.2 公开数据集
      • 1.2.1 ICDAR 2015
  • 2. 文本识别
    • 2.1 PaddleOCR 文字识别数据格式
    • 2.2 公开数据集
      • 2.1 ICDAR 2015
  • 3. 数据存放路径

这里整理了OCR中常用的公开数据集,持续更新中,欢迎各位小伙伴贡献数据集~

1. 文本检测

1.1 PaddleOCR 文字检测数据格式

PaddleOCR 中的文本检测算法支持的标注文件格式如下,中间用"\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 表示当前文本框的文字,当其内容为“###”时,表示该文本框无效,在训练时会跳过。

如果您想在我们未提供的数据集上训练,可以按照上述形式构建标注文件。

1.2 公开数据集

数据集名称图片下载地址PaddleOCR 标注下载地址
ICDAR 2015https://rrc.cvc.uab.es/?ch=4&com=downloadstrain / test
ctw1500https://paddleocr.bj.bcebos.com/dataset/ctw1500.zip图片下载地址中已包含
total texthttps://paddleocr.bj.bcebos.com/dataset/total_text.tar图片下载地址中已包含
td trhttps://paddleocr.bj.bcebos.com/dataset/TD_TR.tar图片下载地址中已包含
1.2.1 ICDAR 2015

ICDAR 2015 数据集包含1000张训练图像和500张测试图像。ICDAR 2015 数据集可以从上表中链接下载,首次下载需注册。
注册完成登陆后,下载下图中红色框标出的部分,其中, Training Set Images下载的内容保存在icdar_c4_train_imgs文件夹下,Test Set Images 下载的内容保存早ch4_test_images文件夹下

将下载到的数据集解压到工作目录下,假设解压在 PaddleOCR/train_data/下。然后从上表中下载转换好的标注文件。

PaddleOCR 也提供了数据格式转换脚本,可以将官网 label 转换支持的数据格式。 数据转换工具在 ppocr/utils/gen_label.py, 这里以训练集为例:

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

解压数据集和下载标注文件后,PaddleOCR/train_data/ 有两个文件夹和两个文件,按照如下方式组织icdar2015数据集:

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

2. 文本识别

2.1 PaddleOCR 文字识别数据格式

PaddleOCR 中的文字识别算法支持两种数据格式:

  • lmdb 用于训练以lmdb格式存储的数据集,使用 lmdb_dataset.py 进行读取;
  • 通用数据 用于训练以文本文件存储的数据集,使用 simple_dataset.py进行读取。

下面以通用数据集为例, 介绍如何准备数据集:

  • 训练集

建议将训练图片放入同一个文件夹,并用一个txt文件(rec_gt_train.txt)记录图片路径和标签,txt文件里的内容如下:

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

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

train_data/rec/train/word_001.jpg   简单可依赖
train_data/rec/train/word_002.jpg   用科技让复杂的世界更简单
...

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

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

除上述单张图像为一行格式之外,PaddleOCR也支持对离线增广后的数据进行训练,为了防止相同样本在同一个batch中被多次采样,我们可以将相同标签对应的图片路径写在一行中,以列表的形式给出,在训练中,PaddleOCR会随机选择列表中的一张图片进行训练。对应地,标注文件的格式如下。

["11.jpg", "12.jpg"]   简单可依赖
["21.jpg", "22.jpg", "23.jpg"]   用科技让复杂的世界更简单
3.jpg   ocr

上述示例标注文件中,"11.jpg"和"12.jpg"的标签相同,都是简单可依赖,在训练的时候,对于该行标注,会随机选择其中的一张图片进行训练。

  • 验证集

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

|-train_data
  |-rec
    |- rec_gt_test.txt
    |- test
        |- word_001.jpg
        |- word_002.jpg
        |- word_003.jpg
        | ...

2.2 公开数据集

数据集名称图片下载地址PaddleOCR 标注下载地址
en benchmark(MJ, SJ, IIIT, SVT, IC03, IC13, IC15, SVTP, and CUTE.)DTRBLMDB格式,可直接用lmdb_dataset.py加载
ICDAR 2015http://rrc.cvc.uab.es/?ch=4&com=downloadstrain/ test
多语言数据集百度网盘 提取码:frgi
google drive
图片下载地址中已包含
2.1 ICDAR 2015

ICDAR 2015 数据集可以在上表中链接下载,用于快速验证。也可以从上表中下载 en benchmark 所需的lmdb格式数据集。

下载完图片后从上表中下载转换好的标注文件。

PaddleOCR 也提供了数据格式转换脚本,可以将ICDAR官网 label 转换为PaddleOCR支持的数据格式。 数据转换工具在 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"

数据样式格式如下,(a)为原始图片,(b)为每张图片对应的 Ground Truth 文本文件:

3. 数据存放路径

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

# linux and mac os
ln -sf <path/to/dataset> <path/to/paddle_ocr>/train_data/dataset
# windows
mklink /d <path/to/paddle_ocr>/train_data/dataset <path/to/dataset>

文字检测

(以下文字转载官方文档detection)

本节以icdar2015数据集为例,介绍PaddleOCR中检测模型训练、评估、测试的使用方式。

  • 1. 准备数据和模型
    • 1.1 准备数据集
    • 1.2 下载预训练模型
  • 2. 开始训练
    • 2.1 启动训练
    • 2.2 断点训练
    • 2.3 更换Backbone 训练
    • 2.4 混合精度训练
    • 2.5 分布式训练
    • 2.6 知识蒸馏训练
    • 2.7 其他训练环境
    • 2.8 模型微调
  • 3. 模型评估与预测
    • 3.1 指标评估
    • 3.2 测试检测效果
  • 4. 模型导出与预测
  • 5. FAQ

1. 准备数据和模型

1.1 准备数据集

准备数据集可参考 ocr_datasets。

1.2 下载预训练模型

首先下载模型backbone的pretrain model,PaddleOCR的检测模型目前支持两种backbone,分别是MobileNetV3、ResNet_vd系列,
您可以根据需求使用PaddleClas中的模型更换backbone,
对应的backbone预训练模型可以从PaddleClas repo 主页中找到下载链接。

cd PaddleOCR/
# 根据backbone的不同选择下载对应的预训练模型
# 下载MobileNetV3的预训练模型
wget -P ./pretrain_models/ https://paddleocr.bj.bcebos.com/pretrained/MobileNetV3_large_x0_5_pretrained.pdparams
# 或,下载ResNet18_vd的预训练模型
wget -P ./pretrain_models/ https://paddleocr.bj.bcebos.com/pretrained/ResNet18_vd_pretrained.pdparams
# 或,下载ResNet50_vd的预训练模型
wget -P ./pretrain_models/ https://paddleocr.bj.bcebos.com/pretrained/ResNet50_vd_ssld_pretrained.pdparams

2. 开始训练

2.1 启动训练

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

# 单机单卡训练 mv3_db 模型
python3 tools/train.py -c configs/det/det_mv3_db.yml \
     -o Global.pretrained_model=./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.pretrained_model=./pretrain_models/MobileNetV3_large_x0_5_pretrained

上述指令中,通过-c 选择训练使用configs/det/det_mv3_db.yml配置文件。
有关配置文件的详细解释,请参考链接。

您也可以通过-o参数在不需要修改yml文件的情况下,改变训练的参数,比如,调整训练的学习率为0.0001

python3 tools/train.py -c configs/det/det_mv3_db.yml -o Optimizer.base_lr=0.0001

2.2 断点训练

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

python3 tools/train.py -c configs/det/det_mv3_db.yml -o Global.checkpoints=./your/trained/model

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

2.3 更换Backbone 训练

PaddleOCR将网络划分为四部分,分别在ppocr/modeling下。 进入网络的数据将按照顺序(transforms->backbones->
necks->heads)依次通过这四个部分。

├── architectures # 网络的组网代码
├── transforms    # 网络的图像变换模块
├── backbones     # 网络的特征提取模块
├── necks         # 网络的特征增强模块
└── heads         # 网络的输出模块

如果要更换的Backbone 在PaddleOCR中有对应实现,直接修改配置yml文件中Backbone部分的参数即可。

如果要使用新的Backbone,更换backbones的例子如下:

  1. 在 ppocr/modeling/backbones 文件夹下新建文件,如my_backbone.py。
  2. 在 my_backbone.py 文件内添加相关代码,示例代码如下:
import paddle
import paddle.nn as nn
import paddle.nn.functional as F


class MyBackbone(nn.Layer):
    def __init__(self, *args, **kwargs):
        super(MyBackbone, self).__init__()
        # your init code
        self.conv = nn.xxxx

    def forward(self, inputs):
        # your network forward
        y = self.conv(inputs)
        return y
  1. 在 ppocr/modeling/backbones/_init_.py文件内导入添加的MyBackbone模块,然后修改配置文件中Backbone进行配置即可使用,格式如下:
Backbone:
name: MyBackbone
args1: args1

注意:如果要更换网络的其他模块,可以参考文档。

2.4 混合精度训练

如果您想进一步加快训练速度,可以使用自动混合精度训练, 以单机单卡为例,命令如下:

python3 tools/train.py -c configs/det/det_mv3_db.yml \
     -o Global.pretrained_model=./pretrain_models/MobileNetV3_large_x0_5_pretrained \
     Global.use_amp=True Global.scale_loss=1024.0 Global.use_dynamic_loss_scaling=True

注意
文本检测模型使用AMP时可能遇到训练不收敛问题,可以参考discussions中的临时解决方案进行使用。

2.5 分布式训练

多机多卡训练时,通过 --ips 参数设置使用的机器IP地址,通过 --gpus 参数设置使用的GPU ID:

python3 -m paddle.distributed.launch --ips="xx.xx.xx.xx,xx.xx.xx.xx" --gpus '0,1,2,3' tools/train.py -c configs/det/det_mv3_db.yml \
     -o Global.pretrained_model=./pretrain_models/MobileNetV3_large_x0_5_pretrained

注意: (1)采用多机多卡训练时,需要替换上面命令中的ips值为您机器的地址,机器之间需要能够相互ping通;(2)训练时需要在多个机器上分别启动命令。查看机器ip地址的命令为ifconfig;(3)更多关于分布式训练的性能优势等信息,请参考:分布式训练教程。

2.6 知识蒸馏训练

PaddleOCR支持了基于知识蒸馏的检测模型训练过程,更多内容可以参考知识蒸馏说明文档。

注意: 知识蒸馏训练目前只支持PP-OCR使用的DBCRNN算法。

2.7 其他训练环境

  • Windows GPU/CPU
    在Windows平台上与Linux平台略有不同:
    Windows平台只支持单卡的训练与预测,指定GPU进行训练set CUDA_VISIBLE_DEVICES=0
    在Windows平台,DataLoader只支持单进程模式,因此需要设置 num_workers 为0;

  • macOS
    不支持GPU模式,需要在配置文件中设置use_gpu为False,其余训练评估预测命令与Linux GPU完全相同。

  • Linux DCU
    DCU设备上运行需要设置环境变量 export HIP_VISIBLE_DEVICES=0,1,2,3,其余训练评估预测命令与Linux GPU完全相同。

2.8 模型微调

实际使用过程中,建议加载官方提供的预训练模型,在自己的数据集中进行微调,关于检测模型的微调方法,请参考:模型微调教程。

3. 模型评估与预测

3.1 指标评估

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

训练中模型参数默认保存在Global.save_model_dir目录下。在评估指标时,需要设置Global.checkpoints指向保存的参数文件。

python3 tools/eval.py -c configs/det/det_mv3_db.yml  -o Global.checkpoints="{path/to/weights}/best_accuracy"

3.2 测试检测效果

测试单张图像的检测效果:

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"

测试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"  PostProcess.box_thresh=0.6 PostProcess.unclip_ratio=2.0
  • 注:box_threshunclip_ratio是DB后处理参数,其他检测模型不支持。

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

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"

4. 模型导出与预测

inference 模型(paddle.jit.save保存的模型)
一般是模型训练,把模型结构和模型参数保存在文件中的固化模型,多用于预测部署场景。
训练过程中保存的模型是checkpoints模型,保存的只有模型的参数,多用于恢复训练等。
与checkpoints模型相比,inference 模型会额外保存模型的结构信息,在预测部署、加速推理上性能优越,灵活方便,适合于实际系统集成。

检测模型转inference 模型方式:

# 加载配置文件`det_mv3_db.yml`,从`output/det_db`目录下加载`best_accuracy`模型,inference模型保存在`./output/det_db_inference`目录下
python3 tools/export_model.py -c configs/det/det_mv3_db.yml -o Global.pretrained_model="./output/det_db/best_accuracy" Global.save_inference_dir="./output/det_db_inference/"

DB检测模型inference 模型预测:

python3 tools/infer/predict_det.py --det_algorithm="DB" --det_model_dir="./output/det_db_inference/" --image_dir="./doc/imgs/" --use_gpu=True

如果是其他检测,比如EAST模型,det_algorithm参数需要修改为EAST,默认为DB算法:

python3 tools/infer/predict_det.py --det_algorithm="EAST" --det_model_dir="./output/det_db_inference/" --image_dir="./doc/imgs/" --use_gpu=True

更多关于推理超参数的配置与解释,请参考:模型推理超参数解释教程。

5. FAQ

Q1: 训练模型转inference 模型之后预测效果不一致?

A:此类问题出现较多,问题多是trained model预测时候的预处理、后处理参数和inference model预测的时候的预处理、后处理参数不一致导致的。以det_mv3_db.yml配置文件训练的模型为例,训练模型、inference模型预测结果不一致问题解决方式如下:

  • 检查trained model预处理,和inference model的预测预处理函数是否一致。算法在评估的时候,输入图像大小会影响精度,为了和论文保持一致,训练icdar15配置文件中将图像resize到[736, 1280],但是在inference model预测的时候只有一套默认参数,会考虑到预测速度问题,默认限制图像最长边为960做resize的。训练模型预处理和inference模型的预处理函数位于ppocr/data/imaug/operators.py
  • 检查trained model后处理,和inference 后处理参数是否一致。

Q1: 训练EAST模型提示找不到lanms库?

A:执行pip3 install lanms-nova 即可。

文字识别

(以下文字转载官方文档recognition)

本文提供了PaddleOCR文本识别任务的全流程指南,包括数据准备、模型训练、调优、评估、预测,各个阶段的详细说明:

  • 1. 数据准备
    • 1.1. 准备数据集
    • 1.2. 自定义数据集
    • 1.3. 数据下载
    • 1.4. 字典
    • 1.5. 添加空格类别
    • 1.6. 数据增强
  • 2. 开始训练
    • 2.1. 启动训练
    • 2.2. 断点训练
    • 2.3. 更换Backbone 训练
    • 2.4. 混合精度训练
    • 2.5. 分布式训练
    • 2.6. 知识蒸馏训练
    • 2.7. 多语言模型训练
    • 2.8. 其他训练环境
    • 2.9. 模型微调
  • 3. 模型评估与预测
    • 3.1. 指标评估
    • 3.2. 测试识别效果
  • 4. 模型导出与预测
  • 5. FAQ

1. 数据准备

1.1. 准备数据集

PaddleOCR 支持两种数据格式:

  • lmdb 用于训练以lmdb格式存储的数据集(LMDBDataSet);
  • 通用数据 用于训练以文本文件存储的数据集(SimpleDataSet);

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

# linux and mac os
ln -sf <path/to/dataset> <path/to/paddle_ocr>/train_data/dataset
# windows
mklink /d <path/to/paddle_ocr>/train_data/dataset <path/to/dataset>

1.2. 自定义数据集

下面以通用数据集为例, 介绍如何准备数据集:

  • 训练集

建议将训练图片放入同一个文件夹,并用一个txt文件(rec_gt_train.txt)记录图片路径和标签,txt文件里的内容如下:

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

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

train_data/rec/train/word_001.jpg   简单可依赖
train_data/rec/train/word_002.jpg   用科技让复杂的世界更简单
...

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

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

除上述单张图像为一行格式之外,PaddleOCR也支持对离线增广后的数据进行训练,为了防止相同样本在同一个batch中被多次采样,我们可以将相同标签对应的图片路径写在一行中,以列表的形式给出,在训练中,PaddleOCR会随机选择列表中的一张图片进行训练。对应地,标注文件的格式如下。

["11.jpg", "12.jpg"]   简单可依赖
["21.jpg", "22.jpg", "23.jpg"]   用科技让复杂的世界更简单
3.jpg   ocr

上述示例标注文件中,"11.jpg"和"12.jpg"的标签相同,都是简单可依赖,在训练的时候,对于该行标注,会随机选择其中的一张图片进行训练。

  • 验证集

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

|-train_data
  |-rec
    |- rec_gt_test.txt
    |- test
        |- word_001.jpg
        |- word_002.jpg
        |- word_003.jpg
        | ...

1.3. 数据下载

  • ICDAR2015

若您本地没有数据集,可以在官网下载 ICDAR2015 数据,用于快速验证。也可以参考DTRB ,下载 benchmark 所需的lmdb格式数据集。

如果你使用的是icdar2015的公开数据集,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 也提供了数据格式转换脚本,可以将ICDAR官网 label 转换为PaddleOCR支持的数据格式。 数据转换工具在 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"

数据样式格式如下,(a)为原始图片,(b)为每张图片对应的 Ground Truth 文本文件

  • 多语言数据集

多语言模型的训练数据集均为100w的合成数据,使用了开源合成工具 text_renderer ,少量的字体可以通过下面两种方式下载。

  • 百度网盘 提取码:frgi
  • google drive

1.4. 字典

最后需要提供一个字典({word_dict_name}.txt),使模型在训练时,可以将所有出现的字符映射为字典的索引。

因此字典需要包含所有希望被正确识别的字符,{word_dict_name}.txt需要写成如下格式,并以 utf-8 编码格式保存:

l
d
a
d
r
n

word_dict.txt 每行有一个单字,将字符与数字索引映射在一起,“and” 将被映射成 [2 5 1]

  • 内置字典

PaddleOCR内置了一部分字典,可以按需使用。

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/en_dict.txt 是一个包含96个字符的英文字典

目前的多语言模型仍处在demo阶段,会持续优化模型并补充语种,非常欢迎您为我们提供其他语言的字典和字体
如您愿意可将字典文件提交至 dict,我们会在Repo中感谢您。

  • 自定义字典

如需自定义dic文件,请在 configs/rec/PP-OCRv4/en_PP-OCRv4_rec.yml 中添加 character_dict_path 字段, 指向您的字典路径。

1.5. 添加空格类别

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

1.6. 数据增强

PaddleOCR提供了多种数据增强方式,默认配置文件中已经添加了数据增广。

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

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

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

2. 开始训练

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

2.1. 启动训练

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

cd PaddleOCR/
# 下载英文PP-OCRv4的预训练模型
wget -P ./pretrain_models/ https://paddleocr.bj.bcebos.com/PP-OCRv4/english/en_PP-OCRv4_rec_train.tar
# 解压模型参数
cd pretrain_models
tar -xf en_PP-OCRv4_rec_train.tar && rm -rf en_PP-OCRv4_rec_train.tar

开始训练:

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

# GPU训练 支持单卡,多卡训练
# 训练icdar15英文数据 训练日志会自动保存为 "{save_model_dir}" 下的train.log

#单卡训练(训练周期长,不建议)
python3 tools/train.py -c configs/rec/PP-OCRv4/en_PP-OCRv4_rec.yml -o Global.pretrained_model=./pretrain_models/en_PP-OCRv4_rec_train/best_accuracy

#多卡训练,通过--gpus参数指定卡号
python3 -m paddle.distributed.launch --gpus '0,1,2,3'  tools/train.py -c configs/rec/PP-OCRv4/en_PP-OCRv4_rec.yml -o Global.pretrained_model=./pretrain_models/en_PP-OCRv4_rec_train/best_accuracy

正常启动训练后,会看到以下log输出:

[2024/06/16 11:28:26] ppocr INFO: epoch: [1/50], global_step: 10, lr: 0.000007, acc: 0.343750, norm_edit_dis: 0.752802, CTCLoss: 13.178495, NRTRLoss: 1.398275, loss: 14.568232, avg_reader_cost: 0.28627 s, avg_batch_cost: 1.04250 s, avg_samples: 67.2, ips: 64.46042 samples/s, eta: 0:57:09, max_mem_reserved: 12078 MB, max_mem_allocated: 11935 MB
[2024/06/16 11:28:30] ppocr INFO: epoch: [1/50], global_step: 20, lr: 0.000014, acc: 0.361979, norm_edit_dis: 0.764480, CTCLoss: 12.389563, NRTRLoss: 1.389737, loss: 13.795437, avg_reader_cost: 0.00035 s, avg_batch_cost: 0.47960 s, avg_samples: 65.6, ips: 136.78172 samples/s, eta: 0:41:36, max_mem_reserved: 12078 MB, max_mem_allocated: 11949 MB
[2024/06/16 11:28:35] ppocr INFO: epoch: [1/50], global_step: 30, lr: 0.000030, acc: 0.390625, norm_edit_dis: 0.788205, CTCLoss: 10.617269, NRTRLoss: 1.334532, loss: 11.975240, avg_reader_cost: 0.00035 s, avg_batch_cost: 0.48364 s, avg_samples: 78.4, ips: 162.10323 samples/s, eta: 0:36:26, max_mem_reserved: 12078 MB, max_mem_allocated: 11976 MB
[2024/06/16 11:28:40] ppocr INFO: epoch: [1/50], global_step: 40, lr: 0.000045, acc: 0.393229, norm_edit_dis: 0.785400, CTCLoss: 10.627735, NRTRLoss: 1.330406, loss: 11.949156, avg_reader_cost: 0.00036 s, avg_batch_cost: 0.48152 s, avg_samples: 73.6, ips: 152.84850 samples/s, eta: 0:33:47, max_mem_reserved: 12078 MB, max_mem_allocated: 11976 MB
[2024/06/16 11:28:45] ppocr INFO: epoch: [1/50], global_step: 50, lr: 0.000060, acc: 0.401042, norm_edit_dis: 0.804457, CTCLoss: 8.343242, NRTRLoss: 1.220365, loss: 9.561325, avg_reader_cost: 0.00035 s, avg_batch_cost: 0.48413 s, avg_samples: 67.2, ips: 138.80508 samples/s, eta: 0:32:11, max_mem_reserved: 12078 MB, max_mem_allocated: 11976 MB
[2024/06/16 11:28:50] ppocr INFO: epoch: [1/50], global_step: 60, lr: 0.000075, acc: 0.468750, norm_edit_dis: 0.833311, CTCLoss: 7.356572, NRTRLoss: 1.191381, loss: 8.570213, avg_reader_cost: 0.00028 s, avg_batch_cost: 0.47786 s, avg_samples: 68.8, ips: 143.97404 samples/s, eta: 0:31:02, max_mem_reserved: 12078 MB, max_mem_allocated: 11990 MB
[2024/06/16 11:28:53] ppocr INFO: epoch: [1/50], global_step: 66, lr: 0.000084, acc: 0.489583, norm_edit_dis: 0.841231, CTCLoss: 7.246758, NRTRLoss: 1.181412, loss: 8.424673, avg_reader_cost: 0.00018 s, avg_batch_cost: 0.28659 s, avg_samples: 36.8, ips: 128.40797 samples/s, eta: 0:30:30, max_mem_reserved: 12078 MB, max_mem_allocated: 11990 MB

log 中自动打印如下信息:

字段含义
epoch当前迭代轮次
iter当前迭代次数
lr当前学习率
loss当前损失函数
acc当前batch的准确率
norm_edit_dis当前 batch 的编辑距离
reader_cost当前 batch 数据处理耗时
batch_cost当前 batch 总耗时
samples当前 batch 内的样本数
ips每秒处理图片的数量

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

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

提示: 可通过 -c 参数选择 configs/rec/ 路径下的多种模型配置进行训练,PaddleOCR支持的识别算法可以参考前沿算法列表:

训练中文数据,推荐使用ch_PP-OCRv4_rec_distillation.yml,如您希望尝试其他算法在中文数据集上的效果,请参考下列说明修改配置文件:

ch_PP-OCRv4_rec_distillation.yml 为例:

Global:
  ...
  # 添加自定义字典,如修改字典请将路径指向新字典
  character_dict_path: ppocr/utils/ppocr_keys_v1.txt
  ...
  # 识别空格
  use_space_char: True


Optimizer:
  ...
  # 添加学习率衰减策略
  lr:
    name: Cosine
    learning_rate: 0.0005
  ...

...

Train:
  dataset:
    # 数据集格式,支持LMDBDataSet以及SimpleDataSet
    name: SimpleDataSet
    # 数据集路径
    data_dir: ./train_data/
    # 训练集标签文件
    label_file_list: ["./train_data/train_list.txt"]
    transforms:
      ...
      - RecResizeImg:
          # 修改 image_shape 以适应长文本
          image_shape: [3, 48, 320]
      ...
  loader:
    ...
    # 单卡训练的batch_size
    batch_size_per_card: 256
    ...

Eval:
  dataset:
    # 数据集格式,支持LMDBDataSet以及SimpleDataSet
    name: SimpleDataSet
    # 数据集路径
    data_dir: ./train_data
    # 验证集标签文件
    label_file_list: ["./train_data/val_list.txt"]
    transforms:
      ...
      - RecResizeImg:
          # 修改 image_shape 以适应长文本
          image_shape: [3, 48, 320]
      ...
  loader:
    # 单卡验证的batch_size
    batch_size_per_card: 256
    ...

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

2.2. 断点训练

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

python3 tools/train.py -c configs/rec/PP-OCRv4/en_PP-OCRv4_rec.yml -o Global.checkpoints=./your/trained/model

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

2.3. 更换Backbone 训练

PaddleOCR将网络划分为四部分,分别在ppocr/modeling下。 进入网络的数据将按照顺序(transforms->backbones->necks->heads)依次通过这四个部分。

├── architectures # 网络的组网代码
├── transforms    # 网络的图像变换模块
├── backbones     # 网络的特征提取模块
├── necks         # 网络的特征增强模块
└── heads         # 网络的输出模块

如果要更换的Backbone 在PaddleOCR中有对应实现,直接修改配置yml文件中Backbone部分的参数即可。

如果要使用新的Backbone,更换backbones的例子如下:

  1. 在 ppocr/modeling/backbones 文件夹下新建文件,如my_backbone.py。
  2. 在 my_backbone.py 文件内添加相关代码,示例代码如下:
import paddle
import paddle.nn as nn
import paddle.nn.functional as F


class MyBackbone(nn.Layer):
    def __init__(self, *args, **kwargs):
        super(MyBackbone, self).__init__()
        # your init code
        self.conv = nn.xxxx

    def forward(self, inputs):
        # your network forward
        y = self.conv(inputs)
        return y
  1. 在 ppocr/modeling/backbones/_init_.py文件内导入添加的MyBackbone模块,然后修改配置文件中Backbone进行配置即可使用,格式如下:
Backbone:
name: MyBackbone
args1: args1

注意:如果要更换网络的其他模块,可以参考文档。

2.4. 混合精度训练

如果您想进一步加快训练速度,可以使用自动混合精度训练, 以单机单卡为例,命令如下:

python3 tools/train.py -c configs/rec/PP-OCRv4/en_PP-OCRv4_rec.yml \
     -o Global.pretrained_model=./pretrain_models/en_PP-OCRv4_rec_train/best_accuracy \
     Global.use_amp=True Global.scale_loss=1024.0 Global.use_dynamic_loss_scaling=True

2.5. 分布式训练

多机多卡训练时,通过 --ips 参数设置使用的机器IP地址,通过 --gpus 参数设置使用的GPU ID:

python3 -m paddle.distributed.launch --ips="xx.xx.xx.xx,xx.xx.xx.xx" --gpus '0,1,2,3' tools/train.py -c configs/rec/PP-OCRv4/en_PP-OCRv4_rec.yml \
     -o Global.pretrained_model=./pretrain_models/en_PP-OCRv4_rec_train/best_accuracy

注意: (1)采用多机多卡训练时,需要替换上面命令中的ips值为您机器的地址,机器之间需要能够相互ping通;(2)训练时需要在多个机器上分别启动命令。查看机器ip地址的命令为ifconfig;(3)更多关于分布式训练的性能优势等信息,请参考:分布式训练教程。

2.6. 知识蒸馏训练

PaddleOCR支持了基于知识蒸馏的文本识别模型训练过程,更多内容可以参考知识蒸馏说明文档。

2.7. 多语言模型训练

PaddleOCR目前已支持80种(除中文外)语种识别,configs/rec/multi_languages 路径下提供了一个多语言的配置文件模版: rec_multi_language_lite_train.yml。

按语系划分,目前PaddleOCR支持的语种有:

配置文件算法名称backbonetransseqpredlanguage
rec_chinese_cht_lite_train.ymlCRNNMobilenet_v3 small 0.5NoneBiLSTMctc中文繁体
rec_en_lite_train.ymlCRNNMobilenet_v3 small 0.5NoneBiLSTMctc英语(区分大小写)
rec_french_lite_train.ymlCRNNMobilenet_v3 small 0.5NoneBiLSTMctc法语
rec_ger_lite_train.ymlCRNNMobilenet_v3 small 0.5NoneBiLSTMctc德语
rec_japan_lite_train.ymlCRNNMobilenet_v3 small 0.5NoneBiLSTMctc日语
rec_korean_lite_train.ymlCRNNMobilenet_v3 small 0.5NoneBiLSTMctc韩语
rec_latin_lite_train.ymlCRNNMobilenet_v3 small 0.5NoneBiLSTMctc拉丁字母
rec_arabic_lite_train.ymlCRNNMobilenet_v3 small 0.5NoneBiLSTMctc阿拉伯字母
rec_cyrillic_lite_train.ymlCRNNMobilenet_v3 small 0.5NoneBiLSTMctc斯拉夫字母
rec_devanagari_lite_train.ymlCRNNMobilenet_v3 small 0.5NoneBiLSTMctc梵文字母

更多支持语种请参考: 多语言模型

如您希望在现有模型效果的基础上调优,请参考下列说明修改配置文件:

rec_french_lite_train 为例:

Global:
  ...
  # 添加自定义字典,如修改字典请将路径指向新字典
  character_dict_path: ./ppocr/utils/dict/french_dict.txt
  ...
  # 识别空格
  use_space_char: True

...

Train:
  dataset:
    # 数据集格式,支持LMDBDataSet以及SimpleDataSet
    name: SimpleDataSet
    # 数据集路径
    data_dir: ./train_data/
    # 训练集标签文件
    label_file_list: ["./train_data/french_train.txt"]
    ...

Eval:
  dataset:
    # 数据集格式,支持LMDBDataSet以及SimpleDataSet
    name: SimpleDataSet
    # 数据集路径
    data_dir: ./train_data
    # 验证集标签文件
    label_file_list: ["./train_data/french_val.txt"]
    ...

2.8. 其他训练环境

  • Windows GPU/CPU
    在Windows平台上与Linux平台略有不同:
    Windows平台只支持单卡的训练与预测,指定GPU进行训练set CUDA_VISIBLE_DEVICES=0
    在Windows平台,DataLoader只支持单进程模式,因此需要设置 num_workers 为0;

  • macOS
    不支持GPU模式,需要在配置文件中设置use_gpu为False,其余训练评估预测命令与Linux GPU完全相同。

  • Linux DCU
    DCU设备上运行需要设置环境变量 export HIP_VISIBLE_DEVICES=0,1,2,3,其余训练评估预测命令与Linux GPU完全相同。

2.9 模型微调

实际使用过程中,建议加载官方提供的预训练模型,在自己的数据集中进行微调,关于识别模型的微调方法,请参考:模型微调教程。

3. 模型评估与预测

3.1. 指标评估

训练中模型参数默认保存在Global.save_model_dir目录下。在评估指标时,需要设置Global.checkpoints指向保存的参数文件。评估数据集可以通过 configs/rec/PP-OCRv3/en_PP-OCRv3_rec.yml 修改Eval中的 label_file_path 设置。

# GPU 评估, Global.checkpoints 为待测权重
python3 -m paddle.distributed.launch --gpus '0' tools/eval.py -c configs/rec/PP-OCRv4/en_PP-OCRv4_rec.yml -o Global.checkpoints={path/to/weights}/best_accuracy

3.2. 测试识别效果

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

默认预测图片存储在 infer_img 里,通过 -o Global.checkpoints 加载训练好的参数文件:

根据配置文件中设置的 save_model_dirsave_epoch_step 字段,会有以下几种参数被保存下来:

output/rec/
├── best_accuracy.pdopt
├── best_accuracy.pdparams
├── best_accuracy.states
├── config.yml
├── iter_epoch_3.pdopt
├── iter_epoch_3.pdparams
├── iter_epoch_3.states
├── latest.pdopt
├── latest.pdparams
├── latest.states
└── train.log

其中 best_accuracy.* 是评估集上的最优模型;iter_epoch_x.* 是以 save_epoch_step 为间隔保存下来的模型;latest.* 是最后一个epoch的模型。

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

得到输入图像的预测结果:

infer_img: doc/imgs_words/en/word_1.png
        result: ('joint', 0.9998967)

预测使用的配置文件必须与训练一致,如您通过 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.infer_img=doc/imgs_words/ch/word_1.jpg

得到输入图像的预测结果:

infer_img: doc/imgs_words/ch/word_1.jpg
        result: ('韩国小馆', 0.997218)

4. 模型导出与预测

inference 模型(paddle.jit.save保存的模型)
一般是模型训练,把模型结构和模型参数保存在文件中的固化模型,多用于预测部署场景。
训练过程中保存的模型是checkpoints模型,保存的只有模型的参数,多用于恢复训练等。
与checkpoints模型相比,inference 模型会额外保存模型的结构信息,在预测部署、加速推理上性能优越,灵活方便,适合于实际系统集成。

识别模型转inference模型与检测的方式相同,如下:

# -c 后面设置训练算法的yml配置文件
# -o 配置可选参数
# Global.pretrained_model 参数设置待转换的训练模型地址,不用添加文件后缀 .pdmodel,.pdopt或.pdparams。
# Global.save_inference_dir参数设置转换的模型将保存的地址。

python3 tools/export_model.py -c configs/rec/PP-OCRv4/en_PP-OCRv4_rec.yml -o Global.pretrained_model=./pretrain_models/en_PP-OCRv4_rec_train/best_accuracy  Global.save_inference_dir=./inference/en_PP-OCRv4_rec/

**注意:**如果您是在自己的数据集上训练的模型,并且调整了中文字符的字典文件,请注意修改配置文件中的character_dict_path为自定义字典文件。

转换成功后,在目录下有三个文件:

inference/en_PP-OCRv4_rec/
    ├── inference.pdiparams         # 识别inference模型的参数文件
    ├── inference.pdiparams.info    # 识别inference模型的参数信息,可忽略
    └── inference.pdmodel           # 识别inference模型的program文件
  • 自定义模型推理

    如果训练时修改了文本的字典,在使用inference模型预测时,需要通过--rec_char_dict_path指定使用的字典路径,更多关于推理超参数的配置与解释,请参考:模型推理超参数解释教程。

    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, 48, 320" --rec_char_dict_path="your text dict path"
    

5. FAQ

Q1: 训练模型转inference 模型之后预测效果不一致?

A:此类问题出现较多,问题多是trained model预测时候的预处理、后处理参数和inference model预测的时候的预处理、后处理参数不一致导致的。可以对比训练使用的配置文件中的预处理、后处理和预测时是否存在差异。

文本方向分类器

(以下文字转载官方文档angle_class)

  • 1.方法介绍
  • 2.数据准备
  • 3.启动训练
  • 4.训练
  • 5.评估
  • 6.预测

1. 方法介绍

文本方向分类器主要用于图片非0度的场景下,在这种场景下需要对图片里检测到的文本行进行一个转正的操作。在PaddleOCR系统内,
文字检测之后得到的文本行图片经过仿射变换之后送入识别模型,此时只需要对文字进行一个0和180度的角度分类,因此PaddleOCR内置的
文本方向分类器只支持了0和180度的分类。如果想支持更多角度,可以自己修改算法进行支持。

0和180度数据样本例子:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2. 数据准备

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

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

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

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

  • 训练集

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

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

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

" 图像文件名                 图像标注信息 "
train/cls/train/word_001.jpg   0
train/cls/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
            | ...

3. 启动训练

将准备好的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

4. 训练

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 # 训练日志

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

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

5. 评估

评估数据集可以通过修改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

6. 预测

  • 训练引擎的预测

使用 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

得到输入图像的预测结果:

infer_img: doc/imgs_words/ch/word_1.jpg
     result: ('0', 0.9998784)

知识蒸馏

(以下文字转载官方文档knowledge_distillation)

  • 知识蒸馏
    • 1. 简介
      • 1.1 知识蒸馏介绍
      • 1.2 PaddleOCR知识蒸馏简介
    • 2. 配置文件解析
      • 2.1 识别配置文件解析
        • 2.1.1 模型结构
        • 2.1.2 损失函数
        • 2.1.3 后处理
        • 2.1.4 指标计算
        • 2.1.5 蒸馏模型微调
      • 2.2 检测配置文件解析
        • 2.2.1 模型结构
        • 2.2.2 损失函数
        • 2.2.3 后处理
        • 2.2.4 蒸馏指标计算
        • 2.2.5 检测蒸馏模型finetune

1. 简介

1.1 知识蒸馏介绍

近年来,深度神经网络在计算机视觉、自然语言处理等领域被验证是一种极其有效的解决问题的方法。通过构建合适的神经网络,加以训练,最终网络模型的性能指标基本上都会超过传统算法。

在数据量足够大的情况下,通过合理构建网络模型的方式增加其参数量,可以显著改善模型性能,但是这又带来了模型复杂度急剧提升的问题。大模型在实际场景中使用的成本较高。

深度神经网络一般有较多的参数冗余,目前有几种主要的方法对模型进行压缩,减小其参数量。如裁剪、量化、知识蒸馏等,其中知识蒸馏是指使用教师模型(teacher model)去指导学生模型(student model)学习特定任务,保证小模型在参数量不变的情况下,得到比较大的性能提升。

此外,在知识蒸馏任务中,也衍生出了互学习的模型训练方法,论文Deep Mutual Learning中指出,使用两个完全相同的模型在训练的过程中互相监督,可以达到比单个模型训练更好的效果。

1.2 PaddleOCR知识蒸馏简介

无论是大模型蒸馏小模型,还是小模型之间互相学习,更新参数,他们本质上是都是不同模型之间输出或者特征图(feature map)之间的相互监督,区别仅在于 (1) 模型是否需要固定参数。(2) 模型是否需要加载预训练模型。

对于大模型蒸馏小模型的情况,大模型一般需要加载预训练模型并固定参数;对于小模型之间互相蒸馏的情况,小模型一般都不加载预训练模型,参数也都是可学习的状态。

在知识蒸馏任务中,不只有2个模型之间进行蒸馏的情况,多个模型之间互相学习的情况也非常普遍。因此在知识蒸馏代码框架中,也有必要支持该种类别的蒸馏方法。

PaddleOCR中集成了知识蒸馏的算法,具体地,有以下几个主要的特点:

  • 支持任意网络的互相学习,不要求子网络结构完全一致或者具有预训练模型;同时子网络数量也没有任何限制,只需要在配置文件中添加即可。
  • 支持loss函数通过配置文件任意配置,不仅可以使用某种loss,也可以使用多种loss的组合
  • 支持知识蒸馏训练、预测、评估与导出等所有模型相关的环境,方便使用与部署。

通过知识蒸馏,在中英文通用文字识别任务中,不增加任何预测耗时的情况下,可以给模型带来3%以上的精度提升,结合学习率调整策略以及模型结构微调策略,最终提升提升超过5%。

2. 配置文件解析

在知识蒸馏训练的过程中,数据预处理、优化器、学习率、全局的一些属性没有任何变化。模型结构、损失函数、后处理、指标计算等模块的配置文件需要进行微调。

下面以识别与检测的知识蒸馏配置文件为例,对知识蒸馏的训练与配置进行解析。

2.1 识别配置文件解析

配置文件在ch_PP-OCRv3_rec_distillation.yml。

2.1.1 模型结构

知识蒸馏任务中,模型结构配置如下所示。

Architecture:
  model_type: &model_type "rec"    # 模型类别,rec、det等,每个子网络的模型类别
  name: DistillationModel          # 结构名称,蒸馏任务中,为DistillationModel,用于构建对应的结构
  algorithm: Distillation          # 算法名称
  Models:                          # 模型,包含子网络的配置信息
    Teacher:                       # 子网络名称,至少需要包含`pretrained`与`freeze_params`信息,其他的参数为子网络的构造参数
      pretrained:                  # 该子网络是否需要加载预训练模型
      freeze_params: false         # 是否需要固定参数
      return_all_feats: true       # 子网络的参数,表示是否需要返回所有的features,如果为False,则只返回最后的输出
      model_type: *model_type      # 模型类别
      algorithm: SVTR              # 子网络的算法名称,该子网络其余参数均为构造参数,与普通的模型训练配置一致
      Transform:
      Backbone:
        name: MobileNetV1Enhance
        scale: 0.5
        last_conv_stride: [1, 2]
        last_pool_type: avg
      Head:
        name: MultiHead
        head_list:
          - CTCHead:
              Neck:
                name: svtr
                dims: 64
                depth: 2
                hidden_dims: 120
                use_guide: True
              Head:
                fc_decay: 0.00001
          - SARHead:
              enc_dim: 512
              max_text_length: *max_text_length
    Student:
      pretrained:
      freeze_params: false
      return_all_feats: true
      model_type: *model_type
      algorithm: SVTR
      Transform:
      Backbone:
        name: MobileNetV1Enhance
        scale: 0.5
        last_conv_stride: [1, 2]
        last_pool_type: avg
      Head:
        name: MultiHead
        head_list:
          - CTCHead:
              Neck:
                name: svtr
                dims: 64
                depth: 2
                hidden_dims: 120
                use_guide: True
              Head:
                fc_decay: 0.00001
          - SARHead:
              enc_dim: 512
              max_text_length: *max_text_length

当然,这里如果希望添加更多的子网络进行训练,也可以按照StudentTeacher的添加方式,在配置文件中添加相应的字段。比如说如果希望有3个模型互相监督,共同训练,那么Architecture可以写为如下格式。

Architecture:
  model_type: &model_type "rec"
  name: DistillationModel
  algorithm: Distillation
  Models:
    Teacher:
      pretrained:
      freeze_params: false
      return_all_feats: true
      model_type: *model_type
      algorithm: SVTR
      Transform:
      Backbone:
        name: MobileNetV1Enhance
        scale: 0.5
        last_conv_stride: [1, 2]
        last_pool_type: avg
      Head:
        name: MultiHead
        head_list:
          - CTCHead:
              Neck:
                name: svtr
                dims: 64
                depth: 2
                hidden_dims: 120
                use_guide: True
              Head:
                fc_decay: 0.00001
          - SARHead:
              enc_dim: 512
              max_text_length: *max_text_length
    Student:
      pretrained:
      freeze_params: false
      return_all_feats: true
      model_type: *model_type
      algorithm: SVTR
      Transform:
      Backbone:
        name: MobileNetV1Enhance
        scale: 0.5
        last_conv_stride: [1, 2]
        last_pool_type: avg
      Head:
        name: MultiHead
        head_list:
          - CTCHead:
              Neck:
                name: svtr
                dims: 64
                depth: 2
                hidden_dims: 120
                use_guide: True
              Head:
                fc_decay: 0.00001
          - SARHead:
              enc_dim: 512
              max_text_length: *max_text_length
    Student2:
      pretrained:
      freeze_params: false
      return_all_feats: true
      model_type: *model_type
      algorithm: SVTR
      Transform:
      Backbone:
        name: MobileNetV1Enhance
        scale: 0.5
        last_conv_stride: [1, 2]
        last_pool_type: avg
      Head:
        name: MultiHead
        head_list:
          - CTCHead:
              Neck:
                name: svtr
                dims: 64
                depth: 2
                hidden_dims: 120
                use_guide: True
              Head:
                fc_decay: 0.00001
          - SARHead:
              enc_dim: 512
              max_text_length: *max_text_length

最终该模型训练时,包含3个子网络:Teacher, Student, Student2

蒸馏模型DistillationModel类的具体实现代码可以参考distillation_model.py。

最终模型forward输出为一个字典,key为所有的子网络名称,例如这里为StudentTeacher,value为对应子网络的输出,可以为Tensor(只返回该网络的最后一层)和dict(也返回了中间的特征信息)。

在识别任务中,为了添加更多损失函数,保证蒸馏方法的可扩展性,将每个子网络的输出保存为dict,其中包含子模块输出。以该识别模型为例,每个子网络的输出结果均为dict,key包含backbone_out,neck_out, head_outvalue为对应模块的tensor,最终对于上述配置文件,DistillationModel的输出格式如下。

{
  "Teacher": {
    "backbone_out": tensor,
    "neck_out": tensor,
    "head_out": tensor,
  },
  "Student": {
    "backbone_out": tensor,
    "neck_out": tensor,
    "head_out": tensor,
  }
}

2.1.2 损失函数

知识蒸馏任务中,损失函数配置如下所示。

Loss:
  name: CombinedLoss
  loss_config_list:
  - DistillationDMLLoss:                       # 蒸馏的DML损失函数,继承自标准的DMLLoss
      weight: 1.0                              # 权重
      act: "softmax"                           # 激活函数,对输入使用激活函数处理,可以为softmax, sigmoid或者为None,默认为None
      use_log: true                            # 对输入计算log,如果函数已经
      model_name_pairs:                        # 用于计算DML loss的子网络名称对,如果希望计算其他子网络的DML loss,可以在列表下面继续填充
      - ["Student", "Teacher"]
      key: head_out                            # 取子网络输出dict中,该key对应的tensor
      multi_head: True                         # 是否为多头结构
      dis_head: ctc                            # 指定用于计算损失函数的head
      name: dml_ctc                            # 蒸馏loss的前缀名称,避免不同loss之间的命名冲突
  - DistillationDMLLoss:                       # 蒸馏的DML损失函数,继承自标准的DMLLoss
      weight: 0.5                              # 权重
      act: "softmax"                           # 激活函数,对输入使用激活函数处理,可以为softmax, sigmoid或者为None,默认为None
      use_log: true                            # 对输入计算log,如果函数已经
      model_name_pairs:                        # 用于计算DML loss的子网络名称对,如果希望计算其他子网络的DML loss,可以在列表下面继续填充
      - ["Student", "Teacher"]
      key: head_out                            # 取子网络输出dict中,该key对应的tensor
      multi_head: True                         # 是否为多头结构
      dis_head: sar                            # 指定用于计算损失函数的head
      name: dml_sar                            # 蒸馏loss的前缀名称,避免不同loss之间的命名冲突
  - DistillationDistanceLoss:                  # 蒸馏的距离损失函数
      weight: 1.0                              # 权重
      mode: "l2"                               # 距离计算方法,目前支持l1, l2, smooth_l1
      model_name_pairs:                        # 用于计算distance loss的子网络名称对
      - ["Student", "Teacher"]
      key: backbone_out                        # 取子网络输出dict中,该key对应的tensor
  - DistillationCTCLoss:                       # 基于蒸馏的CTC损失函数,继承自标准的CTC loss
      weight: 1.0                              # 损失函数的权重,loss_config_list中,每个损失函数的配置都必须包含该字段
      model_name_list: ["Student", "Teacher"]  # 对于蒸馏模型的预测结果,提取这两个子网络的输出,与gt计算CTC loss
      key: head_out                            # 取子网络输出dict中,该key对应的tensor
  - DistillationSARLoss:                       # 基于蒸馏的SAR损失函数,继承自标准的SARLoss
      weight: 1.0                              # 损失函数的权重,loss_config_list中,每个损失函数的配置都必须包含该字段
      model_name_list: ["Student", "Teacher"]  # 对于蒸馏模型的预测结果,提取这两个子网络的输出,与gt计算CTC loss
      key: head_out                            # 取子网络输出dict中,该key对应的tensor
      multi_head: True                         # 是否为多头结构,为true时,取出其中的SAR分支计算损失函数

上述损失函数中,所有的蒸馏损失函数均继承自标准的损失函数类,主要功能为: 对蒸馏模型的输出进行解析,找到用于计算损失的中间节点(tensor),再使用标准的损失函数类去计算。

以上述配置为例,最终蒸馏训练的损失函数包含下面5个部分。

  • StudentTeacher最终输出(head_out)的CTC分支与gt的CTC loss,权重为1。在这里因为2个子网络都需要更新参数,因此2者都需要计算与g的loss。
  • StudentTeacher最终输出(head_out)的SAR分支与gt的SAR loss,权重为1.0。在这里因为2个子网络都需要更新参数,因此2者都需要计算与g的loss。
  • StudentTeacher最终输出(head_out)的CTC分支之间的DML loss,权重为1。
  • StudentTeacher最终输出(head_out)的SAR分支之间的DML loss,权重为0.5。
  • StudentTeacher的骨干网络输出(backbone_out)之间的l2 loss,权重为1。

关于CombinedLoss更加具体的实现可以参考: combined_loss.py。关于DistillationCTCLoss等蒸馏损失函数更加具体的实现可以参考distillation_loss.py。

2.1.3 后处理

知识蒸馏任务中,后处理配置如下所示。

PostProcess:
  name: DistillationCTCLabelDecode       # 蒸馏任务的CTC解码后处理,继承自标准的CTCLabelDecode类
  model_name: ["Student", "Teacher"]     # 对于蒸馏模型的预测结果,提取这两个子网络的输出,进行解码
  key: head_out                          # 取子网络输出dict中,该key对应的tensor
  multi_head: True                       # 多头结构时,会取出其中的CTC分支进行计算

以上述配置为例,最终会同时计算StudentTeahcer 2个子网络的CTC解码输出,返回一个dictkey为用于处理的子网络名称,value为用于处理的子网络列表。

关于DistillationCTCLabelDecode更加具体的实现可以参考: rec_postprocess.py

2.1.4 指标计算

知识蒸馏任务中,指标计算配置如下所示。

Metric:
  name: DistillationMetric         # 蒸馏任务的CTC解码后处理,继承自标准的CTCLabelDecode类
  base_metric_name: RecMetric      # 指标计算的基类,对于模型的输出,会基于该类,计算指标
  main_indicator: acc              # 指标的名称
  key: "Student"                   # 选取该子网络的 main_indicator 作为作为保存保存best model的判断标准
  ignore_space: False              # 评估时是否忽略空格的影响

以上述配置为例,最终会使用Student子网络的acc指标作为保存best model的判断指标,同时,日志中也会打印出所有子网络的acc指标。

关于DistillationMetric更加具体的实现可以参考: distillation_metric.py。

2.1.5 蒸馏模型微调

对蒸馏得到的识别蒸馏进行微调有2种方式。

(1)基于知识蒸馏的微调:这种情况比较简单,下载预训练模型,在ch_PP-OCRv3_rec_distillation.yml中配置好预训练模型路径以及自己的数据路径,即可进行模型微调训练。

(2)微调时不使用知识蒸馏:这种情况,需要首先将预训练模型中的学生模型参数提取出来,具体步骤如下。

  • 首先下载预训练模型并解压。
# 下面预训练模型并解压
wget https://paddleocr.bj.bcebos.com/PP-OCRv3/chinese/ch_PP-OCRv3_rec_train.tar
tar -xf ch_PP-OCRv3_rec_train.tar
  • 然后使用python,对其中的学生模型参数进行提取
import paddle
# 加载预训练模型
all_params = paddle.load("ch_PP-OCRv3_rec_train/best_accuracy.pdparams")
# 查看权重参数的keys
print(all_params.keys())
# 学生模型的权重提取
s_params = {key[len("Student."):]: all_params[key] for key in all_params if "Student." in key}
# 查看学生模型权重参数的keys
print(s_params.keys())
# 保存
paddle.save(s_params, "ch_PP-OCRv3_rec_train/student.pdparams")

转化完成之后,使用ch_PP-OCRv3_rec.yml,修改预训练模型的路径(为导出的student.pdparams模型路径)以及自己的数据路径,即可进行模型微调。

2.2 检测配置文件解析

检测模型蒸馏的配置文件在PaddleOCR/configs/det/ch_PP-OCRv3/目录下,包含两个个蒸馏配置文件:

  • ch_PP-OCRv3_det_cml.yml,采用cml蒸馏,采用一个大模型蒸馏两个小模型,且两个小模型互相学习的方法
  • ch_PP-OCRv3_det_dml.yml,采用DML的蒸馏,两个Student模型互蒸馏的方法

2.2.1 模型结构

知识蒸馏任务中,模型结构配置如下所示:

Architecture:
  name: DistillationModel          # 结构名称,蒸馏任务中,为DistillationModel,用于构建对应的结构
  algorithm: Distillation          # 算法名称
  Models:                          # 模型,包含子网络的配置信息
    Student:                       # 子网络名称,至少需要包含`pretrained`与`freeze_params`信息,其他的参数为子网络的构造参数
      freeze_params: false         # 是否需要固定参数
      return_all_feats: false      # 子网络的参数,表示是否需要返回所有的features,如果为False,则只返回最后的输出
      model_type: det
      algorithm: DB
      Backbone:
        name: ResNet
        in_channels: 3
        layers: 50
      Neck:
        name: LKPAN
        out_channels: 256
      Head:
        name: DBHead
        kernel_list: [7,2,2]
        k: 50
    Teacher:                      # 另外一个子网络,这里给的是DML蒸馏示例,
      freeze_params: true
      return_all_feats: false
      model_type: det
      algorithm: DB
      Transform:
      Backbone:
        name: ResNet
        in_channels: 3
        layers: 50
      Neck:
        name: LKPAN
        out_channels: 256
      Head:
        name: DBHead
        kernel_list: [7,2,2]
        k: 50

如果是采用DML,即两个小模型互相学习的方法,上述配置文件里的Teacher网络结构需要设置为Student模型一样的配置,具体参考配置文件ch_PP-OCRv3_det_dml.yml。

下面介绍ch_PP-OCRv3_det_cml.yml的配置文件参数:

Architecture:
  name: DistillationModel
  algorithm: Distillation
  model_type: det
  Models:
    Teacher:                         # CML蒸馏的Teacher模型配置
      pretrained: ./pretrain_models/ch_ppocr_server_v2.0_det_train/best_accuracy
      freeze_params: true            # Teacher 不训练
      return_all_feats: false
      model_type: det
      algorithm: DB
      Transform:
      Backbone:
        name: ResNet
        in_channels: 3
        layers: 50
      Neck:
        name: LKPAN
        out_channels: 256
      Head:
        name: DBHead
        kernel_list: [7,2,2]
        k: 50
    Student:                         # CML蒸馏的Student模型配置
      pretrained: ./pretrain_models/MobileNetV3_large_x0_5_pretrained
      freeze_params: false
      return_all_feats: false
      model_type: det
      algorithm: DB
      Backbone:
        name: MobileNetV3
        scale: 0.5
        model_name: large
        disable_se: true
      Neck:
        name: RSEFPN
        out_channels: 96
        shortcut: True
      Head:
        name: DBHead
        k: 50
    Student2:                          # CML蒸馏的Student2模型配置
      pretrained: ./pretrain_models/MobileNetV3_large_x0_5_pretrained
      freeze_params: false
      return_all_feats: false
      model_type: det
      algorithm: DB
      Transform:
      Backbone:
        name: MobileNetV3
        scale: 0.5
        model_name: large
        disable_se: true
      Neck:
        name: RSEFPN
        out_channels: 96
        shortcut: True
      Head:
        name: DBHead
        k: 50

蒸馏模型DistillationModel类的具体实现代码可以参考distillation_model.py。

最终模型forward输出为一个字典,key为所有的子网络名称,例如这里为StudentTeacher,value为对应子网络的输出,可以为Tensor(只返回该网络的最后一层)和dict(也返回了中间的特征信息)。

在蒸馏任务中,为了方便添加蒸馏损失函数,每个网络的输出保存为dict,其中包含子模块输出。每个子网络的输出结果均为dict,key包含backbone_out,neck_out, head_outvalue为对应模块的tensor,最终对于上述配置文件,DistillationModel的输出格式如下。

{
  "Teacher": {
    "backbone_out": tensor,
    "neck_out": tensor,
    "head_out": tensor,
  },
  "Student": {
    "backbone_out": tensor,
    "neck_out": tensor,
    "head_out": tensor,
  }
}

2.2.2 损失函数

检测ch_PP-OCRv3_det_cml.yml蒸馏损失函数配置如下所示。

Loss:
  name: CombinedLoss
  loss_config_list:
  - DistillationDilaDBLoss:
      weight: 1.0
      model_name_pairs:
      - ["Student", "Teacher"]
      - ["Student2", "Teacher"]                  # 改动1,计算两个Student和Teacher的损失
      key: maps
      balance_loss: true
      main_loss_type: DiceLoss
      alpha: 5
      beta: 10
      ohem_ratio: 3
  - DistillationDMLLoss:                         # 改动2,增加计算两个Student之间的损失
      model_name_pairs:
      - ["Student", "Student2"]
      maps_name: "thrink_maps"
      weight: 1.0
      # act: None
      key: maps
  - DistillationDBLoss:
      weight: 1.0
      model_name_list: ["Student", "Student2"]   # 改动3,计算两个Student和GT之间的损失
      balance_loss: true
      main_loss_type: DiceLoss
      alpha: 5
      beta: 10
      ohem_ratio: 3

关于DistillationDilaDBLoss更加具体的实现可以参考: distillation_loss.py。关于DistillationDBLoss等蒸馏损失函数更加具体的实现可以参考distillation_loss.py。

2.2.3 后处理

知识蒸馏任务中,检测蒸馏后处理配置如下所示。

PostProcess:
  name: DistillationDBPostProcess                  # DB检测蒸馏任务的CTC解码后处理,继承自标准的DBPostProcess类
  model_name: ["Student", "Student2", "Teacher"]   # 对于蒸馏模型的预测结果,提取多个子网络的输出,进行解码,不需要后处理的网络可以不在model_name中设置
  thresh: 0.3
  box_thresh: 0.6
  max_candidates: 1000
  unclip_ratio: 1.5

以上述配置为例,最终会同时计算StudentStudent2Teacher 3个子网络的输出做后处理计算。同时,由于有多个输入,后处理返回的输出也有多个,

关于DistillationDBPostProcess更加具体的实现可以参考: db_postprocess.py

2.2.4 蒸馏指标计算

知识蒸馏任务中,检测蒸馏指标计算配置如下所示。

Metric:
  name: DistillationMetric
  base_metric_name: DetMetric
  main_indicator: hmean
  key: "Student"

由于蒸馏需要包含多个网络,甚至多个Student网络,在计算指标的时候只需要计算一个Student网络的指标即可,key字段设置为Student则表示只计算Student网络的精度。

2.2.5 检测蒸馏模型finetune

PP-OCRv3检测蒸馏有两种方式:

  • 采用ch_PP-OCRv3_det_cml.yml,采用cml蒸馏,同样Teacher模型设置为PaddleOCR提供的模型或者您训练好的大模型
  • 采用ch_PP-OCRv3_det_dml.yml,采用DML的蒸馏,两个Student模型互蒸馏的方法,在PaddleOCR采用的数据集上相比单独训练Student模型有1%-2%的提升。

在具体fine-tune时,需要在网络结构的pretrained参数中设置要加载的预训练模型。

在精度提升方面,cml的精度>dml的精度蒸馏方法的精度。当数据量不足或者Teacher模型精度与Student精度相差不大的时候,这个结论或许会改变。

另外,由于PaddleOCR提供的蒸馏预训练模型包含了多个模型的参数,如果您希望提取Student模型的参数,可以参考如下代码:

# 下载蒸馏训练模型的参数
wget https://paddleocr.bj.bcebos.com/PP-OCRv2/chinese/ch_PP-OCRv3_det_distill_train.tar
import paddle
# 加载预训练模型
all_params = paddle.load("ch_PP-OCRv3_det_distill_train/best_accuracy.pdparams")
# 查看权重参数的keys
print(all_params.keys())
# 学生模型的权重提取
s_params = {key[len("Student."):]: all_params[key] for key in all_params if "Student." in key}
# 查看学生模型权重参数的keys
print(s_params.keys())
# 保存
paddle.save(s_params, "ch_PP-OCRv3_det_distill_train/student.pdparams")

最终Student模型的参数将会保存在ch_PP-OCRv3_det_distill_train/student.pdparams中,用于模型的fine-tune。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2208034.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用Spring Security实现用户-角色-资源的权限控制

文章目录 一、基于角色的请求控制二、加载用户角色信息三、角色与资源的关联四、测试角色权限控制1. 未登录用户访问受保护资源2. 登录用户访问受保护资源3. 角色不足的用户访问受保护资源&#xff08;把前面改成.roles("USER")&#xff09; 五、自定义异常处理1. 自…

CANoe的数据回放功能

文章目录 CANoe简介1.Offline回放功能2.Replay Block回放模块3.两者的异同 CANoe简介 CANoe&#xff08;CAN open environment&#xff09;&#xff1a; 用于汽车ECU网络仿真、数据分析、测试和诊断&#xff0c;还可以进行数据回放、程序刷写等。具有实时报文跟踪、数据解析及…

Android开发启动页跳过倒计时效果

Android开发启动页跳过倒计时效果 app启动页都会放些广告图&#xff0c;然后倒计时跳过。 一、思路&#xff1a; 不是很难&#xff0c;就用用个倒计时控制mHandler.sendEmptyMessageDelayed(WHAT_COUNT_DOWN, 100); 二、效果图&#xff1a; 三、关键代码&#xff1a; publ…

消息队列面试题——第二篇

1. rocketmq、rabbitmq、kafka的区别 架构设计和消息模型 特性rocketmqrabbitmqkafka消息模型基于主题和消费组&#xff0c;支持发布/订阅和点对点两种模型基于队列模型&#xff0c;支持发布/订阅和点对点两种模型基于分区的主题模型&#xff0c;主要用于日志流式处理和高吞吐…

基于SSM创城志愿者管理系统JAVA|VUE|Springboot计算机毕业设计源代码+数据库+LW文档+开题报告+答辩稿+部署教+代码讲解

源代码数据库LW文档&#xff08;1万字以上&#xff09;开题报告答辩稿 部署教程代码讲解代码时间修改教程 一、开发工具、运行环境、开发技术 开发工具 1、操作系统&#xff1a;Window操作系统 2、开发工具&#xff1a;IntelliJ IDEA或者Eclipse 3、数据库存储&#xff1a…

RNN心脏病预测

本文为为&#x1f517;365天深度学习训练营内部文章 原作者&#xff1a;K同学啊 一 前期准备 1.数据导入 import pandas as pd from keras.optimizers import Adam from matplotlib import pyplot as plt from sklearn.model_selection import train_test_split from sklearn.p…

jenkins 插件Publish Over SSH

一、安装插件 二、配置sshserver http://192.168.31.156:8080/manage/configure 三、添加自由风格&#xff1a;PublishOverSSHDemo 我们将工作目录&#xff1a;/var/lib/jenkins/workspace/PublishOverSSHDemo下的图片m3.jpeg 同步到目标143服务器目录&#xff1a;/root/imag…

Mysql(七) --- 索引

文章目录 前言1.简介1.1.索引是什么&#xff1f;1.2.为什么使用索引? 2.索引应该使用什么数据结构&#xff1f;2.1.Hash2.2.二叉搜索树2.3.N叉树2.4.B树2.4.1. 简介2.4.2. B树的特点2.4.3. B树和B树的对比 3.Mysql中的页3.1.为什么要使用页3.2.页文件头和页文件尾3.3.页主体3.…

Python开源项目月排行 2024年9月

#2024年9月2024年9月29日1jax一个开源的高性能数值计算库&#xff0c;旨在为机器学习和科学计算提供灵活性和效率。该项目由 Google 研发&#xff0c;并在 GitHub 上进行维护。AX 主要用于以下几个方面&#xff1a; 自动微分&#xff1a;提供高效的自动微分功能&#xff0c;支持…

嵌入式面试——FreeRTOS篇(九) 内存管理

本篇为&#xff1a;FreeRTOS 内存管理篇 一、FreeRTOS内存管理简介 1、FreeRTOS内存管理介绍 答&#xff1a; 在使用 FreeRTOS 创建任务、队列、信号量等对象的时&#xff0c;一般都提供了两种方法&#xff1a; 动态方法创建&#xff1a;自动地从 FreeRTOS 管理的内存堆中申…

【AI绘画教程】StableDiffusion出图颜色偏白发灰?用好VAE立马解决!(附VAE模型下载)

大家好&#xff0c;我是画画的小强 之前已经给大家推荐过不少AI绘画中 Stable Diffusion WebUI 的大模型&#xff0c;今天为大家介绍一下 WebUI 中“外挂VAE”的相关内容&#xff0c;可以解决我们在用大模型出图过程中出现的图像颜色发灰、发白的问题&#xff0c;一起来看看吧…

话说你们维保到期通知都是谁通知的

离谱了&#xff0c;公司有个客户维保到期了 过了2个月才发现。 白干了两个月&#xff0c; 客户也不愿意给这两个月钱。 现在商务和运维在扯皮&#xff0c; 商务说运维部门应该到期给客户发通知&#xff0c; 运维说商务到期要续签&#xff0c; 就应该商务去通知。 然后老…

ppt怎么做出高级感?找对高级ppt模板,轻松一键替换

想问问大家国庆节后的工作忙吗&#xff1f;小编的大厂朋友们都忙疯了&#xff01; 都在忙着做各种项目的执行总结PPT报告&#xff0c;和接下来的工作计划展望&#xff01;做出来的PPT还会被领导嫌弃排版没创意、不高级...... 这不&#xff0c;还来找小编&#xff0c;问有没有什…

水库抽样算法(大数据算法作业)

时隔一个多月&#xff0c;终于想起来写大数据算法基础的实验报告&#xff0c;主要是快截止了&#xff0c;hh 这两天加急把这个报告写完了~ 接下来&#xff0c;写一写证明过程&#xff08;参考书籍&#xff1a;高等教育出版社《数据科学与工程算法基础》&#xff09;主要代码以…

MODBUS协议介绍,通过MODBUS协议控制伺服电机工作

1.前言 modbus协议本身的介绍&#xff0c;请大家自行查阅资料。本文简单介绍一下如何通过MODBUS协议组装控制指令。 最近搞了一个项目&#xff0c;要驱动伺服电机工作。通过下位机STM32 407 100封脚 给伺服电机发控制指令。电机和下位机之前的通信采用RS485串口通信&#xff…

seaCMS v12.9代码审计学习(下半)

文章目录 admin/admin_safe.php任意文件下载CSRF 添加管理员账户CSRF配合XSS弹cookie admin/admin_safe.php任意文件下载 在admin_safe.php文件下有着这么一段代码&#xff0c;他的作用时检查action的值是否为download&#xff0c;如果为download那么将你传入的文件直接打印给…

LeetCode题练习与总结:二叉树的序列化与反序列化--297

一、题目描述 序列化是将一个数据结构或者对象转换为连续的比特位的操作&#xff0c;进而可以将转换后的数据存储在一个文件或者内存中&#xff0c;同时也可以通过网络传输到另一个计算机环境&#xff0c;采取相反方式重构得到原数据。 请设计一个算法来实现二叉树的序列化与…

校园网环境下基于OpenWRT的路由器选型与解决方案

校园网环境下基于OpenWRT的路由器选型与解决方案 网页认证(锐捷认证)解除校园网设备限制,路由器选型和解决方案 openwrt 我们学校校园网一个账号只能登录两台设备&#xff0c;多了直接就退出联网状态&#xff0c;然后校园网是基于锐捷认证进行认证的&#xff0c;然后通过ment…

基于逻辑回归实现乳腺癌预测

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

使用IDEA生成API文档

1. 在IDEA中&#xff0c;Tools->Generate JavaDoc Scope 2.Output Directory里面放&#xff0c;生成的目录。 Other command line arguments:-encoding utf-8 -charset utf-8&#xff08;解决乱码&#xff09; 3.点击ok&#xff0c;生成的效果图