OCR发票关键信息抽取-模型训练

273 阅读6分钟

1. 项目背景及意义

关键信息抽取在文档场景中被广泛使用,如身份证中的姓名、住址信息抽取,快递单中的姓名、联系方式等关键字段内容的抽取。传统基于模板匹配的方案需要针对不同的场景制定模板并进行适配,较为繁琐,不够鲁棒。基于该问题,我们借助飞桨提供的PaddleOCR套件中的关键信息抽取方案,实现对增值税发票场景的关键信息抽取。

2. 项目内容

本项目基于PaddleOCR开源套件,以VI-LayoutXLM多模态关键信息抽取模型为基础,针对增值税发票场景进行适配,提取该场景的关键信息。

3. 安装环境

import os
os.chdir("/home/aistudio/")
# 首先git官方的PaddleOCR项目,安装需要的依赖
# 第一次运行打开该注释
!git clone https://gitee.com/PaddlePaddle/PaddleOCR.git
os.chdir("/home/aistudio/PaddleOCR/")
!pip uninstall opencv-python -y
# 安装PaddleOCR的依赖
!pip install -r requirements.txt
# 安装关键信息抽取任务的依赖
!pip install -r ./ppstructure/kie/requirements.txt

4. 关键信息抽取

基于文档图像的关键信息抽取包含3个部分:(1)文本检测(2)文本识别(3)关键信息抽取方法,包括语义实体识别或者关系抽取,下面分别进行介绍。

4.1 文本检测

本文重点关注发票的关键信息抽取模型训练与预测过程,因此在关键信息抽取过程中,直接使用标注的文本检测与识别标注信息进行测试,如果你希望自定义该场景的文本检测模型,完成端到端的关键信息抽取部分,请参考文本检测模型训练教程,按照训练数据格式准备数据,并完成该场景下垂类文本检测模型的微调过程。

4.2 文本识别

本文重点关注发票的关键信息抽取模型训练与预测过程,因此在关键信息抽取过程中,直接使用提供的文本检测与识别标注信息进行测试,如果你希望自定义该场景的文本检测模型,完成端到端的关键信息抽取部分,请参考文本识别模型训练教程,按照训练数据格式准备数据,并完成该场景下垂类文本识别模型的微调过程。

4.3 语义实体识别 (Semantic Entity Recognition)

语义实体识别指的是给定一段文本行,确定其类别(如姓名住址等类别)。PaddleOCR中提供了基于VI-LayoutXLM的多模态语义实体识别方法,融合文本、位置与版面信息,相比LayoutXLM多模态模型,去除了其中的视觉骨干网络特征提取部分,引入符合阅读顺序的文本行排序方法,同时使用UDML联合互蒸馏方法进行训练,最终在精度与速度方面均超越LayoutXLM。更多关于VI-LayoutXLM的算法介绍与精度指标,请参考:VI-LayoutXLM算法介绍

4.3.1 准备数据

发票场景为例,我们首先需要标注出其中的关键字段,我们将其标注为问题-答案的key-value pair,如下,编号No为12270830,则No字段标注为question,12270830字段标注为answer。如下图所示。

注意:

  • 如果文本检测模型数据标注过程中,没有标注 非关键信息内容 的检测框,那么在标注关键信息抽取任务的时候,也不需要标注该部分,如上图所示;如果标注的过程,如果同时标注了非关键信息内容 的检测框,那么我们需要将该部分的label记为other。
  • 标注过程中,需要以文本行为单位进行标注,无需标注单个字符的位置信息。

已经处理好的增值税发票数据集从这里下载:增值税发票数据集下载链接

讲数据集解压在train_data目录下,命令如下。

!tar -xf /home/aistudio/data/data165561/zzsfp.tar
!mkdir train_data
!mv zzsfp train_data/
mkdir: 无法创建目录"train_data": 文件已存在

目录结构如下所示。

train_data
  |--zzsfp
       |---class_list.txt
       |---imgs/
       |---train.json
       |---val.json

其中class_list.txt是包含otherquestionanswer,3个种类的的类别列表(不区分大小写),imgs目录底下,train.jsonval.json分别表示训练与评估集合的标注文件。训练集中包含30张图片,验证集中包含8张图片。部分标注如下所示。

b33.jpg [{"transcription": "No", "label": "question", "points": [[2882, 472], [3026, 472], [3026, 588], [2882, 588]], }, {"transcription": "12269563", "label": "answer", "points": [[3066, 448], [3598, 448], [3598, 576], [3066, 576]], ]}]

相比于OCR检测的标注,仅多了label字段。

4.3.2 开始训练

VI-LayoutXLM的配置为ser_vi_layoutxlm_xfund_zh_udml.yml,需要修改数据、类别数目以及配置文件。

Architecture:
  model_type: &model_type "kie"
  name: DistillationModel
  algorithm: Distillation
  Models:
    Teacher:
      pretrained:
      freeze_params: false
      return_all_feats: true
      model_type: *model_type
      algorithm: &algorithm "LayoutXLM"
      Transform:
      Backbone:
        name: LayoutXLMForSer
        pretrained: True
        # one of base or vi
        mode: vi
        checkpoints:
        # 定义类别数目
        num_classes: &num_classes 5
   ...
PostProcess:
  name: DistillationSerPostProcess
  model_name: ["Student", "Teacher"]
  key: backbone_out
  # 定义类别文件
  class_path: &class_path train_data/zzsfp/class_list.txt
Train:
  dataset:
    name: SimpleDataSet
    # 定义训练数据目录与标注文件
    data_dir: train_data/zzsfp/imgs
    label_file_list:
      - train_data/zzsfp/train.json
  ...
Eval:
  dataset:
    # 定义评估数据目录与标注文件
    name: SimpleDataSet
    data_dir: train_data/zzsfp/imgs
    label_file_list:
      - train_data/zzsfp/val.json
  ...

示例配置文件存储在文件/home/aistudio/work/ser_vi_layoutxlm_udml.yaml中。运行下面的命令可以完成训练过程。

!python tools/train.py -c /home/aistudio/work/ser_vi_layoutxlm_udml.yml
or
!python tools/train.py -c D:\aistudio\work\ser_vi_layoutxlm_udml.yaml

最终在output目录下面会生成保存的预训练模型。

我们对LayoutXLM与VI-LayoutXLM均进行训练,精度对比如下。

模型迭代轮数Hmean
LayoutXLM50100%
VI-LayoutXLM50100%

可以看出,由于当前数据量较少,场景比较简单,因此2个模型的Hmean均达到了100%。

4.3.3 模型评估

模型训练过程中,使用的是知识蒸馏的策略,最终保留了学生模型的参数,在评估时,我们需要针对学生模型的配置文件进行修改,这里保存在:/home/aistudio/work/ser_vi_layoutxlm.yml,修改内容与训练配置相同,包括类别数、类别映射文件、数据目录

4.3.4 注意点

use_gpu 设置为 False 时关闭gpu训练,使用cpu

降级 PaddlePaddle,

paddle.fluid 模块在 PaddlePaddle 2.6.0 及以上版本中已经被移除。这导致了 PaddleOCR 在加载相关模块时无法找到 paddle.fluid

pip uninstall paddlepaddle-gpu
pip install paddlepaddle-gpu==2.5.2

或
pip uninstall paddlepaddle
pip install  -i https://pypi.tuna.tsinghua.edu.cn/simple --trusted-host pypi.tuna.tsinghua.edu.cn     paddlepaddle==2.5.2