★★★ 本文源自AlStudio社区精品项目,【点击此处】查看更多精品内容 >>>

1. 背景介绍

车牌识别(Vehicle License Plate Recognition,VLPR) 是计算机视频图像识别技术在车辆牌照识别中的一种应用。车牌识别技术已被广泛用于智能交通的各个领域:

  • 停车场管理: 公共停车场和小区停车场场景下,车牌识别用于车辆停车计时管理。
  • 城市智能交通: 智能交通场景下,车牌识别可用于违章追溯,车辆大数据分析。

在上述场景下,车牌识别的主要难点如下:

  1. 车牌在图像中的尺度差异大、在车辆上的悬挂位置不固定
  2. 车牌图像质量层次不齐: 角度倾斜、图片模糊、光照不足、过曝等问题严重
  3. 端侧设备存储空间和算力有限,对模型大小和推理速度有要求

2. 快速体验

本项目基于Aistudio完成, 具体环境如下:

  • 操作系统: Linux
  • PaddlePaddle: 2.3.2
  • paddleslim: 2.3.4
  • PaddleOCR: Release/2.6

下载 PaddleOCR代码

#! git clone https://github.com/PaddlePaddle/PaddleOCR
! git clone https://gitee.com/paddlepaddle/PaddleOCR

安装依赖库

! pip install -r /home/aistudio/PaddleOCR/requirements.txt --user
! pip install paddleslim editdistance imgaug scikit-image rapidfuzz --user

安装成功后可看到如下提示:

Installing collected packages: pyclipper, Polygon3, lmdb, lanms-neo, tifffile, rapidfuzz, PyWavelets, PyMuPDF, opencv-contrib-python

3. 数据准备

所使用的数据集为 CCPD和自建黄牌车牌数据集,CCPD车牌数据集包含蓝牌和绿牌两种类型,数据集分布如下:

数据集类型数量
训练集350977(蓝牌)+10775(绿牌)+829(黄牌)
测试集1000(蓝牌)+1001(绿牌)+300(黄牌)
! tar -xf /home/aistudio/data/data175158/CCPD2020.tar -C /home/aistudio/data 
! tar -xf /home/aistudio/data/data175158/yellow.tar -C /home/aistudio/data 
! tar -xf /home/aistudio/data/data175171/CCPD2019.tar -C /home/aistudio/data 

解压之后数据的分布如下

  • 检测数据集
数据集类型数据集名称数据集数量gt文件路径根目录
训练集CCPD2019350977/home/aistudio/data/CCPD2019/det_train.txt/home/aistudio/data
CCPD202010775/home/aistudio/data/CCPD2020/det_train.txt/home/aistudio/data
黄牌数据集829/home/aistudio/data/yellow/det_train.txt/home/aistudio/data
测试集CCPD20191000/home/aistudio/data/CCPD2019/det_val.txt/home/aistudio/data
CCPD20201001/home/aistudio/data/CCPD2020/det_val.txt/home/aistudio/data
黄牌数据集300/home/aistudio/data/yellow/det_val.txt/home/aistudio/data
  • 识别数据集
数据集类型数据集名称数据集数量gt文件路径根目录
训练集CCPD2019350977/home/aistudio/data/CCPD2019/rec_train.txt/home/aistudio/data
CCPD202010775/home/aistudio/data/CCPD2020/rec_train.txt/home/aistudio/data
黄牌数据集829/home/aistudio/data/yellow/rec_train.txt/home/aistudio/data
测试集CCPD20191000/home/aistudio/data/CCPD2019/rec_val.txt/home/aistudio/data
CCPD20201001/home/aistudio/data/CCPD2020/rec_val.txt/home/aistudio/data
黄牌数据集300/home/aistudio/data/yellow/rec_val.txt/home/aistudio/data

4. 针对文本检测模型的优化

4.1 优化方法

选用 PaddleOCR 中的 PP-OCRv3中的文本检测模型做为base模型,并且使用 PP-OCRv3 文本检测模型参数作为预训练模型。由于车牌场景均为端侧设备部署,因此对速度和模型大小有比较高的要求,因此还需要采用量化训练的方式进行模型大小的压缩和模型推理速度的加速。模型量化可以在基本不损失模型的精度的情况下,减小模型参数大小并加速计算,使用量化后的模型在移动端等部署时更具备速度优势。

因此,本实验中对于车牌检测有如下3种方案:

  1. PP-OCRv3超轻量中英文预训练模型直接检测
  2. 车牌数据集在PP-OCRv3文本检测模型上fine-tune
  3. 车牌数据集在PP-OCRv3文本检测模型上fine-tune后量化

4.2 模型训练和评估

开始实验之前先切换到PaddleOCR目录

import os
os.chdir('/home/aistudio/PaddleOCR')

从下表中下载PP-OCRv3文本检测预训练模型

模型名称模型简介配置文件推理模型大小下载地址
ch_PP-OCRv3_det【最新】原始超轻量模型,支持中英文、多语种文本检测ch_PP-OCRv3_det_cml.yml3.8M推理模型 / 训练模型

使用如下命令下载预训练模型

