PaddleNLP基于ERNIR3.0文天职类以中医疗搜刮检索词企图分类(KUAKE-QIC)为例
相关项目链接: Paddlenlp之UIE模子实战实体抽取使命【打车数据、快递单】
Paddlenlp之UIE分类模子【以感情倾向阐发新闻分类为例】含智能标注计划)
利用理论:分类模子大集成者[PaddleHub、Finetune、prompt]
Paddlenlp之UIE关系抽取模子【高管关系抽取为例】 本项目链接: [PaddleNLP基于ERNIR3.0文天职类使命详解【多分类(单标签)】 ]()
0.媒介:文天职类使命介绍
文天职类使命是天然语言处置中最常见的使命,文天职类使命简单来说就是对给定的一个句子或一段文本利用文天职类器停止分类。文天职类使命普遍利用于长短文天职类、感情阐发、新闻分类、事务类别分类、政务数据分类、商品信息分类、商品类目揣测、文章分类、论文类别分类、专利分类、案件描述分类、功名分类、企图分类、论文专利分类、邮件主动标签、评论正负识别、药物反响分类、对话分类、税种识别、来电信息主动分类、赞扬分类、告白检测、灵敏违法内容检测、内容平安检测、舆情阐发、话题标识表记标帜等各类日常或专业范畴中。
文天职类使命能够根据标签类型分为多分类(multi class)、多标签(multi label)、条理分类(hierarchical等三类使命,接下来我们将以下图的新闻文天职类为例介绍三种分类使命的区别。
PaddleNLP摘用AutoModelForSequenceClassification, AutoTokenizer供给了便利易用的接口,可指定模子名或模子参数文件途径通过from_pretrained() 办法加载差别收集构造的预操练模子,并在输出层上叠加一层线性层,且响应预操练模子权重下载速度快、不变。Transformer预操练模子汇总包罗了如 ERNIE、BERT、RoBERTa等40多个支流预操练模子,500多个模子权重。下面以ERNIE 3.0 中文base模子为例,演示若何加载预操练模子和分词器:
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() 。
PaddleNLP Datasets API:供参考
PaddleNLP供给了以下数据集的快速读取API,现实利用时请根据需要添加splits信息:
加载数据集
快速加载内置数据集 目前PaddleNLP内置20余个NLP数据集,涵盖阅读理解,文天职类,序列标注,机器翻译等多项使命。目前供给的数据集能够在 数据集列表 中找到。
以 msra_ner 数据集为例:
loaddataset() 办法会从 paddlenlp.datasets 下找到msraner数据集对应的数据读取脚本(默认途径: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竞赛,对操练数据停止了数据加强)。 loaddataset() 办法供给的 datafiles参数能够实现那个功用。以 SQuAD 为例。
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 数据集为例:
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 快递单信息抽取使命中的数据为例:
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('\002')
labels = labels.split('\002')
yield {'tokens': words, 'labels': labels}
# data_path为read()办法的参数
map_ds = load_dataset(read, data_path='数据集/data1/dev.txt', lazy=False)
iter_ds = load_dataset(read, data_path='数据集/data1/dev.txt', lazy=True)
for i in range(3):
print(map_ds[i])
{'tokens': ['喻', '晓', '刚', '云', '南', '省', '楚', '雄', '彝', '族', '自', '治', '州', '南', '华', '县', '东', '街', '古', '城', '路', '3', '7', '号', '1', '8', '5', '1', '3', '3', '8', '6', '1', '6', '3'], 'labels': ['P-B', 'P-I', 'P-I', 'A1-B', 'A1-I', 'A1-I', 'A2-B', 'A2-I', 'A2-I', 'A2-I', 'A2-I', 'A2-I', 'A2-I', 'A3-B', 'A3-I', 'A3-I', 'A4-B', 'A4-I', 'A4-I', 'A4-I', 'A4-I', 'A4-I', 'A4-I', 'A4-I', 'T-B', 'T-I', 'T-I', 'T-I', 'T-I', 'T-I', 'T-I', 'T-I', 'T-I', 'T-I', 'T-I']}
{'tokens': ['1', '3', '4', '2', '6', '3', '3', '8', '1', '3', '5', '寇', '铭', '哲', '黑', '龙', '江', '省', '七', '台', '河', '市', '桃', '山', '区', '风', '摘', '路', '朝', '阳', '广', '场'], 'labels': ['T-B', 'T-I', 'T-I', 'T-I', 'T-I', 'T-I', 'T-I', 'T-I', 'T-I', 'T-I', 'T-I', 'P-B', 'P-I', 'P-I', 'A1-B', 'A1-I', 'A1-I', 'A1-I', 'A2-B', 'A2-I', 'A2-I', 'A2-I', 'A3-B', 'A3-I', 'A3-I', 'A4-B', 'A4-I', 'A4-I', 'A4-I', 'A4-I', 'A4-I', 'A4-I']}
{'tokens': ['湖', '南', '省', '长', '沙', '市', '岳', '麓', '区', '银', '杉', '路', '3', '1', '号', '绿', '地', '中', '央', '广', '场', '7', '栋', '2', '1', '楼', '须', '平', '盛', '1', '3', '6', '0', '1', '2', '6', '9', '5', '3', '8'], 'labels': ['A1-B', 'A1-I', 'A1-I', 'A2-B', 'A2-I', 'A2-I', 'A3-B', 'A3-I', 'A3-I', 'A4-B', 'A4-I', 'A4-I', 'A4-I', 'A4-I', 'A4-I', 'A4-I', 'A4-I', 'A4-I', 'A4-I', 'A4-I', 'A4-I', 'A4-I', 'A4-I', 'A4-I', 'A4-I', 'A4-I', 'P-B', 'P-I', 'P-I', 'T-B', 'T-I', 'T-I', 'T-I', 'T-I', 'T-I', 'T-I', 'T-I', 'T-I', 'T-I', 'T-I']}
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(' ')
# words = words.split('\002')
# labels = labels.split('') #分类问题内容和标签一般不需要再朋分
yield {'connect': words, 'labels': labels}
# data_path为read()办法的参数
map_ds = load_dataset(read, data_path='数据集/input.txt', lazy=False)
# iter_ds = load_dataset(read, data_path='数据集/dev.txt', lazy=True)
# train= load_dataset(read, data_path='数据集/input_train.txt', lazy=False)
# dev= load_dataset(read, data_path='数据集/input_dev.txt', lazy=False) #自定义好操练测试集
for i in range(3):
print(map_ds[i])
{'connect': '出栏一头猪吃亏300元,事实谁能笑到最初!', 'labels': '金融'} {'connect': '区块链投资心得,能做到就不会亏钱', 'labels': '金融'} {'connect': '你家拆迁,要钱仍是要房?谜底一目了然。', 'labels': '房产'}
api接口文档
选举将数据读代替码写成生成器(generator)的形式,如许能够更好的构建 MapDataset 和 IterDataset 两种数据集。同时也选举将单条数据写成字典的格局,如许能够更便利的监测数据流向。
事实上,MapDataset 在绝大大都时候都能够称心要求。一般只要在数据集过于浩荡无法一次性加载进内存的时候我们才考虑利用 IterDataset 。任何人都能够便利的定义属于本身的数据集。
注解:
需要重视的是,只要PaddleNLP内置的数据集具有将数据中的label主动转为id的功用(详尽前提拜见 创建DatasetBuilder)。
像上例中的自定义数据集需要在自定义的convert to feature办法中添加label转id的功用。
自定义数据读取function中的参数能够间接以关键字参数的的体例传进 load_dataset() 中。并且关于自定义数据集,lazy 参数是必需传进的。
2.基于ERNIR3.0文天职类使命模子微调
save_dir:保留操练模子的目次;默认保留在当前目次checkpoint文件夹下。
dataset:操练数据集;默认为"cblue"。
dataset_dir:当地数据集途径,数据集途径中应包罗train.txt,dev.txt和label.txt文件;默认为None。
task_name:操练数据集;默认为"KUAKE-QIC"。
maxseqlength:ERNIE模子利用的更大序列长度,更大不克不及超越512, 若呈现显存不敷,请恰当调低那一参数;默认为128。
model_name:抉择预操练模子;默认为"ernie-3.0-base-zh"。
device: 选用什么设备停止操练,可选cpu、gpu、xpu、npu。如利用gpu操练,可利用参数gpus指定GPU卡号。
batch_size:批处置大小,请连系显存情状停止调整,若呈现显存不敷,请恰当调低那一参数;默认为32。
learning_rate:Fine-tune的更大进修率;默认为6e-5。
weight_decay:掌握正则项力度的参数,用于避免过拟合,默认为0.01。
early_stop:抉择能否利用早停法(EarlyStopping);默认为False。
earlystopnums:在设定的早停操练轮次内,模子在开发集上表示不再上升,操练末行;默认为4。 epochs: 操练轮次,默认为100。
warmup:能否利用进修率warmup战略;默认为False。
warmupproportion:进修率warmup战略的比例数,假设设为0.1,则进修率会在前10%steps数从0渐渐增长到learningrate, 然后再迟缓衰减;默认为0.1。
logging_steps: 日记打印的间隔steps数,默认5。
initfromckpt: 模子初始checkpoint参数地址,默认None。
seed:随机种子,默认为3。
parser.add_argument("--save_dir",
default="./checkpoint",
type=str,
help="The output directory where the model "
"checkpoints will be written.")
parser.add_argument("--dataset",
default="cblue",
type=str,
help="Dataset for text classfication.")
parser.add_argument("--dataset_dir",
default=None,
type=str,
help="Local dataset directory should include"
"train.txt, dev.txt and label.txt")
parser.add_argument("--task_name",
default="KUAKE-QIC",
type=str,
help="Task name for text classfication dataset.")
parser.add_argument("--max_seq_length",
default=128,
type=int,
help="The maximum total input sequence length"
"after tokenization. Sequences longer than this "
"will be truncated, sequences shorter will be padded.")
parser.add_argument('--model_name',
default="ernie-3.0-base-zh",
help="Select model to train, defaults "
"to ernie-3.0-base-zh.")
parser.add_argument('--device',
choices=['cpu', 'gpu', 'xpu', 'npu'],
default="gpu",
help="Select which device to train model, defaults to gpu.")
parser.add_argument("--batch_size",
default=32,
type=int,
help="Batch size per GPU/CPU for training.")
parser.add_argument("--learning_rate",
default=6e-5,
type=float,
help="The initial learning rate for Adam.")
parser.add_argument("--weight_decay",
default=0.01,
type=float,
help="Weight decay if we apply some.")
parser.add_argument('--early_stop',
action='store_true',
help='Epoch before early stop.')
parser.add_argument('--early_stop_nums',
type=int,
default=4,
help='Number of epoch before early stop.')
parser.add_argument("--epochs",
default=100,
type=int,
help="Total number of training epochs to perform.")
parser.add_argument('--warmup',
action='store_true',
help="whether use warmup strategy")
parser.add_argument('--warmup_proportion',
default=0.1,
type=float,
help="Linear warmup proportion of learning "
"rate over the training process.")
parser.add_argument("--logging_steps",
default=5,
type=int,
help="The interval steps to logging.")
parser.add_argument("--init_from_ckpt",
type=str,
default=None,
help="The path of checkpoint to be loaded.")
parser.add_argument("--seed",
type=int,
default=3,
help="random seed for initialization")
2.1.1 性能目标修改
关于性能目标参考手册修改添加:我已经添加进往 :
import numpy as np
import paddle
x = np.array([0.1, 0.5, 0.6, 0.7])
y = np.array([0, 1, 1, 1])
m = paddle.metric.Precision()
m.update(x, y)
res = m.accumulate()
print(res) # 1.0
import numpy as np
import paddle
x = np.array([0.1, 0.5, 0.6, 0.7])
y = np.array([1, 0, 1, 1])
m = paddle.metric.Recall()
m.update(x, y)
res = m.accumulate()
print(res) # 2.0 / 3.0
f1_score = float(2 * precision * recall /
(precision + recall))
修改后文件为:new
暂时未处理。
吐槽一下最新版本paddlenlp上面py文件已经没了!
现实摘用那个-----AccuracyAndF1
修改后文件为:new2
# !python train.py --warmup --early_stop --epochs 10 --model_name "ernie-3.0-base-zh" --max_seq_length 128 --batch_size 32 --logging_steps 10 --learning_rate 6e-5
!python train.py --warmup --early_stop --epochs 5 --model_name ernie-3.0-medium-zh
#修改后的操练文件train_new2.py ,次要利用了paddlenlp.metrics.glue的AccuracyAndF1:准确率及F1-score,可用于GLUE中的MRPC 和QQP使命
#不外吐槽一下: return (acc,precision,recall,f1,(acc + f1) / 2,) 最初一个目标竟然是加权均匀.....
!python train_new2.py --warmup --early_stop --epochs 5 --save_dir "./checkpoint2" --batch_size 16
法式运行时将会主动停止操练,评估,测试。同时操练过程中会主动保留开发集上更佳模子在指定的 save_dir 中,保留模子文件构造如下所示:
checkpoint/
├── model_config.json
├── model_state.pdparams
├── tokenizer_config.json
└── vocab.txt
NOTE:
如需恢复模子操练,则能够设置 initfromckpt , 如initfromckpt=checkpoint/model_state.pdparams。
如需操练中文文天职类使命,只需改换预操练模子参数 model_name 。中文操练使命选举利用"ernie-3.0-base-zh",更多可选模子可参考Transformer预操练模子。
2.1.2 利用文心ERNIE最新大模子停止操练
最新开源ERNIE 3.0系列预操练模子:
110M参数通用模子ERNIE 3.0 Base
280M参数重量级通用模子ERNIE 3.0 XBase
74M轻量级通用模子ERNIE 3.0 Medium
文档链接:
ERNIE模子汇总
ERNIE模子汇总
目前间接定义name就能够挪用的次要为下面几类:
目开源 ERNIE 3.0 Base 、ERNIE 3.0 Medium 、 ERNIE 3.0 Mini 、 ERNIE 3.0 Micro 、 ERNIE 3.0 Nano 五个模子:
ERNIE 3.0-Base (12-layer, 768-hidden, 12-heads)
ERNIE 3.0-Medium (6-layer, 768-hidden, 12-heads)
ERNIE 3.0-Mini (6-layer, 384-hidden, 12-heads)
ERNIE 3.0-Micro (4-layer, 384-hidden, 12-heads)
ERNIE 3.0-Nano (4-layer, 312-hidden, 12-heads)
从当地文件创建数据集
利用当地数据集来操练我们的文天职类模子,本项目撑持利用固定格局当地数据集文件停止操练 假设需要对当地数据集停止数据标注,能够参考文天职类使命doccano数据标注利用指南停止文天职类数据标注。[那个放到下个项目讲解]
本项目将以CBLUE数据集中医疗搜刮检索词企图分类(KUAKE-QIC)使命为例停止介绍若何加载当地固定格局数据集停止操练:
当地数据集目次构造如下:
data/
├── train.txt # 操练数据集文件
├── dev.txt # 开发数据集文件
├── label.txt # 分类标签文件
└── data.txt # 可选,待揣测数据文件
train.txt(操练数据集文件), dev.txt(开发数据集文件),输进文本序列与标签类别号用'\t'分离隔。 train.txt/dev.txt 文件格局:
输进序列1'\t'标签1'\n'
输进序列2'\t'标签2'\n'
丙氨酸氨基转移酶和天门冬氨酸氨基转移酶高严峻吗 其他
慢性肝炎早期症状有哪些表示 疾病表述
胃欠好能食南瓜吗 重视事项
为什么我的手到炎天就会脱皮并且很严峻有什么办法翱4天... 病情诊断
脸上拆线后能够出往玩吗?能够流 其他
西宁青海治不孕不育专科病院 就医定见
冠状沟破例良多肉粒是什么 病情诊断
肛裂治疗用什么办法比力好 治疗计划
包皮过长应该怎么样治疗有效 治疗计划
请问白癜风是一种什么样的疾病 疾病表述
月颠末了四天测出怀孕能否能够确定 其他
label.txt(分类标签文件)笔录数据集中所有标签聚集,每一行为一个标签名。 label.txt 文件格局:
标签名1'\n'
标签名2'\n'
病情诊断
治疗计划
病因阐发
目标解读
就医定见
疾病表述
后果表述
重视事项
成效感化
医疗费用
其他
data.txt(可选,待揣测数据文件)。
黑苦荞茶的成效与感化及食用办法
接壤痣会凸起吗
查抄能否能怀孕挂什么科
鱼油怎么食咬破食仍是间接咽下往
幼儿挑食的心理原因是
2.3 GPU多卡操练
指定GPU卡号/多卡操练
unset CUDA_VISIBLE_DEVICES
python -m paddle.distributed.launch --gpus "0" train.py --warmup --early_stop
unset CUDA_VISIBLE_DEVICES
python -m paddle.distributed.launch --gpus "0" train.py --warmup --dataset_dir data/KUAKE_QIC
利用多卡操练能够指定多个GPU卡号,例如 --gpus "0,1"
unset CUDA_VISIBLE_DEVICES
python -m paddle.distributed.launch --gpus "0,1" train.py --warmup --dataset_dir data/KUAKE_QIC
2.4模子揣测
输进待揣测数据和数据标签比照列表,模子揣测数据对应的标签
利用默认数据停止揣测:
!python predict.py --params_path ./checkpoint/
input data: 黑苦荞茶的成效与感化及食用办法
label: 成效感化
input data: 接壤痣会凸起吗
label: 疾病表述
input data: 查抄能否能怀孕挂什么科
label: 就医定见
input data: 鱼油怎么食咬破食仍是间接咽下往
label: 其他
input data: 幼儿挑食的心理原因是
label: 病因阐发
#也能够抉择利用当地数据文件data/data.txt停止揣测:
!python predict.py --params_path ./checkpoint/ --dataset_dir data/KUAKE_QIC
label: 成效感化
input data: 接壤痣会凸起吗
label: 疾病表述
input data: 查抄能否能怀孕挂什么科
label: 就医定见
input data: 鱼油怎么食咬破食仍是间接咽下往
label: 其他
input data: 幼儿挑食的心理原因是
label: 病因阐发
3.总结
最新开源ERNIE 3.0系列预操练模子:
110M参数通用模子ERNIE 3.0 Base
280M参数重量级通用模子ERNIE 3.0 XBase
74M轻量级通用模子ERNIE 3.0 Medium
新增语音-语言跨模态模子ERNIE-SAT 正式开源
新增ERNIE-Gen(中文)预操练模子,撑持多类支流生成使命:次要包罗摘要、问题生成、对话、问答 动静连系的文心ERNIE开发套件:基于飞桨动态图功用,撑持文心ERNIE模子动态图操练。
将文本预处置、预操练模子、收集搭建、模子评估、上线摆设等NLP开发流程标准封拆。
撑持NLP常用使命:文天职类、文本婚配、序列标注、信息抽取、文本生成、数据蒸馏等。
供给数据清洗、数据加强、分词、格局转换、大小写转换等数据预处置东西。
文心大模子ERNIE是百度发布的财产级常识加强大模子,涵盖了NLP大模子和跨模态大模子。2019年3月,开源了国内首个开源预操练模子文心ERNIE 1.0,尔后在语言与跨模态的理解和生成等范畴获得一系列手艺打破,并对外开源与开放了系列模子,助力大模子研究与财产化利用开展。
那里温馨提醒碰着问题多看文档手册
后续将对:多标签分类、条理分类停止讲解、以及那块数据集的标注讲解。
在空了会对穿插验证,数据加强研究一下
本人博客: