前言
上一篇文章中讲到了GPT,也简单讲到了GPT和BERT的区别,这里先贴回来温习一下: GPT和BERT之间的区别是:GPT选择了transformer中decoder阶段结构作为预训练结构;而BERT选择了transformer中encoder阶段结构作为预训练结构。 这样首先需要知道encoder结构和decoder结构之间的利弊:
encoder | decoder |
---|
双向网络 | 单向网络 | 没有天然的预测目标(Bert自己构造mask) | 有天然的预测目标(天然mask+预测下一个词) | 能看到所有词(更适合做语言理解) | 只能看到一个词前面的词(更适合做语言预测) |
BERT这里使用了双向的Encoder,再回来看BERT这个名字Bidirectional Encoder Representation from Transformer,就十分贴切了。
如何预训练 pretrain
那么本篇就主要学习下BERT这个预训练模型: 由于GPT使用的是单向网络,这就给了BERT改进的空间–双向网络,双向网络下一个token既能看到它前面的token又能看到它后面的token,上下文信息都知道了,那模型预测什么呢?
“完形填空”mask --Masked Language Model (MLM)
BERT首先想到了“完形填空”的方式,在输入的时候挖掉一些token,让模型去填这些“空”。但是如果只构造mask挖掉一些token会使模型只去关注这些被mask的地方,从而忽视其他部分。 所以BERT采用了以下方式构造mask:
- 80%的token输入时被替换为mask
- 10%的token在输入时被替换为其他token
- 10%的token保持不变
这样模型并不知道被mask的是不是正确的,没被mask的也可能是错误的,就会让模型不至于只关注被mask的地方。
预测下一句 --Next Sentence Prediction (NSP)
除了“完形填空”,BERT这里还有另一种预测方式,就是把任意两个句子拼起来,在第一句前加一个[CLS]的token,用该token去预测是否是可相互连接的句子(这里之前GPT的方式,除了可以判断两句话是否连接,还可以判断两句话是否是相似的,是否是蕴含关系,是否是问题答案关系等等则放在finetune阶段,因为上下句子是否连接完全不需要标签,天然可以有大量的预训练数据)
这里的拼接方式如下图所示[CLS][句子1的token][SEP][句子2的token][SEP]
每个token的输入除了token的embedding还有位置的embedding和分割符的embedding(这里第一个句子的segment embedding 全为0,第二个句子的全为1)
BERT 预训练阶通过将上述两个任务结合起来,将两者的 Loss 相加进行训练: 如下图左边所示,每次既要判断[CLS]输出的0/1是否判断准确,还要判断每个[MASK]的token是否预测准确。
如何finetuning
BERT的finetuning阶段和GPT比较类似,都可以对不同任务进行finetuning。 不同的是BERT在做分类/是否任务时通常采用的是第一个[CLS]的输出,而GPT往往采用最后一个[token]的输出,这里采用第一个[CLS]的输出大概是因为第一个[CLS]是一个无偏袒的token,通过self-attention可以学习到所有其他token的完整信息。 下面两图所示的都是采用[CLS]的输出来进行分类/是否任务的例子: 左边是判断两个句子是否存在推理关系,右边则是判断一个句子的所属分类。 除了分类/是否任务外,BERT还可以做其他,比如预测每个词的标签/分类,预测一句话的答案QA问题等。 下图所示的就是QA问题的一个finetuning,给定一个question和一个可能包含答案的paragraph,对paragraph中question的答案的起始终止位置进行预测(即预测paragraph中每个token的输出分类BIO,或者预测每个单词作为起始/终止位置的概率)
|