! mkdir models
%cd models
! wget https://paddleocr.bj.bcebos.com/PP-OCRv3/chinese/ch_PP-OCRv3_det_distill_train.tar
! tar -xf ch_PP-OCRv3_det_distill_train.tar
%cd /home/aistudio/PaddleOCR
4.2.1 方案1:直接检测

预训练模型下载完成后,我们使用ch_PP-OCRv3_det_student 配置文件进行后续实验,在开始评估之前需要对配置文件中部分字段进行设置,具体如下:

  1. Global.pretrained_model: 指向PP-OCRv3文本检测预训练模型地址
  2. Eval.dataset.data_dir:指向验证集图片存放目录
  3. Eval.dataset.label_file_list:指向验证集标注文件
  4. Eval.loader.num_workers: 验证集多进程数据读取的进程数,在aistudio中需要设为2

使用如下命令进行PP-OCRv3文本检测预训练模型的评估

! python tools/eval.py -c configs/det/ch_PP-OCRv3/ch_PP-OCRv3_det_student.yml -o \
    Global.pretrained_model=models/ch_PP-OCRv3_det_distill_train/student.pdparams \
     Eval.dataset.data_dir=/home/aistudio/data/ \
     Eval.dataset.label_file_list=[/home/aistudio/data/yellow/det_val.txt,/home/aistudio/data/CCPD2020/det_val.txt,/home/aistudio/data/CCPD2019/det_val.txt] \
     Eval.loader.num_workers=2  

执行完成后可看见如下输出:

[2023/03/22 14:58:15] ppocr INFO: metric eval ***************
[2023/03/22 14:58:15] ppocr INFO: precision:0.5121225983531564
[2023/03/22 14:58:15] ppocr INFO: recall:0.9722101606600086
[2023/03/22 14:58:15] ppocr INFO: hmean:0.6708614232209738
[2023/03/22 14:58:15] ppocr INFO: fps:21.042592384588875

使用预训练模型进行评估,指标如下所示:

方案hmeans
PP-OCRv3中英文超轻量检测预训练模型67.08%
4.2.2 方案2:fine-tune

和评估相同,进行训练也需要对部分字段进行设置,具体如下:

在使用预训练模型进行fine-tune时,需要设置如下11个字段

  1. Global.pretrained_model: 指向PP-OCRv3文本检测预训练模型地址
  2. Global.eval_batch_step: 模型多少step评估一次,这里设为从第0个step开始每隔539个step评估一次,539为一个epoch总的step数。
  3. Optimizer.lr.name: 学习率衰减器设为常量 Const
  4. Optimizer.lr.learning_rate: 学习率设为之前的0.05倍
  5. Optimizer.lr.warmup_epoch: warmup_epoch设为0
  6. Train.dataset.data_dir:指向训练集图片存放目录
  7. Train.dataset.ratio_list: 不同数据源在每个epoch的采样率,这里设置为[1,0.16,0.005],保证黄牌+绿牌:蓝牌=1:1
  8. Train.dataset.label_file_list:指向训练集标注文件
  9. Train.loader.num_workers: 训练集多进程数据读取的进程数,在aistudio中需要设为1
  10. Eval.dataset.data_dir:指向验证集图片存放目录
  11. Eval.dataset.label_file_list:指向验证集标注文件
  12. Eval.loader.num_workers: 验证集多进程数据读取的进程数,在aistudio中需要设为0

使用如下代码即可启动在CCPD车牌数据集上的fine-tune。

! python3.7 tools/train.py -c configs/det/ch_PP-OCRv3/ch_PP-OCRv3_det_student.yml -o \
    Global.pretrained_model=models/ch_PP-OCRv3_det_distill_train/student.pdparams \
    Global.save_model_dir=output/CCPD/det/ \
    Global.eval_batch_step="[0, 539]" \
    Global.epoch_num=12 \
    Optimizer.lr.name=Const \
    Optimizer.lr.learning_rate=0.0005 \
    Optimizer.lr.warmup_epoch=0 \
    Train.dataset.data_dir=/home/aistudio/data \
    Train.dataset.label_file_list=[/home/aistudio/data/yellow/det_train.txt,/home/aistudio/data/CCPD2020/det_train.txt,/home/aistudio/data/CCPD2019/det_train.txt] \
    Train.dataset.ratio_list=[1,0.16,0.005] \
    Eval.dataset.data_dir=/home/aistudio/data \
    Eval.dataset.label_file_list=[/home/aistudio/data/yellow/det_val.txt,/home/aistudio/data/CCPD2020/det_val.txt,/home/aistudio/data/CCPD2019/det_val.txt]

训练过程中可看见如下输出:

