NLP实战:快递单信息抽取-基于ERNIE1.0 预训练模型

2023-05-16

目录

一、介绍

二、代码

2.1前期准备

2.2加载自定义数据集

 2.3数据处理

2.4数据读入

2.5PaddleNLP一键加载预训练模型

2.6设置Fine-Tune优化策略,模型配置

2.7模型训练与评估

​编辑

2.8模型预测

三、总结

原文:


一、介绍

命名实体识别(Named Entity Recognition,简称NER)是自然语言处理(NLP)中的一项任务,目的是识别文本中的命名实体并将其分类为预定义的类别,如人名、地名、组织机构等。命名实体通常指具有独特标识的实体,这些实体在文本中出现时通常会带有特殊的上下文信息。

命名实体识别在很多自然语言处理任务中都是非常重要的预处理步骤,如信息提取、机器翻译、问题回答等。通过对文本中的命名实体进行识别和分类,可以更好地理解文本的含义和结构,为后续的处理任务提供更多的语义信息。

常用的命名实体分类包括人名、地名、组织机构名、日期、时间、货币等,分类的具体数量和类别可以根据不同的应用场景进行调整。

本项目将演示如何使用PaddleNLP语义预训练模型ERNIE完成从快递单中抽取姓名、电话、省、市、区、详细地址等内容,形成结构化信息。辅助物流行业从业者进行有效信息的提取,从而降低客户填单的成本。

2017年之前,对文本处理主要依赖于序列模型Recurrent Neural Network (RNN).

基于BiGRU+CRF的快递单信息抽取项目介绍了如何使用序列模型完成快递单信息抽取任务。

随着深度学习的发展,模型参数数量迅速增加。为了训练这些参数,需要更大的数据集,但对于大部分NLP任务,构建大规模标注数据集很难且成本高。相反,大规模未标注语料库的构建相对容易。因此,我们可以利用这些数据先学习到好的表示,再将其用于其他任务中。最近的研究表明,基于大规模未标注语料库的预训练模型(Pretrained Models, PTM)在NLP任务中表现出色。现在,随着计算能力和训练技巧的提高,PTM也得以不断发展和进步。

本示例展示了以ERNIE(Enhanced Representation through Knowledge Integration)为代表的预训练模型如何Finetune完成序列标注任务。

二、代码

在百度飞桨平台的CodeLab跑就行,类似于Google的colab平台。

2.1前期准备

安装环境

pip install --upgrade paddlenlp
# 下载并解压数据集
from paddle.utils.download import get_path_from_url
URL = "https://paddlenlp.bj.bcebos.com/paddlenlp/datasets/waybill.tar.gz"
get_path_from_url(URL, "./")

# 查看预测的数据
!head -n 5 data/test.txt

from functools import partial

import paddle
from paddlenlp.datasets import MapDataset
from paddlenlp.data import Stack, Tuple, Pad
from paddlenlp.transformers import ErnieTokenizer, ErnieForTokenClassification
from paddlenlp.metrics import ChunkEvaluator
from utils import convert_example, evaluate, predict, load_dict

2.2加载自定义数据集

推荐使用MapDataset()自定义数据集。

def load_dataset(datafiles):
    def read(data_path):
        with open(data_path, 'r', encoding='utf-8') as fp:
            next(fp)  # Skip header
            for line in fp.readlines():
                words, labels = line.strip('\n').split('\t')
                words = words.split('\002')
                labels = labels.split('\002')
                yield words, labels

    if isinstance(datafiles, str):
        return MapDataset(list(read(datafiles)))
    elif isinstance(datafiles, list) or isinstance(datafiles, tuple):
        return [MapDataset(list(read(datafile))) for datafile in datafiles]

# Create dataset, tokenizer and dataloader.
train_ds, dev_ds, test_ds = load_dataset(datafiles=(
        './data/train.txt', './data/dev.txt', './data/test.txt'))
for i in range(5):
    print(train_ds[i])

每条数据包含一句文本和这个文本中每个汉字以及数字对应的label标签。

之后,还需要对输入句子进行数据处理,如切词,映射词表id等。

 2.3数据处理

预训练模型ERNIE对中文数据的处理是以字为单位。PaddleNLP对于各种预训练模型已经内置了相应的tokenizer。指定想要使用的模型名字即可加载对应的tokenizer。

