接下来使用 BertForMaskedLM() 建立模型,并将模型设置模型成验证模式。由于 BERT 模型体积很大,且托管在外网,所以本次先从网盘下载链接:https://pan.baidu.com/s/1afwmZEXZUFnmSwm6eEvmyg
提取码:qkuc
此时,我们已经准备好了待输入的语句和预训练模型,接下来需要做的就是让模型去预测的覆盖的词的序号。
outputs = model(input_ids) prediction_scores = outputs[0] prediction_scores.shape最后找到预测值中最大值对应的序号,然后通过 tokenizer.convert_ids_to_tokens() 在词表中查找,转换成对应的字。
import numpy as np sample = prediction_scores[0].detach().numpy() pred = np.argmax(sample, axis=1) tokenizer.convert_ids_to_tokens(pred)[14]输出结果应该是:
中可以看到,最后的预测结果是正确的的,说明 BERT 真的对语言有了理解。
句子预测任务预训练 BERT 时除了 MLM 预训练策略,还要进行预测下一个句子的任务。句子预测任务基于理解两个句子间的关系,这种关系无法直接被 Masked Language Model 捕捉到。训练数据的构成是由语料库中的句子组成句子对,详细地说,当选择两个相邻句子 A 和 B 组成预训练样本时,有 50% 的几率使句子 A 在句子 B 之前,50% 的几率使句子 B 在句子 A 之前。尽管这个方法并不复杂,但是这个预训练对于问答任务和自然语言推理任务等下游任务有很好的帮助。
下面我们使用 PyTorch-Transformers 库中的句子预测模型进行,观察一下输出结果。
首先构造输入样本,然后进行分词和词向序号的转换。
samples = ["[CLS]今天天气怎么样?[SEP]今天天气很好。[SEP]", "[CLS]小明今年几岁了?[SEP]小明爱吃西瓜。[SEP]"] tokenizer = BertTokenizer.from_pretrained(model_name) tokenized_text = [tokenizer.tokenize(i) for i in samples] input_ids = [tokenizer.convert_tokens_to_ids(i) for i in tokenized_text] input_ids = torch.LongTensor(input_ids) input_ids构造句子的分段 id,按照上下句分别标为 0 和 1。
segments_ids = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1]] segments_tensors = torch.tensor(segments_ids) segments_tensors接下来使用 BertForNextSentencePrediction() 初始化模型,再加载 BERT 的预训练参数。
from pytorch_transformers import BertForNextSentencePrediction model = BertForNextSentencePrediction.from_pretrained( model_name, cache_dir="./") model.eval()最后将样本输入模型进行预测,输出模型的预测结果。
outputs = model(input_ids) seq_relationship_scores = outputs[0] seq_relationship_scores sample = seq_relationship_scores.detach().numpy() pred = np.argmax(sample, axis=1) pred最终的输出结果应该是:[0, 1]。
0 表示是上下句关系,1 表示不是上下句关系。因此从上面结果可以看到,模型预测第一个句子对是上下句关系,第二个句子对不是,对于这两个样本 BERT 的预测正确。
我们通过两个例子来看 BERT 的效果,都是非常理想的。实际上,BERT 效果好的原因主要有两点:
使用的双向的 Transformer 结构学习到左、右两侧上下文语境。
使用完整的文档语料训练而不是打乱的句子,配合下个句子预测任务,从而学习到了捕捉很长的连续语句中的信息的能力。
BERT 文本分类实践上面,我们使用 BERT 完成了两个小例子。接下来,尝试利用 BERT 完成文本分类任务。实际上,当使用 BERT 完成文本分类时,通常有 2 种方案:
从预训练好的 BERT 模型中提取特征向量,即 Feature Extraction 方法。
将下游任务模型添加到 BERT 模型之后,然后使用下游任务的训练集对进行训练,即 Fine-Tuning 方法。
通常 Fine-Tuning 方法更常被人们使用,因为通过结合下游任务的数据集进行微调从而调整预训练模型参数,使模型能够更好捕捉到下游任务的数据特征。下面使用 Fine-Tuning 方法应用 BERT 预训练模型进行情感分类任务。
首先,下载一个 情感分类数据集,我们已经提前下载好并放在网盘中。