[2023/03/22 15:17:22] ppocr INFO: Initialize indexs of datasets:['/home/aistudio/data/yellow/det_train.txt', '/home/aistudio/data/CCPD2020/det_train.txt', '/home/aistudio/data/CCPD2019/det_train.txt']
[2023/03/22 15:22:44] ppocr INFO: epoch: [2/12], global_step: 960, lr: 0.000500, loss: 0.738884, loss_shrink_maps: 0.359954, loss_threshold_maps: 0.313610, loss_binary_maps: 0.072066, avg_reader_cost: 0.03725 s, avg_batch_cost: 0.22163 s, avg_samples: 8.0, ips: 36.09593 samples/s, eta: 0:20:18
[2023/03/22 15:22:47] ppocr INFO: epoch: [2/12], global_step: 970, lr: 0.000500, loss: 0.774840, loss_shrink_maps: 0.376398, loss_threshold_maps: 0.313610, loss_binary_maps: 0.075208, avg_reader_cost: 0.06016 s, avg_batch_cost: 0.24616 s, avg_samples: 8.0, ips: 32.49960 samples/s, eta: 0:20:18
[2023/03/22 15:22:49] ppocr INFO: epoch: [2/12], global_step: 980, lr: 0.000500, loss: 0.768924, loss_shrink_maps: 0.378589, loss_threshold_maps: 0.336693, loss_binary_maps: 0.075870, avg_reader_cost: 0.04459 s, avg_batch_cost: 0.22813 s, avg_samples: 8.0, ips: 35.06788 samples/s, eta: 0:20:16

进行fine_tune时,在大约11epoch时指标即可达到99%。(由于还在上学时间问题,就只训练了12轮,要是想要训练更多轮,请修改Global.epoch_num)

训练完成后使用如下命令进行评估

! python3.7 tools/eval.py -c configs/det/ch_PP-OCRv3/ch_PP-OCRv3_det_student.yml -o \
    Global.checkpoints=output/CCPD/det/best_accuracy.pdparams \
    Eval.dataset.data_dir=/home/aistudio/data \
    Eval.dataset.label_file_list=[/home/aistudio/data/yellow/det_val.txt,/home/aistudio/data/CCPD2020/det_val.txt,/home/aistudio/data/CCPD2019/det_val.txt]

执行完成后可看见如下输出:

[2023/03/22 16:07:53] ppocr INFO: metric eval ***************
[2023/03/22 16:07:53] ppocr INFO: precision:0.9922279792746114
[2023/03/22 16:07:53] ppocr INFO: recall:0.9978289188015632
[2023/03/22 16:07:53] ppocr INFO: hmean:0.9950205672223426
[2023/03/22 16:07:53] ppocr INFO: fps:29.57183031711502

使用预训练模型和fine-tune,指标分别如下:

方案hmeans
PP-OCRv3中英文超轻量检测预训练模型67.08%
PP-OCRv3中英文超轻量检测预训练模型 fine-tune99.50%

可以看到进行fine-tune能显著提升车牌检测的效果。

4.2.3 量化训练

要是想在端侧设备上进行部署,我们还需要对模型进行量化以提升模型的运行速度并降低模型体积。

此处使用在线量化训练,如果需要在线量化训练可通过如下命令启动:

! python3.7 deploy/slim/quantization/quant.py -c configs/det/ch_PP-OCRv3/ch_PP-OCRv3_det_student.yml -o \
    Global.pretrained_model=output/CCPD/det/best_accuracy.pdparams \
    Global.save_model_dir=output/CCPD/det_quant/ \
    Global.eval_batch_step="[0, 539]" \
    Optimizer.lr.name=Const \
    Optimizer.lr.learning_rate=0.0005 \
    Optimizer.lr.warmup_epoch=0 \
    Train.dataset.data_dir=/home/aistudio/data \
    Train.dataset.label_file_list=[/home/aistudio/data/yellow/det_train.txt,/home/aistudio/data/CCPD2020/det_train.txt,/home/aistudio/data/CCPD2019/det_train.txt] \
    Train.dataset.ratio_list=[1,0.16,0.005] \
    Eval.dataset.data_dir=/home/aistudio/data \
    Eval.dataset.label_file_list=[/home/aistudio/data/yellow/det_val.txt,/home/aistudio/data/CCPD2020/det_val.txt,/home/aistudio/data/CCPD2019/det_val.txt]

参考:https://aistudio.baidu.com/aistudio/projectdetail/3919091?channelType=0&channel=0

量化后指标对比如下

方案hmeans模型大小预测速度(android)
PP-OCRv3中英文超轻量检测预训练模型 fine-tune99.50%2.6m223ms
PP-OCRv3中英文超轻量检测预训练模型 fine-tune+量化99.80%1.1m189ms

可以看到通过量化训练在精度几乎无损的情况下,降低模型体积60%并且推理速度提升15%。

4.3 配置文件

Global:
  debug: false
  use_gpu: true
  epoch_num: 500
  log_smooth_window: 20
  print_batch_step: 10
  save_model_dir: ./output/ch_PP-OCR_V3_det/
  save_epoch_step: 100
  eval_batch_step:
  - 0
  - 400
  cal_metric_during_train: false
  pretrained_model: https://paddleocr.bj.bcebos.com/pretrained/MobileNetV3_large_x0_5_pretrained.pdparams
  checkpoints: null
  save_inference_dir: null
  use_visualdl: false
  infer_img: doc/imgs_en/img_10.jpg
  save_res_path: ./checkpoints/det_db/predicts_db.txt
  distributed: true

Architecture:
  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

