迁移学习
PyTorch BERT ALBERT Python3
最后更新 2020-04-30 19:09 阅读 6811
最后更新 2020-04-30 19:09
阅读 6811
PyTorch BERT ALBERT Python3
1.迁移学习中的有关概念
- 预训练模型(Pretained model)
---大型模型,具备复杂的网络结构,众多的参数量,在NLP领域,往往是语言模型,因为训练是无监督的,可以获得大规模语料
- 微调(Fine-tuning)
---根据给定的预训练模型,改变它的部分参数或者为其新增部分输出结构后,通过在小部分数据集上训练,来使整个模型更好的适应特定任务.
- 微调脚本(Fine-tuning script)
---实现微调过程的代码文件,这些脚本文件中,应包括对预训练模型的调用,对微调参数的选定以及微调结构的更改等,因为微调是一个训练过程,它同样需要一些超参数的设定,往往也包含了整个迁移学习的过程.
- 关于微调脚本的说明
可以使用已经完成的规范脚本
- 两种迁移方式:
1.直接使用预训练模型,进行相同任务的处理,不需要调整参数或模型结构,这些模型开箱即用。但是这种情况一般只适用于普适任务, 如:fasttest工具包中预训练的词向量模型。另外,很多预训练模型开发者为了达到开箱即用的效果,将模型结构分各个部分保存为不同的预训练模型,提供对应的加载方法来完成特定目标.
2.更加主流的迁移学习方式是发挥预训练模型特征抽象的能力,然后再通过微调的方式,通过训练更新小部分参数以此来适应不同的任务。这种迁移方式需要提供小部分的标注数据来进行监督学习.
2. NLP中的标准数据集
- GLUE数据集合的介绍:
GLUE由纽约大学, 华盛顿大学, Google联合推出, 涵盖不同NLP任务类型, 截止至2020年1月其中包括11个子任务数据集, 成为衡量NLP研究发展的衡量标准.
- GLUE数据集合包含以下数据集:
CoLA 数据集---------二分类任务-------评估指标为: MMC(马修斯相关系数, 在正负样本分布十分不均衡下使用)
SST-2 数据集---------二分类任务--------------评估指标为: ACC------情感分析
MRPC 数据集---------句子对二分类任务-----------评估指标为: ACC和F1-----句子对是否语义等价
STS-B 数据集---------句子对多分类任务/句子对回归任务-------评估指标为: Pearson-Spearman Corr---语义相似
QQP 数据集---------句子对二分类任务-----------评估指标为: ACC和F1------语义文本相似性/问题对是否等价
MNLI 数据集---------句子对多分类任务----------评估指标为: ACC-----自然语言推断
SNLI 数据集
QNLI 数据集---------句子对二分类任务-----------评估指标为: ACC----句子是否回答了问题
RTE 数据集---------句子对二分类任务-----------评估指标为: ACC-----自然语言推断 识别蕴涵
WNLI 数据集---------句子对二分类任务-----------评估指标为: ACC---自然语言推断 识别蕴涵
diagnostics数据集(官方未完善)
3 NLP中的常用的预训练模型
- 当下NLP中流行的预训练模型
BERT, GPT, GPT-2, Transformer-XL, XLNet, XLM, RoBERTa, DistilBERT, ALBERT, T5, XLM-RoBERTa
- 预训练模型说明
所有上述训练模型及其变体都是以transformer为基础,对于使用者,不需要理论深度研究,只需要在自己处理目标数据时,尽量遍历所有可用的模型对比得到最优效果即可.
4. 加载和使用预训练模型
- 加载和使用预训练模型的工具:
在这里我们使用torch.hub工具进行模型的加载和使用.
这些预训练模型由世界先进的NLP研发团队huggingface提供.
- 加载和使用预训练模型的步骤:
- 第一步: 确定需要加载的预训练模型并安装依赖包.
pip install tqdm boto3 requests regex sentencepiece sacremoses dataclasses tokenizers filelock
- 第二步: 加载预训练模型的映射器tokenizer.
import torch # 预训练模型的来源 source = 'huggingface/pytorch-transformers' # 选定加载模型那一部分,模型映射器 part = 'tokenizer' # 选择模型名字 model_name = 'bert-base-chinese' tokenizer = torch.hub.load(source, part, model_name)
- 第三步: 加载带/不带头的预训练模型.
# 加载不带头的预训练模型 part = 'model' model = torch.hub.load(source, part, model_name) # 加载带有语言模型头的预训练模型 part = 'modelWithLMHead' lm_model = torch.hub.load(source, part, model_name) # 加载带有类模型头的预训练模型 part = 'modelForSequenceClassification' class_model = torch.hub.load(source, part, model_name) # 加载带有问答模型头的预训练模型 part = 'modelForQuestionAnswering' qa_model = torch.hub.load(source, part, model_name)
- 第四步: 使用模型获得输出结果.
- 使用不带头的模型进行输出
# 输入的中文文本 input_text = "人生该如何起头" # 使用tokenizer进行数值映射 # tokenizer映射后的结果, 101和102是起止符, indexed_tokens = tokenizer.encode(input_text) print("indexed_tokens:", indexed_tokens) # 将映射后的结构用torch.tensor()进行封装 tokens_tensor = torch.tensor([indexed_tokens]) # 使用不带头的预训练模型model获取结果 with torch.no_grad(): encoded_layers, _ = model(tokens_tensor) print("不带头的模型输出结果:", encoded_layers) print("不带头的模型输出结果的尺寸:", encoded_layers.shape)
- 使用带有语言模型头的模型进行输出
# 使用带有语言模型头的预训练模型获得结果 with torch.no_grad(): lm_output = lm_model(tokens_tensor) print("带语言模型头的模型输出结果:", lm_output) print("带语言模型头的模型输出结果的尺寸:", lm_output[0].shape)
- 使用带有分类模型头的模型进行输出
# 使用带有分类模型头的预训练模型获得结果 with torch.no_grad(): classification_output = classification_model(tokens_tensor) print("带分类模型头的模型输出结果:", classification_output) print("带分类模型头的模型输出结果的尺寸:", classification_output[0].shape)
- 使用带有问答模型头的模型进行输出
# 输入两个句子 # 第一句是客观陈述句 # 第二句是对第一句提出的问题 input_text1 = "我家的小狗是黑色的" input_text2 = "我家的小狗是什么颜色的呢" # 映射两个句子 indexed_tokens = tokenizer.encode(input_text1, input_text2) print("句子对应的indexed_tokens:", indexed_tokens) # 利用0来标志第一条语句的位置,1来标志第二条语句位置 segments_ids = [0]*11 + [1]*14 # 转化张量形式 segments_tensor = torch.tensor([segments_ids]) tokens_tensor = torch.tensor([indexed_tokens]) # 使用带有问答模型头的预训练模型model获取结果 with torch.no_grad(): start_logits, end_logits = qa_model(tokens_tensor, token_type_ids=segments_tensor) print("带问答模型头的模型输出结果:", (start_logits, end_logits)) print("带问答模型头的模型输出结果的尺寸:", (start_logits.shape, end_logits.shape))