tokenizer作用为将原始输入文本转化成模型model可以接受的输入数据形式。

label_vocab = load_dict('./data/tag.dic')
tokenizer = ErnieTokenizer.from_pretrained('ernie-1.0')

trans_func = partial(convert_example, tokenizer=tokenizer, label_vocab=label_vocab)

train_ds.map(trans_func)
dev_ds.map(trans_func)
test_ds.map(trans_func)
print (train_ds[0])

2.4数据读入

使用paddle.io.DataLoader接口多线程异步加载数据。

ignore_label = -1
batchify_fn = lambda samples, fn=Tuple(
    Pad(axis=0, pad_val=tokenizer.pad_token_id),  # input_ids
    Pad(axis=0, pad_val=tokenizer.pad_token_type_id),  # token_type_ids
    Stack(),  # seq_len
    Pad(axis=0, pad_val=ignore_label)  # labels
): fn(samples)

train_loader = paddle.io.DataLoader(
    dataset=train_ds,
    batch_size=36,
    return_list=True,
    collate_fn=batchify_fn)
dev_loader = paddle.io.DataLoader(
    dataset=dev_ds,
    batch_size=36,
    return_list=True,
    collate_fn=batchify_fn)
test_loader = paddle.io.DataLoader(
    dataset=test_ds,
    batch_size=36,
    return_list=True,
    collate_fn=batchify_fn)

2.5PaddleNLP一键加载预训练模型

快递单信息抽取本质是一个序列标注任务,PaddleNLP对于各种预训练模型已经内置了对于下游任务文本分类Fine-tune网络。以下教程以ERNIE为预训练模型完成序列标注任务。

paddlenlp.transformers.ErnieForTokenClassification()一行代码即可加载预训练模型ERNIE用于序列标注任务的fine-tune网络。其在ERNIE模型后拼接上一个全连接网络进行分类。

paddlenlp.transformers.ErnieForTokenClassification.from_pretrained()方法只需指定想要使用的模型名称和文本分类的类别数即可完成定义模型网络。

# Define the model netword and its loss
model = ErnieForTokenClassification.from_pretrained("ernie-1.0", num_classes=len(label_vocab))

PaddleNLP不仅支持ERNIE预训练模型,还支持BERT、RoBERTa、Electra等预训练模型。 下表汇总了目前PaddleNLP支持的各类预训练模型。您可以使用PaddleNLP提供的模型,完成文本分类、序列标注、问答等任务。同时我们提供了众多预训练模型的参数权重供用户使用,其中包含了二十多种中文语言模型的预训练权重。中文的预训练模型有bert-base-chinese, bert-wwm-chinese, bert-wwm-ext-chinese, ernie-1.0, ernie-tiny, gpt2-base-cn, roberta-wwm-ext, roberta-wwm-ext-large, rbt3, rbtl3, chinese-electra-base, chinese-electra-small, chinese-xlnet-base, chinese-xlnet-mid, chinese-xlnet-large, unified_transformer-12L-cn, unified_transformer-12L-cn-luge等。

更多预训练模型参考:PaddleNLP Transformer API。

更多预训练模型fine-tune下游任务使用方法,请参考:examples。

2.6设置Fine-Tune优化策略,模型配置

适用于ERNIE/BERT这类Transformer模型的迁移优化学习率策略为warmup的动态学习率。

metric = ChunkEvaluator(label_list=label_vocab.keys(), suffix=True)
loss_fn = paddle.nn.loss.CrossEntropyLoss(ignore_index=ignore_label)
optimizer = paddle.optimizer.AdamW(learning_rate=2e-5, parameters=model.parameters())

2.7模型训练与评估

模型训练的过程通常有以下步骤:

  1. 从dataloader中取出一个batch data
  2. 将batch data喂给model,做前向计算
  3. 将前向计算结果传给损失函数,计算loss。将前向计算结果传给评价方法,计算评价指标。
  4. loss反向回传,更新梯度。重复以上步骤。

每训练一个epoch时,程序将会评估一次,评估当前模型训练的效果。

step = 0
for epoch in range(10):
    for idx, (input_ids, token_type_ids, length, labels) in enumerate(train_loader):
        logits = model(input_ids, token_type_ids)
        loss = paddle.mean(loss_fn(logits, labels))
        loss.backward()
        optimizer.step()
        optimizer.clear_grad()
        step += 1
        print("epoch:%d - step:%d - loss: %f" % (epoch, step, loss))
    evaluate(model, metric, dev_loader)

    paddle.save(model.state_dict(),
                './ernie_result/model_%d.pdparams' % step)