Loss:
  name: DBLoss
  balance_loss: true
  main_loss_type: DiceLoss
  alpha: 5
  beta: 10
  ohem_ratio: 3
Optimizer:
  name: Adam
  beta1: 0.9
  beta2: 0.999
  lr:
    name: Cosine
    learning_rate: 0.001
    warmup_epoch: 2
  regularizer:
    name: L2
    factor: 5.0e-05
PostProcess:
  name: DBPostProcess
  thresh: 0.3
  box_thresh: 0.6
  max_candidates: 1000
  unclip_ratio: 1.5
Metric:
  name: DetMetric
  main_indicator: hmean
Train:
  dataset:
    name: SimpleDataSet
    data_dir: ./train_data/icdar2015/text_localization/
    label_file_list:
      - ./train_data/icdar2015/text_localization/train_icdar2015_label.txt
    ratio_list: [1.0]
    transforms:
    - DecodeImage:
        img_mode: BGR
        channel_first: false
    - DetLabelEncode: null
    - IaaAugment:
        augmenter_args:
        - type: Fliplr
          args:
            p: 0.5
        - type: Affine
          args:
            rotate:
            - -10
            - 10
        - type: Resize
          args:
            size:
            - 0.5
            - 3
    - EastRandomCropData:
        size:
        - 960
        - 960
        max_tries: 50
        keep_ratio: true
    - MakeBorderMap:
        shrink_ratio: 0.4
        thresh_min: 0.3
        thresh_max: 0.7
    - MakeShrinkMap:
        shrink_ratio: 0.4
        min_text_size: 8
    - NormalizeImage:
        scale: 1./255.
        mean:
        - 0.485
        - 0.456
        - 0.406
        std:
        - 0.229
        - 0.224
        - 0.225
        order: hwc
    - ToCHWImage: null
    - KeepKeys:
        keep_keys:
        - image
        - threshold_map
        - threshold_mask
        - shrink_map
        - shrink_mask
  loader:
    shuffle: true
    drop_last: false
    batch_size_per_card: 8
    num_workers: 4
Eval:
  dataset:
    name: SimpleDataSet
    data_dir: ./train_data/icdar2015/text_localization/
    label_file_list:
      - ./train_data/icdar2015/text_localization/test_icdar2015_label.txt
    transforms:
    - DecodeImage:
        img_mode: BGR
        channel_first: false
    - DetLabelEncode: null
    - DetResizeForTest: null
    - NormalizeImage:
        scale: 1./255.
        mean:
        - 0.485
        - 0.456
        - 0.406
        std:
        - 0.229
        - 0.224
        - 0.225
        order: hwc
    - ToCHWImage: null
    - KeepKeys:
        keep_keys:
        - image
        - shape
        - polys
        - ignore_tags
  loader:
    shuffle: false
    drop_last: false
    batch_size_per_card: 1
    num_workers: 2

4.4 模型推理

在实际部署中,我们需要将动态图训练的模型转换为静态图模型进行推理,使用如下命令可以将训练好的模型导出为静态图模型:
此处没有量化模型的推理,如需要请去文档中查找相关命令

#非量化模型
! python tools/export_model.py -c configs/det/ch_PP-OCRv3/ch_PP-OCRv3_det_student.yml -o \
    Global.pretrained_model=output/CCPD/det/best_accuracy.pdparams \
    Global.save_inference_dir=output/CCPD/det/infer
'''
#量化模型
! python deploy/slim/quantization/export_model.py -c configs/det/ch_PP-OCRv3/ch_PP-OCRv3_det_student.yml -o \
    Global.pretrained_model=output/CCPD/det_quant/best_accuracy.pdparams \
    Global.save_inference_dir=output/CCPD/det_quant/infer \
    Eval.dataset.data_dir=/home/aistudio/data \
    Eval.dataset.label_file_list=[/home/aistudio/data/yellow/det_val.txt,/home/aistudio/data/CCPD2020/det_val.txt,/home/aistudio/data/CCPD2019/det_val.txt]
'''

执行完成后可看见如下输出:

[2023/03/22 16:14:12] ppocr INFO: inference model is saved to output/CCPD/det/infer/inference

导出后的模型,使用如下命令可使用预测引擎对单张图片进行推理:

! python3 tools/infer/predict_det.py \
    --det_model_dir=output/CCPD/det/infer \
    --det_limit_side_len=736 \
    --det_limit_type=min \
    --image_dir=/home/aistudio/test_img/ \
    --draw_img_save_dir=output 

执行完成后可看见如下输出:

[2023/03/22 16:20:51] ppocr INFO: 00379310344828-91_90-315&484_438&530-423&537_322&528_325&491_426&500-0_0_33_29_12_30_25-153-15.jpg	[[[326.0, 491.0], [422.0, 501.0], [418.0, 533.0], [322.0, 523.0]]]

