本项目链接: PaddleNLP基于ERNIR3.0文本分类任务详解【多分类(单标签)】
0.前言:文本分类任务介绍
文本分类任务是自然语言处理中最常见的任务,文本分类任务简单来说就是对给定的一个句子或一段文本使用文本分类器进行分类。文本分类任务广泛应用于长短文本分类、情感分析、新闻分类、事件类别分类、政务数据分类、商品信息分类、商品类目预测、文章分类、论文类别分类、专利分类、案件描述分类、罪名分类、意图分类、论文专利分类、邮件自动标签、评论正负识别、药物反应分类、对话分类、税种识别、来电信息自动分类、投诉分类、广告检测、敏感违法内容检测、内容安全检测、舆情分析、话题标记等各类日常或专业领域中。
文本分类任务可以根据标签类型分为多分类(multi class)、多标签(multi label)、层次分类(hierarchical等三类任务,接下来我们将以下图的新闻文本分类为例介绍三种分类任务的区别。
PaddleNLP采用AutoModelForSequenceClassification, AutoTokenizer提供了方便易用的接口,可指定模型名或模型参数文件路径通过from_pretrained() 方法加载不同网络结构的预训练模型,并在输出层上叠加一层线性层,且相应预训练模型权重下载速度快、稳定。Transformer预训练模型汇总包含了如 ERNIE、BERT、RoBERTa等40多个主流预训练模型,500多个模型权重。下面以ERNIE 3.0 中文base模型为例,演示如何加载预训练模型和分词器:
代码语言:javascript复制from paddlenlp.transformers import AutoModelForSequenceClassification, AutoTokenizer
num_classes = 10
model_name = "ernie-3.0-base-zh"
model = AutoModelForSequenceClassification.from_pretrained(model_name, num_classes=num_classes)
tokenizer = AutoTokenizer.from_pretrained(model_name)
1.数据准备
1.1加载数据集、自定义数据集
通过使用PaddleNLP提供的 load_dataset, MapDataset 和 IterDataset ,可以方便的自定义属于自己的数据集。
目前PaddleNLP的通用数据处理流程如下:
- 加载数据集(内置数据集或者自定义数据集,数据集返回 原始数据)。
- 定义 trans_func() ,包括tokenize,token to id等操作,并传入数据集的 map() 方法,将原始数据转为 feature 。
- 根据上一步数据处理的结果定义 batchify 方法和 BatchSampler 。
- 定义 DataLoader , 传入 BatchSampler 和 batchify_fn() 。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wbNrr5ET-1658889546447)(https://ai-studio-static-online.cdn.bcebos.com/14804601029a44afa00a1e6f5255494ba419a581f94a4e04a7bad3b6be8a1d52)]
PaddleNLP Datasets API:供参考
PaddleNLP提供了以下数据集的快速读取API,实际使用时请根据需要添加splits信息:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eXtI9MIu-1658889546448)(https://ai-studio-static-online.cdn.bcebos.com/499101cb11644d33861d326c304dd994328c4de2d57e4d548b0670e60ddbfff0)]
加载数据集
快速加载内置数据集 目前PaddleNLP内置20余个NLP数据集,涵盖阅读理解,文本分类,序列标注,机器翻译等多项任务。目前提供的数据集可以在 数据集列表 中找到。
以 msra_ner 数据集为例:
load_dataset() 方法会从 paddlenlp.datasets 下找到msra_ner数据集对应的数据读取脚本(默认路径:paddlenlp/datasets/msra_ner.py),并调用脚本中 DatasetBuilder 类的相关方法生成数据集。
生成数据集可以以 MapDataset 和 IterDataset 两种类型返回,分别是对 paddle.io.Dataset 和 paddle.io.IterableDataset 的扩展,只需在 load_dataset() 时设置 lazy 参数即可获取相应类型。Flase 对应返回 MapDataset ,True 对应返回 IterDataset,默认值为None,对应返回 DatasetBuilder 默认的数据集类型,大多数为 MapDataset
1.1.1以内置数据集格式读取本地数据集
有的时候,我们希望使用数据格式与内置数据集相同的本地数据替换某些内置数据集的数据(例如参加SQuAD竞赛,对训练数据进行了数据增强)。 load_dataset() 方法提供的 data_files参数可以实现这个功能。以 SQuAD 为例。
代码语言:javascript复制 from paddlenlp.datasets import load_dataset
train_ds, dev_ds = load_dataset("squad", data_files=("my_train_file.json", "my_dev_file.json"))
test_ds = load_dataset("squad", data_files="my_test_file.json")
注解
对于某些数据集,不同的split的读取方式不同。对于这种情况则需要在 splits 参数中以传入与 data_files 一一对应 的split信息。
此时 splits 不再代表选取的内置数据集,而代表以何种格式读取本地数据集。
下面以 COLA 数据集为例:
代码语言:javascript复制from paddlenlp.datasets import load_dataset
train_ds, test_ds = load_dataset("glue", "cola", splits=["train", "test"], data_files=["my_train_file.csv", "my_test_file.csv"])
另外需要注意数据集的是没有默认加载选项的,splits 和data_files 必须至少指定一个。
这个方法还是比较简单的
需要注意的是格式要一致!!!!,可以写程序转换一下
1.1.2 自定义数据集
通过使用PaddleNLP提供的 load_dataset() , MapDataset 和 IterDataset 。任何人都可以方便的定义属于自己的数据集。
从本地文件创建数据集 从本地文件创建数据集时,我们 推荐 根据本地数据集的格式给出读取function并传入 load_dataset() 中创建数据集。
以 waybill_ie 快递单信息抽取任务中的数据为例:
代码语言:javascript复制from paddlenlp.datasets import load_dataset
def read(data_path):
with open(data_path, 'r', encoding='utf-8') as f:
# 跳过列名
next(f)
for line in f:
words, labels = line.strip('n').split('t')
words = words.split('