# model.save_pretrained('./checkpoint')
# tokenizer.save_pretrained('./checkpoint')

 

训练十轮,由于没有gpu所以有点慢运行的(6124秒hhh)。

2.8模型预测

训练保存好的模型,即可用于预测。如以下示例代码自定义预测数据,调用predict()函数即可一键预测。

preds = predict(model, test_loader, test_ds, label_vocab)
file_path = "ernie_results.txt"
with open(file_path, "w", encoding="utf8") as fout:
    fout.write("\n".join(preds))
# Print some examples
print(
    "The results have been saved in the file: %s, some examples are shown below: "
    % file_path)
print("\n".join(preds[:10]))

三、总结

ERNIE是百度提出的一种基于持续学习技术的语义理解框架,该框架结合了大规模数据的预训练和多源知识的增强,能够不断吸收来自海量文本数据的语言信息,从而不断提升模型的效果。ERNIE在多个典型的NLP任务上取得了最好的结果,并在多个国际权威评测中获得了多项冠军。ERNIE技术获得了多个荣誉,包括中国人工智能学会优秀科技成果奖和世界人工智能大会最高荣誉SAIL奖。ERNIE在工业界也得到了广泛应用,例如搜索引擎、新闻推荐、广告系统、语音交互和智能客服等领域。全球顶级科技商业杂志《麻省理工科技评论》也报道了ERNIE相关的创新成果,相关技术也被国际顶级学术会议收录。

可以看出ernir1.0在实体抽取项目上准确率高达99%,看得出预训练模型将会是未来的主流。


原文:

飞桨AI Studio - 人工智能学习与实训社区

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