[2023/03/22 16:20:51] ppocr INFO: 0 The predict time of /home/aistudio/test_img/00379310344828-91_90-315&484_438&530-423&537_322&528_325&491_426&500-0_0_33_29_12_30_25-153-15.jpg: 1.1795234680175781
[2023/03/22 16:20:51] ppocr INFO: The visualized image saved in output/det_res_00379310344828-91_90-315&484_438&530-423&537_322&528_325&491_426&500-0_0_33_29_12_30_25-153-15.jpg
# 可视化结果
import cv2
from matplotlib import pyplot as plt
%matplotlib inline

img = cv2.imread('/home/aistudio/output/det_res_blue.jpg')
plt.figure(figsize=(10, 8))
plt.imshow(img)
plt.show()

5. 针对识别文本识别模型的优化

5.1 优化方法

这里选用 PaddleOCR 中的 PP-OCRv3中的文本识别模型做为base模型,并且使用 PP-OCRv3 文本识别模型参数作为预训练模型。同样使用量化训练减小模型参数大小并加速计算

因此,本实验中对于车牌识别的优化有如下3种方案:

  1. PP-OCRv3超轻量中英文预训练模型直接检测
  2. 车牌数据集在PP-OCRv3文本检测模型上fine-tune
  3. 车牌数据集在PP-OCRv3文本检测模型上fine-tune后量化

5.2 模型训练和评估

从下表中下载PP-OCRv3文本识别预训练模型

模型名称模型简介配置文件推理模型大小下载地址
ch_PP-OCRv3_rec【最新】原始超轻量模型,支持中英文、数字识别ch_PP-OCRv3_rec_distillation.yml12.4M推理模型 / 训练模型

使用如下命令下载预训练模型

! mkdir models
%cd models
! wget https://paddleocr.bj.bcebos.com/PP-OCRv3/chinese/ch_PP-OCRv3_rec_train.tar
! tar -xf ch_PP-OCRv3_rec_train.tar
%cd /home/aistudio/PaddleOCR
5.2.1 方案1:直接识别

预训练模型下载完成后,我们使用ch_PP-OCRv3_rec_distillation.yml 配置文件进行后续实验,在开始评估之前需要对配置文件中部分字段进行设置,具体如下:

  1. Global.pretrained_model: 指向PP-OCRv3文本检测预训练模型地址
  2. Eval.dataset.data_dir:指向验证集图片存放目录
  3. Eval.dataset.label_file_list:指向验证集标注文件
  4. Eval.loader.num_workers: 验证集多进程数据读取的进程数,在aistudio中需要设为2

使用如下命令进行PP-OCRv3文本识别预训练模型的评估

! python3 tools/eval.py -c configs/rec/PP-OCRv3/ch_PP-OCRv3_rec_distillation.yml -o \
    Global.checkpoints=models/ch_PP-OCRv3_rec_train/best_accuracy.pdparams \
    Eval.dataset.data_dir=/home/aistudio/data \
    Eval.dataset.label_file_list=[/home/aistudio/data/yellow/rec_val.txt,/home/aistudio/data/CCPD2019/rec_val.txt,/home/aistudio/data/CCPD2020/rec_val.txt] \
    Eval.loader.num_workers=2

执行完成后可看见如下输出:

[2023/03/22 16:24:45] ppocr INFO: metric eval ***************
[2023/03/22 16:24:45] ppocr INFO: acc:0.003039513664613488
[2023/03/22 16:24:45] ppocr INFO: norm_edit_dis:0.8577995236688262
[2023/03/22 16:24:45] ppocr INFO: Teacher_acc:0.0017368649512077073
[2023/03/22 16:24:45] ppocr INFO: Teacher_norm_edit_dis:0.8571945501724283
[2023/03/22 16:24:45] ppocr INFO: fps:721.437846851147

使用预训练模型进行评估,指标如下所示:

方案acc
PP-OCRv3中英文超轻量识别预训练模型0.00%

从评估日志中可以看到,直接使用PP-OCRv3预训练模型进行评估,acc非常低,但是norm_edit_dis很高。因此,我们猜测是模型大部分文字识别是对的,只有少部分文字识别错误。使用如下命令进行infer查看模型的推理结果进行验证:

! python tools/infer_rec.py -c configs/rec/PP-OCRv3/ch_PP-OCRv3_rec_distillation.yml -o \
    Global.pretrained_model=models/ch_PP-OCRv3_rec_train/best_accuracy.pdparams \
    Global.infer_img=/home/aistudio/data/CCPD2020/PPOCR/test/crop_imgs/1007_0_0_3_29_29_30_28_28.jpg

执行完成后可看见如下输出:

[2023/03/22 16:25:06] ppocr INFO: infer_img: /home/aistudio/data/CCPD2020/PPOCR/test/crop_imgs/1007_0_0_3_29_29_30_28_28.jpg
[2023/03/22 16:25:07] ppocr INFO: 	 result: {"Student": {"label": "皖A·D55644", "score": 0.9129425883293152}, "Teacher": {"label": "皖A·D55644", "score": 0.9304203391075134}}
[2023/03/22 16:25:07] ppocr INFO: success!

从infer结果可以看到,车牌中的文字大部分都识别正确,只是多识别出了一个·。针对这种情况,有如下两种方案:

  1. 直接通过后处理去掉多识别的·
  2. 进行 fine-tune 。

优化后处理

