最近要开始使用Transformer去做一些事情了,特地把与此相关的知识点记录下来,构建相关的、完整的知识结构体系。
以下是要写的文章,文章大部分都发布在公众号【雨石记】上,欢迎关注公众号获取最新文章。
Bert,全称是Bidirectional Encoder Representation from Transformers。顾名思义,主要的亮点是双向编码+Transformer模型。
在上一文《GPT》中,我们知道GPT是一个标准的语言模型,即用context来预测下一个词。这样就有两个缺点:
因此,Bert这样的双向网络应运而生,但既然是双向的网络,那么就有一个问题,那就是损失函数该如何设置?GPT的损失函数非常直观,预测下一个词正确的概率,而Bert则是见到了所有的词,如何构建损失函数来训练网络呢?这就涉及到一种称之为Masked Language Model的预训练目标函数。另外,为了使模型更适用于句子级别的任务,Bert中还采用了一种称之为Next Sentence Prediction的目标函数,来使得模型能更好的捕捉句子信息。我们在下面会一一讲到。
Bert依然是依赖Transformer模型结构,我们知道GPT采用的是Transformer中的Decoder部分的模型结构,当前位置只能attend到之前的位置。而Bert中则没有这样的限制,因此它是用的Transformer的Encoder部分。
而Transformer是由一个一个的block组成的,其主要参数如下:
有了这几个参数后,就可以定义不同配置的模型了,Bert中定义了两个模型,
BertBase和BertLarge。其中:
为了让Bert能够处理下游任务,Bert的输入是两个句子,中间用分隔符分开,在开头加一个特殊的用于分类的字符。即Bert的输入是: [CLS] sentence1 [SEP] sentence2
。
其中,两个句子对应的词语对应的embedding还要加上位置embedding和标明token属于哪个句子的embedding。如下图所示:
在[CLS]上的输出我们认为是输入句子的编码。
输入最长是512。
一般语言模型建模的方式是从左到右或者从右到左,这样的损失函数都很直观,即预测下一个词的概率。
而Bert这种双向的网络,使得下一个词
这个概念消失了,没有了目标,如何做训练呢?
答案就是完形填空
,在输入中,把一些词语遮挡住,遮挡的方法就是用[Mask]这个特殊词语代替。而在预测的时候,就预测这些被遮挡住的词语。其中遮挡词语占所有词语的15%,且是每次随机Mask。
但这有一个问题:在预训练中会[Mask]这个词语,但是在下游任务中,是没有这个词语的,这会导致预训练和下游任务的不匹配。
不匹配的意思我理解就是在预训练阶段任务中,模型会学到句子中有被遮挡的词语,模型要去学习它,而在下游任务中没有,但是模型会按照预训练的习惯去做,会导致任务的不匹配。
解决的办法就是不让模型意识到有这个任务的存在,具体做法就是在所有Mask的词语中,有80%的词语继续用[Mask]特殊词语,有10%用其他词语随机替换,有10%的概率保持不变。这样,模型就不知道当前句子中有没[Mask]的词语了。
在很多下游任务中,需要判断两个句子之间的关系,比如QA问题,需要判断一个句子是不是另一个句子的答案,比如NLI(Natural Language Inference)问题,直接就是两个句子之间的三种关系判断。
因此,为了能更好的捕捉句子之间的关系,在预训练的时候,就做了一个句子级别的损失函数,这个损失函数的目的很简单,就是判断第二个句子是不是第一个句子的下一句。训练时,会随机选择生成训练语料,50%的时下一句,50%的不是。
有了模型,输入输出,目标函数,就可以训练模型了,那么在得到模型之后,如何去微调使之适应下游任务呢?
我们以Question-Answering问题为例来解释,如下图所示:
左图是Bert的预训练,输入是被遮挡的句子;右图是在Question Answer问题上微调。输入是Question和Paragraph,想要得到的是Paragraph上的答案的位置,包括起始位置和结束位置。
所以,先预定义两个embedding分别给起始位置和结束位置。然后,将paragraph在Bert上的每一个输出embedding去和这两个embedding分别做内积然后计算softmax,就得到的损失函数。有了损失函数就可以训练了。
再比如文本分类问题,文本分类和句子之间的关系无关。因而,在微调的时候,可以把Sentence B设置为空,然后把句子输入给bert,拿到[CLS]的输出再加一个全连接层去做分类。
在Glue Task上的微调的结果如下,Glue Task是一系列的任务,包括文本分类,句子关系判断等,这些问题包括:
在这些任务上的表现:
Bert在当时取得了最好的成绩。
SQuAD就是上面微调那一节中描述的在Paragraph中找位置的问题。
在两个版本的SquAD上取得的结果如下图,两个版本的区别在于SQuAD中有的样本没有答案。
把一些必备要素去掉或者换掉后的效果。可见,不管是去掉NSP,还是把Transformer替换掉,都会带来效果的降低。
自然是大力出奇迹。
勤思考, 多提问是Engineer的良好品德。
提问如下:
回答后续公布,欢迎关注公众号【雨石记】