NLP实战:快递单信息抽取-基于ERNIE1.0 预训练模型 的相关文章

  • 高翔ORB-SLAM2稠密建图编译(添加实时彩色点云地图+保存点云地图)

    目录 前言系统版本 一 准备工作下载源码 二 编译 build sh1 删除一些build文件夹2 创建 Vocabulary 文件夹3 在CMakeLists txt中取消编译器的一些设置4 编译5 运行TUM数据集6 实时查看彩色点云地
  • 使用D435i相机跑ORB-SLAM2_RGBD_DENSE_MAP-master稠密建图编译(实时彩色点云地图加回环+保存点云地图)

    目录 前言系统版本 一 准备工作下载源码 二 编译 build sh1 删除一些build文件夹2 创建 Vocabulary 文件夹3 编译1 xff09 错误1 4 解决 段错误 xff08 核心已转储 xff09 改动一改动二 5 v
  • SLAM数据集TUM,KITTI,EuRoC数据集的下载地址与真实轨迹文件的查找

    目录 前言一 TUM数据集1 下载地址2 真实轨迹文件的查找3 轨迹格式 二 KITTI数据集1 下载地址2 真实轨迹文件的查找 三 EuRoC数据集1 下载地址2 真实轨迹文件的查找3 轨迹格式 前言 在SLAM的学习过程中 xff0c
  • 镭神16线激光雷达使用

    目录 一 创建工作空间二 进入src 下载驱动三 编译四 修改IP五 查看激光雷达点云 一 创建工作空间 span class token function mkdir span p leishen ws src 二 进入src 下载驱动
  • 使用D435i相机录制TUM格式的数据集

    目录 前言系统版本 一 使用realsense SDK录制bag包的情况1 录制视频2 提取rgb和depth图片1 2 3 对齐时间戳 二 用realsense ros打开相机录制bag包1 将深度图对齐到RGB2 使用realsense
  • 使用MeshLab软件处理pcd点云文件

    目录 前言1 安装MeshLab软件2 利用pcl库将pcd文件转成ply文件3 利用MeshLab旋转ply点云4 将ply文件转为pcd文件5 将ply文件转为pcd文件 xff08 添加读取配置文件版本 xff09 前言 在使用D43
  • 用C/C++读取配置文件的小例子

    这里提供了一个用C C 43 43 读取配置文件的简单框架 xff0c 具体内容可以依据自己的需要修改 GitHub上面的链接 xff1a https github com YuanpengDuan read config 新建一个文件夹
  • 洛谷P1080 [NOIP2012 提高组] 国王游戏

    此题用到的算法有贪心和高精度计算 高精度 高精度真的太折磨人了 xff0c 我搞了好久好久 xff08 PS xff1a python可跳过这一步 xff0c 它自带高精度 一开始我想用long long 但这个数据长度已经超过long l
  • Python中统一快速更换变量的名称

    首先 xff0c 选中需要更改的变量名称 xff0c 其次按下 Ctrl 43 R xff0c 就会出现如下的界面 其次输入你要替换成的变量名字 例如下方截图 xff0c 我要将num替换为str1 最后 xff0c 点击 Replace
  • Linux Qt程序打包

    前言 当我们在linux系统上开发一些工具时 xff0c 想快速分发给相关人员使用时 xff0c 我们可以把开发的相关依赖进行打包 xff0c 然后分发使用 xff0c 其中打包过程中遇到一些问题 xff0c 在没有安装Qt的机器上运行回报
  • word转pdf保持图片清晰度

    今天写论文的遇到两个问题 1 word插入的图片清晰度不够高 xff0c 放大之后不清晰了 2 word里面清晰度高 xff0c 但是转pdf之后放大不清晰了 问题1解决办法 xff1a word中 gt 插入图片 gt 右键选择图片 按照
  • c++字符串连接函数strcat_s

    格式 int a 100 61 0 int b 100 61 0 strcat s a b 功能 把字符数组2 b 连到字符数组1 a 后面 字符数组1必须足够大 连接前两串以 0 结束
  • Python语音合成探究(二、朗读文本的编码问题)

    语音合成时 xff0c 选取的朗读文本大多是网上收集来的TXT 文件 xff0c 有些文件会因为编码原因打开不了 xff0c 程序运行出错 如同样是 离骚 txt 文档 xff0c 用 with open 39 离骚 txt 39 as f
  • 关于Windows上的Android子系统安装

    Win11早些时候的版本公式里展示的安卓系统 Windows Subsystem for Android 简称WSA xff0c 现在可以在电脑中使用 xff0c 过了一年多的时间才想起还有个这种功能 xff0c 在安装时也是发现一些小细节
  • 大一上学期C++课程设计——学生成绩管理系统(QT项目)

    这里是一个大一的萌新 xff01 仅做学习分享 工程文件在评论区置顶 xff01 xff01 近期整理了一下大一上学期的课程设计报告作为学习总结 xff0c 使用的软件是Qt Creator xff0c 主界面效果如下图 QT具体环境如下图
  • 单片机控制直流电机(风扇)电路详解

    单片机引脚为什么无法直接控制电机或风扇 xff1f 我们在使用单片机去控制 43 5V的直流电机或者散热风扇时 xff0c 可能会有一种疑惑 xff0c 51单片机的引脚电压为 43 5V xff0c 为什么不直接用单片机引脚去驱动电机或者
  • [NOIP2002 普及组] 过河卒

    题目描述 棋盘上 AA 点有一个过河卒 xff0c 需要走到目标 BB 点 卒行走的规则 xff1a 可以向下 或者向右 同时在棋盘上 CC 点有一个对方的马 xff0c 该马所在的点和所有跳跃一步可达的点称为对方马的控制点 因此称之为 马
  • Qt学习笔记(5)

    目录 一 菜单栏 MenuBar 二 工具栏 ToolBar 三 状态栏 StatusBar 四 浮动窗口 DockWidget 五 右键菜单 六 托盘菜单 一 菜单栏 MenuBar 只能有一个 创建的最上方 菜单栏有两种方式可以创建 x
  • ftp 命令访问 ftp服务器

    服务端与客户端 登录到FTP服务器时 xff0c 你可以看到服务端的文件 xff0c 这个时候就要有一个区分 xff0c 一个是服务端 xff0c 一个是客户端 xff0c 你发起连接的这台电脑就叫做客户端 xff0c 要连接的FTP服务器
  • day13-面向对象3

    一 私有权限 封装的意义 xff1a 将属性和方法放到一起做为一个整体 xff0c 然后通过实例化对象来处理 xff1b 隐藏内部实现细节 xff0c 只需要和对象及其属性和方法交互就可以了 xff1b 对类的属性和方法增加 访问权限控制

随机推荐