直接通过后处理去掉多识别的·,在后处理的改动比较简单,只需在 ppocr/postprocess/rec_postprocess.py 文件的96行添加如下代码:

text = text.replace('·','')

改动前后指标对比:

方案acc
PP-OCRv3中英文超轻量识别预训练模型0.00%
PP-OCRv3中英文超轻量识别预训练模型+后处理去掉多识别的·86.49%

可以看到,去掉多余的·能大幅提高精度。

5.2.2 方案2:fine-tune

和评估相同,进行训练也需要对部分字段进行设置,具体如下:

  1. Global.pretrained_model: 指向PP-OCRv3文本识别预训练模型地址
  2. Global.eval_batch_step: 模型多少step评估一次,这里设为从第0个step开始没隔33个step评估一次,33为一个epoch总的step数。
  3. Optimizer.lr.name: 学习率衰减器设为常量 Const
  4. Optimizer.lr.learning_rate: 学习率设为之前的0.05倍
  5. Optimizer.lr.warmup_epoch: warmup_epoch设为0
  6. Train.dataset.data_dir:指向训练集图片存放目录
  7. Train.dataset.ratio_list: 不同数据源在每个epoch的采样率,这里设置为[1,0.16,0.005],保证黄牌+绿牌:蓝牌=1:1
  8. Train.dataset.label_file_list:指向训练集标注文件
  9. Train.loader.num_workers: 训练集多进程数据读取的进程数,在aistudio中需要设为1
  10. Eval.dataset.data_dir:指向验证集图片存放目录
  11. Eval.dataset.label_file_list:指向验证集标注文件
  12. Eval.loader.num_workers: 验证集多进程数据读取的进程数,在aistudio中需要设为0

使用如下命令启动 fine-tune

! python3.7 tools/train.py -c configs/rec/PP-OCRv3/ch_PP-OCRv3_rec_distillation.yml -o \
    Global.pretrained_model=models/ch_PP-OCRv3_rec_train/best_accuracy.pdparams \
    Global.save_model_dir=output/CCPD/rec/ \
    Global.eval_batch_step="[0, 33]" \
    Global.epoch_num=12 \
    Optimizer.lr.name=Const \
    Optimizer.lr.learning_rate=0.0005 \
    Optimizer.lr.warmup_epoch=0 \
    Train.dataset.data_dir=/home/aistudio/data \
    Train.dataset.label_file_list=[/home/aistudio/data/yellow/rec_train.txt,/home/aistudio/data/CCPD2020/rec_train.txt,/home/aistudio/data/CCPD2019/rec_train.txt] \
    Train.dataset.ratio_list=[1,0.16,0.005] \
    Eval.dataset.data_dir=/home/aistudio/data \
    Eval.dataset.label_file_list=[/home/aistudio/data/yellow/rec_val.txt,/home/aistudio/data/CCPD2020/rec_val.txt,/home/aistudio/data/CCPD2019/rec_val.txt]

训练过程中可看见如下输出:

[2023/03/22 16:32:55] ppocr INFO: epoch: [1/12], global_step: 10, lr: 0.000500, acc: 0.187500, norm_edit_dis: 0.688060, Teacher_acc: 0.183594, Teacher_norm_edit_dis: 0.706422, dml_ctc_0: 7.442299, loss: 47.262791, dml_sar_0: 2.063620, loss_distance_l2_Student_Teacher_0: 0.064135, loss_ctc_Student_0: 13.823893, loss_ctc_Teacher_1: 13.819393, loss_sar_Student_0: 4.204846, loss_sar_Teacher_1: 4.209014, avg_reader_cost: 0.25279 s, avg_batch_cost: 1.73066 s, avg_samples: 128.0, ips: 73.96009 samples/s, eta: 0:11:08
[2023/03/22 16:33:07] ppocr INFO: epoch: [1/12], global_step: 20, lr: 0.000500, acc: 0.234375, norm_edit_dis: 0.758703, Teacher_acc: 0.273437, Teacher_norm_edit_dis: 0.756089, dml_ctc_0: 6.490416, loss: 37.212910, dml_sar_0: 1.755042, loss_distance_l2_Student_Teacher_0: 0.052571, loss_ctc_Student_0: 10.867875, loss_ctc_Teacher_1: 11.178175, loss_sar_Student_0: 3.791297, loss_sar_Teacher_1: 3.802717, avg_reader_cost: 0.00046 s, avg_batch_cost: 1.23920 s, avg_samples: 128.0, ips: 103.29254 samples/s, eta: 0:09:18
[2023/03/22 16:33:20] ppocr INFO: epoch: [1/12], global_step: 30, lr: 0.000500, acc: 0.414062, norm_edit_dis: 0.821759, Teacher_acc: 0.441406, Teacher_norm_edit_dis: 0.825498, dml_ctc_0: 3.793174, loss: 30.660704, dml_sar_0: 1.543754, loss_distance_l2_Student_Teacher_0: 0.039392, loss_ctc_Student_0: 8.941044, loss_ctc_Teacher_1: 8.863680, loss_sar_Student_0: 3.622908, loss_sar_Teacher_1: 3.621634, avg_reader_cost: 0.00040 s, avg_batch_cost: 1.23127 s, avg_samples: 128.0, ips: 103.95787 samples/s, eta: 0:08:32

