PaddleHub实战篇{词法分析模型LAC、情感分类ERNIE Tiny}训练、部署【三】
相关文章:
基础知识介绍:
【一】ERNIE:飞桨开源开发套件,入门学习,看看行业顶尖持续学习语义理解框架,如何取得世界多个实战的SOTA效果?_汀、的博客-CSDN博客_ernie模型
百度飞桨:ERNIE 3.0 、通用信息抽取 UIE、paddleNLP的安装使用[一]_汀、的博客-CSDN博客_paddlenlp 安装
项目实战:
PaddleHub--飞桨预训练模型应用工具{风格迁移模型、词法分析情感分析、Fine-tune API微调}【一】_汀、的博客-CSDN博客
PaddleHub--{超参优化AutoDL Finetuner}【二】_汀、的博客-CSDN博客
PaddleHub实战篇{词法分析模型LAC、情感分类ERNIE Tiny}训练、部署【三】_汀、的博客-CSDN博客
PaddleHub实战篇{ERNIE实现文新闻本分类、ERNIE3.0 实现序列标注}【四】_汀、的博客-CSDN博客
一.使用词法分析模型LAC(Lexical Analysis of Chinese)实现分词功能
使用PaddleHub下载数据集、预训练模型等,要求机器可以访问外网。可以使用server_check()检查本地与远端PaddleHub-Server的连接状态,使用方法如下。 如果可以连接远端PaddleHub-Server,则显示“Request Hub-Server successfully”。否则显示“Request Hub-Server unsuccessfully”。
import paddlehub
paddlehub.server_check()
[2022-05-31 16:07:32,221] [ INFO] - Request Hub-Server successfully.
以lac模型为例其对应的安装命令为:
终端输入:
hub install lac
1.1 使用命令行实现快速推理:
说明: LAC是一个联合的词法分析模型,能整体性地完成中文分词、词性标注、专名识别任务。
!hub run lac --input_text "现在,慕尼黑再保险公司不仅是此类行动的倡议者,更是将其大量气候数据整合进保险产品中,并与公众共享大量天气信息,参与到新能源领域的保障中。"
[2022-05-11 11:08:18,037] [ WARNING] - The _initialize method in HubModule will soon be deprecated, you can use the __init__() to handle the initialization of the object W0511 11:08:18.133453 279 analysis_predictor.cc:1687] Deprecated. Please use CreatePredictor instead. [{'word': ['现在', ',', '慕尼黑再保险公司', '不仅', '是', '此类', '行动', '的', '倡议者', ',', '更是', '将', '其', '大量', '气候', '数据', '整合', '进', '保险', '产品', '中', ',', '并', '与', '公众', '共享', '大量', '天气', '信息', ',', '参与', '到', '新能源', '领域', '的', '保障', '中', '。'], 'tag': ['TIME', 'w', 'ORG', 'c', 'v', 'r', 'n', 'u', 'n', 'w', 'd', 'p', 'r', 'a', 'n', 'n', 'v', 'v', 'n', 'n', 'f', 'w', 'c', 'p', 'n', 'v', 'a', 'n', 'n', 'w', 'v', 'v', 'n', 'n', 'u', 'vn', 'f', 'w']}]
实现快速推理的命令行的格式如下所示,其中参数解释如下:
- module-name:模型名称。
- input-parameter:输入参数,即上面例子中的“–input_text”
- input-value:推理的输入值,即上面例子中的“今天是个好日子”。
不同的模型,命令行格式和参数取值也不同,具体信息请在每个模型中查看“命令行预测示例”部分。
hub run ${module-name} ${input-parameter} ${input-value}
1.2 脚本代码:
import paddlehub as hub
# paddlehub.server_check()
lac = hub.Module(name="lac")
test_text = [
"现在,慕尼黑再保险公司不仅是此类行动的倡议者,更是将其大量气候数据整合进保险产品中,并与公众共享大量天气信息,参与到新能源领域的保障中"]
results = lac.cut(text=test_text, use_gpu=False, batch_size=1, return_tag=True)
for result in results:
print(result['word'])
print(result['tag'])
二、情感分类ERNIE Tiny:Transformer模型fine-tune文本分类
使用预训练模型进行迁移学习
通过高质量预训练模型与PaddleHub Fine-tune API,使用户只需要少量代码即可实现自然语言处理和计算机视觉场景的深度学习模型。以文本分类为例,共分4个步骤:
2.1 选择并加载预训练模型
本例使用ERNIE Tiny模型来演示如何利用PaddleHub实现finetune。ERNIE Tiny主要通过模型结构压缩和模型蒸馏的方法,将 ERNIE 2.0 Base 模型进行压缩。相较于 ERNIE 2.0,ERNIE Tiny模型能带来4.3倍的预测提速,具有更高的工业落地能力。
hub install ernie_tiny==2.0.1
import paddlehub as hub
model = hub.Module(name='ernie_tiny', version='2.0.1', task='seq-cls', num_classes=2)
其中,参数:
name
:模型名称,可以选择ernie
,ernie_tiny
,bert-base-cased
,bert-base-chinese
,roberta-wwm-ext
,roberta-wwm-ext-large
等。version
:module版本号task
:fine-tune任务。此处为seq-cls
,表示文本分类任务。num_classes
:表示当前文本分类任务的类别数,根据具体使用的数据集确定,默认为2。
PaddleHub还提供BERT等模型可供选择,具体可参见BERT。
其中,参数:
name
:模型名称,可以选择ernie
,ernie_tiny
,bert-base-cased
,bert-base-chinese
,roberta-wwm-ext
,roberta-wwm-ext-large
等。version
:module版本号task
:fine-tune任务。此处为seq-cls
,表示文本分类任务。num_classes
:表示当前文本分类任务的类别数,根据具体使用的数据集确定,默认为2。
PaddleHub还提供BERT等模型可供选择, 当前支持文本分类任务的模型对应的加载示例如下:
模型名 | PaddleHub Module |
---|---|
ERNIE, Chinese | hub.Module(name='ernie') |
ERNIE tiny, Chinese | hub.Module(name='ernie_tiny') |
ERNIE 2.0 Base, English | hub.Module(name='ernie_v2_eng_base') |
ERNIE 2.0 Large, English | hub.Module(name='ernie_v2_eng_large') |
BERT-Base, Cased | hub.Module(name='bert-base-cased') |
BERT-Base, Uncased | hub.Module(name='bert-base-uncased') |
BERT-Large, Cased | hub.Module(name='bert-large-cased') |
BERT-Large, Uncased | hub.Module(name='bert-large-uncased') |
BERT-Base, Multilingual Cased | hub.Module(nane='bert-base-multilingual-cased') |
BERT-Base, Multilingual Uncased | hub.Module(nane='bert-base-multilingual-uncased') |
BERT-Base, Chinese | hub.Module(name='bert-base-chinese') |
BERT-wwm, Chinese | hub.Module(name='chinese-bert-wwm') |
BERT-wwm-ext, Chinese | hub.Module(name='chinese-bert-wwm-ext') |
RoBERTa-wwm-ext, Chinese | hub.Module(name='roberta-wwm-ext') |
RoBERTa-wwm-ext-large, Chinese | hub.Module(name='roberta-wwm-ext-large') |
RBT3, Chinese | hub.Module(name='rbt3') |
RBTL3, Chinese | hub.Module(name='rbtl3') |
2.2 准备数据集并读取数据
用户可以选择使用自定义的数据集或PaddleHub提供的数据集进行迁移训练。
(1) PaddleHub提供的数据集ChnSentiCorp
# 自动从网络下载数据集并解压到用户目录下$HUB_HOME/.paddlehub/dataset目录
train_dataset = hub.datasets.ChnSentiCorp(
tokenizer=model.get_tokenizer(), max_seq_len=128, mode='train')
dev_dataset = hub.datasets.ChnSentiCorp(
tokenizer=model.get_tokenizer(), max_seq_len=128, mode='dev')
[2022-05-31 16:45:21,090] [ INFO] - Already cached C:\Users\admin\.paddlenlp\models\ernie-tiny\ernie_tiny.pdparams
[2022-05-31 16:45:36,225] [ INFO] - Downloading https://bj.bcebos.com/paddlenlp/models/transformers/ernie_tiny/vocab.txt and saved to C:\Users\admin\.paddlenlp\models\ernie-tiny
[2022-05-31 16:45:36,232] [ INFO] - Downloading vocab.txt from https://bj.bcebos.com/paddlenlp/models/transformers/ernie_tiny/vocab.txt
100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 459k/459k [00:00<00:00, 617kB/s]
[2022-05-31 16:45:37,622] [ INFO] - Downloading https://bj.bcebos.com/paddlenlp/models/transformers/ernie_tiny/spm_cased_simp_sampled.model and saved to C:\Users\admin\.paddlenlp\models\ernie-tiny
[2022-05-31 16:45:37,624] [ INFO] - Downloading spm_cased_simp_sampled.model from https://bj.bcebos.com/paddlenlp/models/transformers/ernie_tiny/spm_cased_simp_sampled.model
100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 1.06M/1.06M [00:01<00:00, 735kB/s]
[2022-05-31 16:45:39,643] [ INFO] - Downloading https://bj.bcebos.com/paddlenlp/models/transformers/ernie_tiny/dict.wordseg.pickle and saved to C:\Users\admin\.paddlenlp\models\ernie-tiny
[2022-05-31 16:45:39,647] [ INFO] - Downloading dict.wordseg.pickle from https://bj.bcebos.com/paddlenlp/models/transformers/ernie_tiny/dict.wordseg.pickle
100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 158M/158M [01:31<00:00, 1.81MB/s]
Download https://bj.bcebos.com/paddlehub-dataset/chnsenticorp.tar.gz
[##################################################] 100.00%
Decompress C:\Users\admin\.paddlehub\tmp\tmpmu7cgtvf\chnsenticorp.tar.gz
[##################################################] 100.00%
[2022-05-31 16:47:34,077] [ INFO] - Already cached C:\Users\admin\.paddlenlp\models\ernie-tiny\vocab.txt
[2022-05-31 16:47:34,079] [ INFO] - Already cached C:\Users\admin\.paddlenlp\models\ernie-tiny\spm_cased_simp_sampled.model
[2022-05-31 16:47:34,080] [ INFO] - Already cached
tokenizer
:表示该module所需用到的tokenizer,其将对输入文本完成切词,并转化成module运行所需模型输入格式。mode
:选择数据模式,可选项有train
,test
,val
, 默认为train
。max_seq_len
:ERNIE/BERT模型使用的最大序列长度,若出现显存不足,请适当调低这一参数。
预训练模型ERNIE对中文数据的处理是以字为单位,tokenizer作用为将原始输入文本转化成模型model可以接受的输入数据形式。 PaddleHub 2.0中的各种预训练模型已经内置了相应的tokenizer,可以通过model.get_tokenizer
方法获取。
(2) 自定义数据集
如果用户希望使用自定义的数据集,则需要对自定义数据进行相应的预处理,将数据集文件处理成预训练模型可以读取的格式。例如用PaddleHub文本分类任务使用自定义数据时,需要切分数据集,将数据集切分为训练集、验证集和测试集。
a. 设置数据集目录。
用户需要将数据集目录设定为如下格式。
├──data: 数据目录
├── train.txt: 训练集数据
├── dev.txt: 验证集数据
└── test.txt: 测试集数据
b. 设置文件格式和内容。
训练集、验证集和测试集文件的编码格式建议为utf8格式。内容的第一列是文本内容,第二列为文本类别标签。列与列之间以Tab键分隔。建议在数据集文件第一行填写列说明"label"和"text_a",中间以Tab键分隔,示例如下:
label text_a
房产 昌平京基鹭府10月29日推别墅1200万套起享97折
教育 贵州2011高考录取分数线发布理科一本448分
社会 众多白领因集体户口面临结婚难题
...
c. 加载自定义数据集。
加载文本分类的自定义数据集,用户仅需要继承基类TextClassificationDataset,修改数据集存放地址以及类别即可,具体可以参考如下代码:
from paddlehub.datasets.base_nlp_dataset import TextClassificationDataset
class SeqClsDataset(TextClassificationDataset):
# 数据集存放目录
base_path = '/path/to/dataset'
# 数据集的标签列表
label_list=['体育', '科技', '社会', '娱乐', '股票', '房产', '教育', '时政', '财经', '星座', '游戏', '家居', '彩票', '时尚']
def __init__(self, tokenizer, max_seq_len: int = 128, mode: str = 'train'):
if mode == 'train':
data_file = 'train.txt'
elif mode == 'test':
data_file = 'test.txt'
else:
data_file = 'dev.txt'
super().__init__(
base_path=self.base_path,
tokenizer=tokenizer,
max_seq_len=max_seq_len,
mode=mode,
data_file=data_file,
label_list=self.label_list,
is_file_with_header=True)
# 选择所需要的模型,获取对应的tokenizer
import paddlehub as hub
model = model = hub.Module(name='ernie_tiny', task='seq-cls', num_classes=len(SeqClsDataset.label_list))
tokenizer = model.get_tokenizer()
# 实例化训练集
train_dataset = SeqClsDataset(tokenizer)
至此用户可以通过SeqClsDataset实例化获取对应的数据集,可以通过hub.Trainer对预训练模型model
完成文本分类任务,详情可参考PaddleHub文本分类demo。
2.3 选择优化策略和运行配置
运行如下代码,即可实现对文本分类模型的finetune:
import paddle
optimizer = paddle.optimizer.Adam(learning_rate=5e-5, parameters=model.parameters())
trainer = hub.Trainer(model, optimizer, checkpoint_dir='test_ernie_text_cls', use_gpu=True)
trainer.train(train_dataset, epochs=5, batch_size=32, eval_dataset=dev_dataset, save_interval=1)
结果:
valuation result] avg_acc=0.9292
[2022-05-31 17:54:14,269] [ INFO] - Saving model checkpoint to test_ernie_text_cls1/epoch_4
[2022-05-31 17:54:17,601] [ TRAIN] - Epoch=5/5, Step=10/300 loss=0.0378 acc=0.9875 lr=0.000050 step/sec=2.18 | ETA 00:02:51
[2022-05-31 17:54:18,496] [ TRAIN] - Epoch=5/5, Step=20/300 loss=0.0692 acc=0.9781 lr=0.000050 step/sec=11.18 | ETA 00:02:50
[2022-05-31 17:54:19,389] [ TRAIN] - Epoch=5/5, Step=30/300 loss=0.0492 acc=0.9844 lr=0.000050 step/sec=11.19 | ETA 00:02:50
[2022-05-31 17:54:20,289] [ TRAIN] - Epoch=5/5, Step=40/300 loss=0.0236 acc=0.9906 lr=0.000050 step/sec=11.12 | ETA 00:02:50
[2022-05-31 17:54:21,185] [ TRAIN] - Epoch=5/5, Step=50/300 loss=0.0114 acc=0.9938 lr=0.000050 step/sec=11.15 | ETA 00:02:49
[2022-05-31 17:54:22,079] [ TRAIN] - Epoch=5/5, Step=60/300 loss=0.0300 acc=0.9875 lr=0.000050 step/sec=11.20 | ETA 00:02:49
[2022-05-31 17:54:22,975] [ TRAIN] - Epoch=5/5, Step=70/300 loss=0.0272 acc=0.9875 lr=0.000050 step/sec=11.16 | ETA 00:02:49
[2022-05-31 17:54:23,867] [ TRAIN] - Epoch=5/5, Step=80/300 loss=0.0394 acc=0.9844 lr=0.000050 step/sec=11.20 | ETA 00:02:49
[2022-05-31 17:54:24,764] [ TRAIN] - Epoch=5/5, Step=90/300 loss=0.0272 acc=0.9938 lr=0.000050 step/sec=11.16 | ETA 00:02:48
[2022-05-31 17:54:25,645] [ TRAIN] - Epoch=5/5, Step=100/300 loss=0.0156 acc=0.9938 lr=0.000050 step/sec=11.35 | ETA 00:02:48
[2022-05-31 17:54:26,519] [ TRAIN] - Epoch=5/5, Step=110/300 loss=0.0084 acc=1.0000 lr=0.000050 step/sec=11.43 | ETA 00:02:48
[2022-05-31 17:54:27,397] [ TRAIN] - Epoch=5/5, Step=120/300 loss=0.0162 acc=0.9938 lr=0.000050 step/sec=11.39 | ETA 00:02:48
[2022-05-31 17:54:28,271] [ TRAIN] - Epoch=5/5, Step=130/300 loss=0.0458 acc=0.9812 lr=0.000050 step/sec=11.45 | ETA 00:02:47
[2022-05-31 17:54:29,145] [ TRAIN] - Epoch=5/5, Step=140/300 loss=0.0292 acc=0.9875 lr=0.000050 step/sec=11.44 | ETA 00:02:47
[2022-05-31 17:54:30,020] [ TRAIN] - Epoch=5/5, Step=150/300 loss=0.0232 acc=0.9938 lr=0.000050 step/sec=11.44 | ETA 00:02:47
[2022-05-31 17:54:30,901] [ TRAIN] - Epoch=5/5, Step=160/300 loss=0.0420 acc=0.9906 lr=0.000050 step/sec=11.34 | ETA 00:02:46
[2022-05-31 17:54:31,773] [ TRAIN] - Epoch=5/5, Step=170/300 loss=0.0333 acc=0.9875 lr=0.000050 step/sec=11.47 | ETA 00:02:46
[2022-05-31 17:54:32,645] [ TRAIN] - Epoch=5/5, Step=180/300 loss=0.0251 acc=0.9938 lr=0.000050 step/sec=11.47 | ETA 00:02:46
[2022-05-31 17:54:33,520] [ TRAIN] - Epoch=5/5, Step=190/300 loss=0.0422 acc=0.9781 lr=0.000050 step/sec=11.43 | ETA 00:02:46
[2022-05-31 17:54:34,395] [ TRAIN] - Epoch=5/5, Step=200/300 loss=0.0501 acc=0.9875 lr=0.000050 step/sec=11.42 | ETA 00:02:45
[2022-05-31 17:54:35,273] [ TRAIN] - Epoch=5/5, Step=210/300 loss=0.0318 acc=0.9875 lr=0.000050 step/sec=11.40 | ETA 00:02:45
[2022-05-31 17:54:36,147] [ TRAIN] - Epoch=5/5, Step=220/300 loss=0.0228 acc=0.9906 lr=0.000050 step/sec=11.44 | ETA 00:02:45
[2022-05-31 17:54:37,021] [ TRAIN] - Epoch=5/5, Step=230/300 loss=0.0258 acc=0.9938 lr=0.000050 step/sec=11.44 | ETA 00:02:45
[2022-05-31 17:54:37,892] [ TRAIN] - Epoch=5/5, Step=240/300 loss=0.0509 acc=0.9812 lr=0.000050 step/sec=11.48 | ETA 00:02:44
[2022-05-31 17:54:38,765] [ TRAIN] - Epoch=5/5, Step=250/300 loss=0.0266 acc=0.9938 lr=0.000050 step/sec=11.46 | ETA 00:02:44
[2022-05-31 17:54:39,655] [ TRAIN] - Epoch=5/5, Step=260/300 loss=0.0101 acc=0.9969 lr=0.000050 step/sec=11.23 | ETA 00:02:44
[2022-05-31 17:54:40,546] [ TRAIN] - Epoch=5/5, Step=270/300 loss=0.0090 acc=0.9969 lr=0.000050 step/sec=11.23 | ETA 00:02:44
[2022-05-31 17:54:41,437] [ TRAIN] - Epoch=5/5, Step=280/300 loss=0.0299 acc=0.9938 lr=0.000050 step/sec=11.22 | ETA 00:02:44
[2022-05-31 17:54:42,328] [ TRAIN] - Epoch=5/5, Step=290/300 loss=0.0219 acc=0.9906 lr=0.000050 step/sec=11.23 | ETA 00:02:43
[2022-05-31 17:54:43,213] [ TRAIN] - Epoch=5/5, Step=300/300 loss=0.0160 acc=0.9969 lr=0.000050 step/sec=11.30 | ETA 00:02:43
[2022-05-31 17:54:44,423] [ EVAL] - Evaluation on validation dataset: \ - Evaluation on validation dataset: | - Evaluation on validation dataset: / - Evaluation on validation dataset: - - Evaluation on validation dataset: \ - Evaluation on validation dataset: | - Evaluation on validation dataset: / - Evaluation on validation dataset: - - Evaluation on validation dataset: \ - Evaluation on validation dataset: | - Evaluation on validation dataset: / - Evaluation on validation dataset: - - [Evaluation result] avg_acc=0.9408
[2022-05-31 17:54:44,425] [ INFO] - Saving model checkpoint to test_ernie_text_cls1/epoch_5
优化策略
飞桨提供了多种优化器选择,如SGD
, Adam
, Adamax
等, 其中Adam
:
learning_rate
: 全局学习率。默认为1e-3;parameters
: 待优化模型参数。
运行配置
Trainer
主要控制Fine-tune的训练,包含以下可控制的参数:
红色为主要修改参数
model
: 被优化模型;optimizer
: 优化器选择;use_gpu
: 是否使用gpu;use_vdl
: 是否使用vdl可视化训练过程;checkpoint_dir
: 保存模型参数的地址;compare_metrics
: 保存最优模型的衡量指标;
trainer.train
主要控制具体的训练过程,包含以下可控制的参数:
train_dataset
: 训练时所用的数据集;epochs
: 训练轮数;batch_size
: 训练的批大小,如果使用GPU,请根据实际情况调整batch_size;num_workers
: works的数量,默认为0;eval_dataset
: 验证集;log_interval
: 打印日志的间隔, 单位为执行批训练的次数。save_interval
: 保存模型的间隔频次,单位为执行训练的轮数。
2.4. 模型预测
当完成Fine-tune后,Fine-tune过程在验证集上表现最优的模型会被保存在${CHECKPOINT_DIR}/best_model
目录下,其中${CHECKPOINT_DIR}
目录为Fine-tune时所选择的保存checkpoint的目录。
我们以以下数据为待预测数据,使用该模型来进行预测:
import paddlehub as hub
data = [
['这个宾馆比较陈旧了,特价的房间也很一般。总体来说一般'],
['怀着十分激动的心情放映,可是看着看着发现,在放映完毕后,出现一集米老鼠的动画片'],
['作为老的四星酒店,房间依然很整洁,相当不错。机场接机服务很好,可以在车上办理入住手续,节省时间。'],
]
label_map = {0: 'negative', 1: 'positive'}
model = hub.Module(
name='ernie_tiny',
version='2.0.1',
task='seq-cls',
load_checkpoint='./test_ernie_text_cls1/best_model/model.pdparams',
label_map=label_map)
results = model.predict(data, max_seq_len=50, batch_size=1, use_gpu=True)
for idx, text in enumerate(data):
print('Data: {} \t Lable: {}'.format(text[0], results[idx]))
Data: 这个宾馆比较陈旧了,特价的房间也很一般。总体来说一般 Lable: negative
Data: 怀着十分激动的心情放映,可是看着看着发现,在放映完毕后,出现一集米老鼠的动画片 Lable: negative
Data: 作为老的四星酒店,房间依然很整洁,相当不错。机场接机服务很好,可以在车上办理入住手续,节省时间。 Lable: positive
3.完整码源
见链接下载
PaddleHub实战篇{词法分析模型LAC、情感分类ERNIETiny}训练、部署【三】-自然语言处理文档类资源-CSDN下载