综述
ELMo,GPT,Bert都是NLP任务中的预训练模型,可以根据语料的上下文动态地调整词向量,不再像是在Word2Vec,GloVe,fastText这些预训练模型中,一旦确定了一个词的向量便不会再变。举个简单的例子,apple可以有两种意思,一个意思是水果,另一个意思是公司。如果使用Word2Vec,GloVe,FastText这些模型去训练,得到的apple只能有一个词向量,但是一个词向量是无法区分apple的两个意思的。ELMo,GPT和Bert这三个预训练模型不仅可以解决多义词的缺陷,而且GPT和Bert预训练的产物并不仅仅是词向量,还顺带包括解决NLP任务的模型参数。就是说GPT和Bert不仅帮我们预训练好词向量,还帮我们设计好怎么解决下游的NLP问题,不需要再重新设计模型。
ELMo
ELMo模型使用上下文预测中心词作为词向量的预训练任务,将预测中心词看作从两个方向预测中心词,有最大似然目标如下:
其中$P(w_i|w_1,w_2,..w_{i-1}|\theta)$使用正向LSTM输出,$P(w_i|w_{i+1},w_{i+2},…,w_n|\theta)$使用反向LSTM输出。通过对这两个LSTM模型学习参数,最大化语料库的似然函数。学习完模型参数后,当ELMo作为预训练模型用于下游NLP任务时,对每一层的LSTM输出作一个加权求和得到词向量,然后将词向量作用于下游NLP任务。
GPT
GPT模型使用上文预测下一个词作为词向量的预训练任务,将预测下一个词看作从前文预测下一个词,有最大似然目标函数如下:
与ELMo模型不同,GPT使用Transformer解码器代替LSTM输出$P(w_i|w_1,w_2,…,w_{i-1},\theta)$。Transformer解码器和Transformer编码器不同,解码器在计算attention时会通过mask层阻挡预测词下文的影响,只使用预测词上文来输出预测词位置的向量。通过预训练我们可以得到词向量和Transformer解码器的参数。从某种意义上说,GPT已经不是为了学习词向量了,GPT是为了得到一个通用NLP任务的预训练模型。我们从GPT的输入可以看到,词向量是固定的,但是当词向量作用于Transformer解码器互相影响后得到的输出,这些输出不仅具有词的语义信息还具有了整段文本的句法与语义信息了,所以我们不能把Transformer解码器的输出简单看作是词向量的输出了。利用GPT的输出,我们可以根据不同的NLP任务在Transformer解码器的输出后面简单添加一些层或稍作组合,就可以用于解决各种NLP任务。实验表明,在针对不同NLP任务时,添加上GPT的预训练任务一起学习效果会更好。
Bert
Bert和GPT一样,也是奔着得到一个通用NLP任务的预训练模型的目的。Bert使用Transformer编码器代替GPT的Transformer解码器,想要通过上下文去预测中心词而不是仅通过上文预测下一个词,即目标函数如下:
ELMo模型虽然有用到双向,但是将上文和下文的作用看作是两个独立的作用,并不是真正的双向,真正的双向应该是上文和下文共同起作用而不是独立起作用。Transformer编码器在每一层与每一层之间都是全连接的,也就是每个词都可以受到上文词和下文词的影响。但是在使用Transformer编码器预测中心词时有一个很大的问题,就是自己可以看见自己,因为Transformer编码器每层之间是全连通的。所以为了解决这个问题,Bert将语料库中15%的词替换成标记[mask],然后在预测时只计算这部分[mask]的预测结果的似然函数,只利用这部分似然函数调整模型参数。然后这又有一个问题,就是在将Bert用于一些NLP任务时,输入的语料是不会有[mask]标记的,除非是完形填空任务。所以需要确保Bert具备“穿透”作用,即确定Bert可以自己看见自己。所以在15%的[mask]中选出10%恢复为原来的词,这样在计算似然函数时会要求模型自己看见自己输出这个位置的词。然后Bert厉害的地方是Bert还考虑到了纠错,当处理单词纠错复原任务或本身输入语料存在错误时,输入语料的一些位置的词语是不正确的,为了模拟这种情况,Bert在15%[mask]中再选出10%随机替换成其他词。现在Bert通过预测这15%的词作为预训练任务学习模型参数,学习出来的模型可以很好地应对完型填空,单词纠错复原,文本分类等任务了。
Bert的预训练任务除了通过上下文预测中心词以外,还有一个预测句子关系的任务。输入是使用一个分隔符连接的两个句子,输出是判断两个句子是否存在上下关系,即第二个句子是否是第一个句子的下一个句子。Bert对这两个预训练任务一起学习,不断调整模型参数,最终得到了现在我们常见的Bert预训练模型了。现在总结一下Bert的工作流程:
预训练之完型填空:
(1) 随机选择15%单词使用[mask]标记覆盖
(2) 从15%的[mask]中,随机选择10%复原,再随机选择10%随机替换成另一个词
(3) 输入是词向量+位置向量+句子向量(句子向量全部相同)
(4) 对15%的单词计算似然函数,通过梯度法不断调整模型参数最大化似然函数
预训练之句子关系预测:
(1) 使用一个分隔符按顺序串联两个句子
(2) 对每一对构成上下关系的句子,随机选择一对不构成上下关系的句子作为负例。
(3) 输入是词向量+位置向量+句子向量(不同句子的句子向量不同,同一句子的句子向量相同)
(4) 对两个句子,预测第二句话是否是第一句话的下一句话。不断调整参数降低预测错误率。
得到Bert预训练模型后,就可以使用Bert处理各种NLP任务了。关于Bert更详细的解析以及Bert怎么用于各种NLP任务,可以参考这篇文章:https://zhuanlan.zhihu.com/p/46652512
最后再贴上一篇很不错的关于ELMo,GPT和Bert的文章:https://www.cnblogs.com/robert-dlut/p/9824346.html