进行fine_tune时,在大约12epoch时指标达到最高(时间有限,可自行修改训练轮数)

评估

训练完成后使用如下命令进行评估

! python tools/eval.py -c configs/rec/PP-OCRv3/ch_PP-OCRv3_rec_distillation.yml -o \
    Global.pretrained_model=/home/aistudio/PaddleOCR/output/CCPD/rec/best_accuracy.pdparams \
    Eval.dataset.data_dir=/home/aistudio/data \
    Eval.dataset.label_file_list=[/home/aistudio/data/yellow/rec_val.txt,/home/aistudio/data/CCPD2020/rec_val.txt,/home/aistudio/data/CCPD2019/rec_val.txt]

执行完成后可看见如下输出:

[2023/03/22 16:48:43] ppocr INFO: metric eval ***************
[2023/03/22 16:48:43] ppocr INFO: acc:0.9218410728534907
[2023/03/22 16:48:43] ppocr INFO: norm_edit_dis:0.9828139970006491
[2023/03/22 16:48:43] ppocr INFO: Teacher_acc:0.9036039908658098
[2023/03/22 16:48:43] ppocr INFO: Teacher_norm_edit_dis:0.9804214999919667
[2023/03/22 16:48:43] ppocr INFO: fps:724.4679140632986

使用预训练模型和fine-tune,指标分别如下:

方案acc
PP-OCRv3中英文超轻量识别预训练模型0.00%
PP-OCRv3中英文超轻量识别预训练模型+后处理去掉多识别的·86.49%
PP-OCRv3中英文超轻量识别预训练模型 fine-tune92.18%

可以看到进行fine-tune能显著提升车牌识别的效果。

5.2.3 量化训练

要是想在端侧设备上进行部署,我们还需要对模型进行量化以提升模型的运行速度并降低模型体积。

此处使用PACT在线量化进行训练,如果需要在线量化训练可通过如下命令启动:


! python3.7 deploy/slim/quantization/quant.py -c configs/rec/PP-OCRv3/ch_PP-OCRv3_rec_distillation.yml -o \
    Global.pretrained_model=output/CCPD/rec_distillation/best_accuracy.pdparams \
    Global.save_model_dir=output/CCPD/rec_distillation_quant/ \
    Global.eval_batch_step="[0, 33]" \
    Optimizer.lr.name=Const \
    Optimizer.lr.learning_rate=0.0005 \
    Optimizer.lr.warmup_epoch=0 \
    Train.dataset.data_dir=/home/aistudio/data \
    Train.dataset.label_file_list=[/home/aistudio/data/yellow/rec_train.txt,/home/aistudio/data/CCPD2020/rec_train.txt,/home/aistudio/data/CCPD2019/rec_train.txt] \
    Train.dataset.ratio_list=[1,0.16,0.005] \
    Train.loader.batch_size_per_card=64 \
    Eval.dataset.data_dir=/home/aistudio/data \
    Eval.dataset.label_file_list=[/home/aistudio/data/yellow/rec_val.txt,/home/aistudio/data/CCPD2020/rec_val.txt,/home/aistudio/data/CCPD2019/rec_val.txt] \
    Eval.loader.batch_size_per_card=64

量化后指标对比如下:

方案acc模型大小预测速度(android)
PP-OCRv3中英文超轻量识别预训练模型 fine-tune92.14%11.0m4.2ms
PP-OCRv3中英文超轻量识别预训练模型 fine-tune + 量化90.31%4.9m1.8ms

量化后能降低模型体积53%并且推理速度提升57%,但是由于识别数据过少,量化带来了1%的精度下降。

5.3 模型推理

(此处使用非量化模型)

在实际部署中,我们需要将动态图训练的模型转换为静态图模型进行推理,使用如下命令可以将训练好的模型导出为静态图模型:


# 量化模型
! python deploy/slim/quantization/export_model.py -c configs/rec/PP-OCRv3/ch_PP-OCRv3_rec_distillation.yml -o \
    Global.pretrained_model=output/CCPD/rec_distillation_quant/best_accuracy.pdparams \
    Global.save_inference_dir=output/CCPD/rec_distillation_quant/infer \
    Eval.dataset.data_dir=/home/aistudio/data \
    Eval.dataset.label_file_list=[/home/aistudio/data/yellow/rec_val.txt,/home/aistudio/data/CCPD2020/rec_val.txt,/home/aistudio/data/CCPD2019/rec_val.txt]
#非量化模型
! python tools/export_model.py -c configs/rec/PP-OCRv3/ch_PP-OCRv3_rec_distillation.yml -o \
    Global.pretrained_model=/home/aistudio/PaddleOCR/output/CCPD/rec/best_accuracy.pdparams \
    Global.save_inference_dir=output/CCPD/rec_distillation/infer


执行完成后可看见如下输出:

