# 安装PaddleHub
!pip install --upgrade paddlehub -i https://pypi.tuna.tsinghua.edu.cn/simple
PART I. 加载预置中文情感分类数据集ChnSentiCorp
ChnSentiCorp数据集是一个中文情感二分类数据集。PaddleHub已支持加载该数据集。关于该数据集,详情请查看ChnSentiCorp数据集使用。
更多预置数据集,查看详情
import paddlehub as hub
dataset = hub.dataset.ChnSentiCorp()
for e in dataset.get_train_examples()[:3]:
print("{}\t{}\t{}".format(e.guid, e.text_a, e.label))
PART II. PaddleHub一键加载ernie tiny
ERNIE Tiny 主要通过模型结构压缩和模型蒸馏的方法,将 ERNIE 2.0 Base 模型进行压缩。特点和优势如下:
-
采用 3 层 transformer 结构,线性提速 4 倍;
-
模型加宽隐层参数,从 ERNIE 2.0 的 768 扩展到 1024;
-
缩短输入文本的序列长度,降低计算复杂度,模型首次采用中文 subword 粒度输入,长度平均缩短 40%;
-
ERNIE Tiny 在训练中扮演学生角色,利用模型蒸馏的方式在 Transformer 层和 Prediction 层学习教师模型 ERNIE 2.0 模型对应层的分布和输出;
综合优化能带来4.3倍的预测提速,具有更高的工业落地能力,应用于百度搜索、凤巢等项目。
!hub install ernie_tiny
module = hub.Module(name="ernie_tiny")
如果想尝试其他语义模型(如ernie, RoBERTa等),只需要更换Module中的name
参数即可.
模型名 | 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') |
RoBERTa-Large, Chinese | hub.Module(name='roberta_wwm_ext_chinese_L-24_H-1024_A-16') |
RoBERTa-Base, Chinese | hub.Module(name='roberta_wwm_ext_chinese_L-12_H-768_A-12') |
BERT-Base, Uncased | hub.Module(name='bert_uncased_L-12_H-768_A-12') |
BERT-Large, Uncased | hub.Module(name='bert_uncased_L-24_H-1024_A-16') |
BERT-Base, Cased | hub.Module(name='bert_cased_L-12_H-768_A-12') |
BERT-Large, Cased | hub.Module(name='bert_cased_L-24_H-1024_A-16') |
BERT-Base, Multilingual Cased | hub.Module(nane='bert_multi_cased_L-12_H-768_A-12') |
BERT-Base, Chinese | hub.Module(name='bert_chinese_L-12_H-768_A-12') |
PART III. 构建Reader
接着生成一个文本分类的reader,reader负责将dataset的数据进行预处理,首先对文本进行切词,接着以特定格式组织并输入给模型进行训练。
ClassifyReader
的参数有以下三个:
dataset
: 传入PaddleHub Dataset;vocab_path
: 传入ERNIE/BERT模型对应的词表文件路径;max_seq_len
: ERNIE模型的最大序列长度,若序列长度不足,会通过padding方式补到max_seq_len, 若序列长度大于该值,则会以截断方式让序列长度为max_seq_len;sp_model_path
: 传入 ERNIE tiny的subword切分模型路径;word_dict_path
: 传入 ERNIE tiny的词语切分模型路径;
NOTE::其中参数sp_model_path,word_dict_path仅适用于ERNIE tiny,如果使用其他预训练模型,则无需指定这两个参数
reader = hub.reader.ClassifyReader(
dataset=dataset,
vocab_path=module.get_vocab_path(),
sp_model_path=module.get_spm_path(),
word_dict_path=module.get_word_dict_path(),
max_seq_len=128)
PART IV、选择Fine-Tune优化策略
适用于ERNIE/BERT这类Transformer模型的迁移优化策略为AdamWeightDecayStrategy
。详情请查看Strategy。
AdamWeightDecayStrategy
的参数:
learning_rate
: 最大学习率lr_scheduler
: 有linear_decay
和noam_decay
两种衰减策略可选warmup_proprotion
: 训练预热的比例,若设置为0.1, 则会在前10%的训练step中学习率逐步提升到learning_rate
weight_decay
: 权重衰减,类似模型正则项策略,避免模型overfitting
strategy = hub.AdamWeightDecayStrategy(
weight_decay=0.01,
warmup_proportion=0.1,
learning_rate=5e-5,
lr_scheduler="linear_decay",
optimizer_name="adam")
PART V. 选择运行配置
在进行Finetune前,我们可以设置一些运行时的配置,例如如下代码中的配置,表示:
-
use_cuda
:设置为False表示使用CPU进行训练。如果您本机支持GPU,且安装的是GPU版本的PaddlePaddle,我们建议您将这个选项设置为True; -
num_epoch
:Finetune时遍历训练集的次数,; -
batch_size
:每次训练的时候,给模型输入的每批数据大小为16,模型训练时能够并行处理批数据,因此batch_size越大,训练的效率越高,但是同时带来了内存的负荷,过大的batch_size可能导致内存不足而无法训练,因此选择一个合适的batch_size是很重要的一步; -
eval_interval
:每隔50 step在验证集上进行一次性能评估; -
checkpoint_dir
:训练的参数和数据的保存目录; -
strategy
:Fine-tune策略;
更多运行配置,请查看RunConfig
config = hub.RunConfig(
use_cuda=True,
num_epoch=3,
checkpoint_dir="hub_ernie_text_cls_demo",
batch_size=100,
eval_interval=50,
strategy=strategy)
PART VI. 组建Finetune Task
有了合适的预训练模型和准备要迁移的数据集后,我们开始组建一个Task。
- 获取module的上下文环境,包括输入和输出的变量,以及Paddle Program;
- 从输出变量中找到用于情感分类的文本特征pooled_output;
- 在pooled_output后面接入一个全连接层,生成Task;
TextClassifierTask
的参数有:
-
data_reader
:读取数据的reader; -
config
: 运行配置; -
feature
:从预训练提取的特征; -
feed_list
:program需要输入的变量; -
num_classes
:数据集的类别数量; -
metric_choice
:任务评估指标,list类型,默认为["acc"]。metrics_choices支持训练过程中同时评估多个指标,作为最佳模型的判断依据,例如["matthews", "acc"],"matthews"将作为主指标,为最佳模型的判断依据;
NOTE: Reader参数max_seq_len、moduel的context接口参数max_seq_len应该保持一致,最大序列长度max_seq_len
是可以调整的参数,建议值128,根据任务文本长度不同可以调整该值,但最大不超过512。
inputs, outputs, program = module.context(
trainable=True, max_seq_len=128)
# Use "pooled_output" for classification tasks on an entire sentence.
pooled_output = outputs["pooled_output"]
feed_list = [
inputs["input_ids"].name,
inputs["position_ids"].name,
inputs["segment_ids"].name,
inputs["input_mask"].name,
]
cls_task = hub.TextClassifierTask(
data_reader=reader,
feature=pooled_output,
feed_list=feed_list,
num_classes=dataset.num_labels,
config=config,
metrics_choices=["acc"])
Part VII. 开始Finetune
我们选择finetune_and_eval接口来进行模型训练,这个接口在finetune的过程中,会周期性的进行模型效果的评估,以便我们了解整个训练过程的性能变化。
run_states = cls_task.finetune_and_eval()
PART VIII. 使用模型进行预测
当Finetune完成后,我们使用模型来进行预测,整个预测流程大致可以分为以下几步:
- 构建网络
- 生成预测数据的Reader
- 切换到预测的Program
- 加载预训练好的参数
- 运行Program进行预测
- 预测代码如下:
import numpy as np
inv_label_map = {val: key for key, val in reader.label_map.items()}
# Data to be prdicted
data = [[d.text_a, d.text_b] for d in dataset.get_test_examples()[:10]]
index = 0
run_states = cls_task.predict(data=data)
results = [run_state.run_results for run_state in run_states]
for batch_result in results:
# get predict index
batch_result = np.argmax(batch_result, axis=2)[0]
for result in batch_result:
print("%s\tpredict=%s" % (data[index][0], inv_label_map[result]))
index += 1
总的来说,PaddleHub完成迁移学习过程只需下图所展示的6步即可完成。
想了解更多资讯,可访问飞桨PaddlePaddle官网 https://www.paddlepaddle.org.cn/?fr=osc
想尝试在线运行,可关注项目链接:https://aistudio.baidu.com/aistudio/projectdetail/186443
>> 访问 PaddlePaddle 官网,了解更多相关内容。
下载安装命令 ## CPU版本安装命令 pip install -f https://paddlepaddle.org.cn/pip/oschina/cpu paddlepaddle ## GPU版本安装命令 pip install -f https://paddlepaddle.org.cn/pip/oschina/gpu paddlepaddle-gpu