[2023/03/22 16:51:53] ppocr INFO: inference model is saved to output/CCPD/rec_distillation/infer/Teacher/inference
[2023/03/22 16:51:55] ppocr INFO: inference model is saved to output/CCPD/rec_distillation/infer/Student/inference

导出后的模型,使用如下命令可使用预测引擎对单张图片进行推理:

! python3 tools/infer/predict_rec.py \
    --rec_model_dir=/home/aistudio/PaddleOCR/output/CCPD/rec_distillation/infer/Student/ \
    --image_dir=/home/aistudio/rec.jpg

执行完成后可看见如下输出:

[2023/03/22 16:57:34] ppocr INFO: Predicts of /home/aistudio/rec.jpg:('皖AD65516', 0.9506336450576782)

6. 串联推理

检测模型和识别模型分别fine-tune并导出为inference模型之后,可以使用如下命令进行端到端推理。

! python3 tools/infer/predict_system.py \
    --det_model_dir=output/CCPD/det/infer \
    --rec_model_dir=output/CCPD/rec_distillation/infer/Teacher \
    --det_limit_side_len=736 \
    --det_limit_type=min \
    --image_dir=/home/aistudio/test_img/ \
    --draw_img_save_dir=output

执行完成后可看见如下输出:

[2023/03/22 17:02:05] ppocr DEBUG: dt_boxes num : 1, elapse : 1.1589457988739014
[2023/03/22 17:02:06] ppocr DEBUG: rec_res num  : 1, elapse : 0.46366143226623535
[2023/03/22 17:02:06] ppocr DEBUG: 0  Predict time of /home/aistudio/test_img/00379310344828-91_90-315&484_438&530-423&537_322&528_325&491_426&500-0_0_33_29_12_30_25-153-15.jpg: 1.626s
[2023/03/22 17:02:06] ppocr DEBUG: 皖A95N61, 0.948
[2023/03/22 17:02:06] ppocr DEBUG: The visualized image saved in output/00379310344828-91_90-315&484_438&530-423&537_322&528_325&491_426&500-0_0_33_29_12_30_25-153-15.jpg
[2023/03/22 17:02:06] ppocr INFO: The predict total time is 1.7099494934082031

7. 实验总结

我们分别使用PP-OCRv3中英文超轻量预训练模型在车牌数据集上进行了直接评估和 fine-tune 和 fine-tune +量化3种方案的实验,指标对比如下:

  • 检测
方案hmeans模型大小预测速度(android)
PP-OCRv3中英文超轻量检测预训练模型直接预测67.08%2.6M233ms
PP-OCRv3中英文超轻量检测预训练模型 fine-tune99.50%2.6M233ms
PP-OCRv3中英文超轻量检测预训练模型 fine-tune + 量化99.80%1.1M189ms
  • 识别
方案acc模型大小预测速度(android)
PP-OCRv3中英文超轻量识别预训练模型直接预测0.00%11.0M4.2ms
PP-OCRv3中英文超轻量识别预训练模型直接预测+后处理去掉多识别的·86.49%11.0M4.2ms
PP-OCRv3中英文超轻量识别预训练模型 fine-tune92.18%11.0M4,2ms
PP-OCRv3中英文超轻量识别预训练模型 fine-tune + 量化90.31%4.9M1.8ms

结论

PP-OCRv3的检测模型在未经过fine-tune的情况下,精度和经过 fine-tune 后又较大差距。在使用量化训练后检测模型的精度几乎无损,并且模型大小压缩57%。

PP-OCRv3的识别模型在未经过fine-tune的情况下,在车牌数据集上精度为0%,但是经过分析可以知道,模型大部分字符都预测正确,但是会多预测一个特殊字符,去掉这个特殊字符后,精度就提高了很多。PP-OCRv3识别模型在经过 fine-tune 后识别精度进一步提升。在使用量化训练后识别模型大小压缩55%,精度轻微损失。
本次也参考了很多大佬的项目,也又查看PaddleOCR的文档等,通过这次项目经验,也是学到了很多新的知识和BUG,希望和大家一起进步,由于本人备考研究生,没有太多时间训练所以也请见谅。

参考项目和文献:

【1】模型量化(2):Paddle 模型的静态量化和动态量化:https://aistudio.baidu.com/aistudio/projectdetail/3924444?channel=0&channelType=0&sUid=2281900&shared=1&ts=1679477014286

【2】PaddleOCR:车牌识别:https://aistudio.baidu.com/aistudio/projectdetail/739559?channel=0&channelType=0&sUid=2281900&shared=1&ts=1679477041726

【3】十分钟掌握PaddleOCR使用:https://aistudio.baidu.com/aistudio/projectdetail/467229?channel=0&channelType=0&sUid=2281900&shared=1&ts=1679477090416

【4】https://github.com/PaddlePaddle/PaddleOCR/blob/dygraph/tools/end2end/readme.md

【5】https://github.com/PaddlePaddle/PaddleOCR/tree/dygraph

导师:顾茜老师

学员:罗宏立

感谢老师指导,再接再厉

此文章为转载
原文链接

Logo

学大模型,用大模型上飞桨星河社区!每天8点V100G算力免费领!免费领取ERNIE 4.0 100w Token >>>

更多推荐