天然语言处理中的语言模型预训练方法(ELMo、GPT和BERT)

天然语言处理中的语言模型预训练方法(ELMo、GPT和BERT)html

最近,在天然语言处理(NLP)领域中,使用语言模型预训练方法在多项NLP任务上都得到了不错的提高,普遍受到了各界的关注。就此,我将最近看的一些相关论文进行总结,选取了几个表明性模型(包括ELMo [1]OpenAI GPT [2]BERT [3])和你们一块儿学习分享。算法

1. 引言

在介绍论文以前,我将先简单介绍一些相关背景知识。首先是语言模型(Language Model),语言模型简单来讲就是一串词序列的几率分布。具体来讲,语言模型的做用是为一个长度为m的文本肯定一个几率分布P,表示这段文本存在的可能性。在实践中,若是文本的长度较长,P(wi | w1, w2, . . . , wi−1)的估算会很是困难。所以,研究者们提出使用一个简化模型:n元模型(n-gram model)。在 n 元模型中估算条件几率时,只须要对当前词的前n个词进行计算。在n元模型中,传统的方法通常采用频率计数的比例来估算n元条件几率。当n较大时,机会存在数据稀疏问题,致使估算结果不许确。所以,通常在百万词级别的语料中,通常也就用到三元模型。网络

为了缓解n元模型估算几率时遇到的数据稀疏问题,研究者们提出了神经网络语言模型。表明性工做是Bengio等人在2003年提出的神经网络语言模型,该语言模型使用了一个三层前馈神经网络来进行建模。其中有趣的发现了第一层参数,用作词表示不只低维紧密,并且可以蕴涵语义,也就为如今你们都用的词向量(例如word2vec)打下了基础。其实,语言模型就是根据上下文去预测下一个词是什么,这不须要人工标注语料,因此语言模型可以从无限制的大规模单语语料中,学习到丰富的语义知识。app

接下来在简单介绍一下预训练的思想。咱们知道目前神经网络在进行训练的时候基本都是基于后向传播(BP)算法,经过对网络模型参数进行随机初始化,而后经过BP算法利用例如SGD这样的优化算法去优化模型参数。那么预训练的思想就是,该模型的参数再也不是随机初始化,而是先有一个任务进行训练获得一套模型参数,而后用这套参数对模型进行初始化,再进行训练。其实早期的使用自编码器栈式搭建深度神经网络就是这个思想。还有词向量也能够当作是第一层word embedding进行了预训练,此外在基于神经网络的迁移学习中也大量用到了这个思想。框架

接下来,咱们就具体看一下这几篇用语言模型进行预训练的工做。函数

2. ELMo

2.1 引言

Deep Contextualized Word Representations》这篇论文来自华盛顿大学的工做,最后是发表在今年的NAACL会议上,并得到了最佳论文。其实这个工做的前身来自同一团队在ACL2017发表的《Semi-supervised sequence tagging with bidirectional language models [4],只是在这篇论文里,他们把模型更加通用化了。首先咱们来看看他们工做的动机,他们认为一个预训练的词表示应该可以包含丰富的句法和语义信息,而且可以对多义词进行建模。而传统的词向量(例如word2vec)是上下文无关的。例以下面"apple"的例子,这两个"apple"根据上下文意思是不一样的,可是在word2vec中,只有apple一个词向量,没法对一词多义进行建模。性能

因此他们利用语言模型来得到一个上下文相关的预训练表示,称为ELMo,并在6NLP任务上得到了提高。学习

2.2 方法

EMLo中,他们使用的是一个双向的LSTM语言模型,由一个前向和一个后向语言模型构成,目标函数就是取这两个方向语言模型的最大似然。大数据

在预训练好这个语言模型以后,ELMo就是根据下面的公式来用做词表示,其实就是把这个双向语言模型的每一中间层进行一个求和。最简单的也可使用最高层的表示来做为ELMo优化

而后在进行有监督的NLP任务时,能够将ELMo直接当作特征拼接到具体任务模型的词向量输入或者是模型的最高层表示上。总结一下,不像传统的词向量,每个词只对应一个词向量,ELMo利用预训练好的双向语言模型,而后根据具体输入从该语言模型中能够获得上下文依赖的当前词表示(对于不一样上下文的同一个词的表示是不同的),再当成特征加入到具体的NLP有监督模型里。

2.3 实验

这里咱们简单看一下主要的实验,具体实验还需阅读论文。首先是整个模型效果的实验。他们在6NLP任务上进行了实验,首先根据目前每一个任务搭建了不一样的模型做为baseline,而后加入ELMo,能够看到加入ELMo6个任务都有所提高,平均大约可以提高2个多百分点,而且最后的结果都超过了以前的先进结果(SOTA)。

在下面的分析实验中,咱们能够看到使用全部层的效果要比只使用最后一层做为ELMo的效果要好。在输入仍是输出上面加EMLo效果好的问题上,并无定论,不一样的任务可能效果不同。

3. Open AI GPT

3.1 引言

咱们来看看第二篇论文《Improving Language Understanding by Generative Pre-Training》,这是OpenAI 团队前一段时间放出来的预印版论文。他们的目标是学习一个通用的表示,可以在大量任务上进行应用。这篇论文的亮点主要在于,他们利用了Transformer网络代替了LSTM做为语言模型来更好的捕获长距离语言结构。而后在进行具体任务有监督微调时使用了语言模型做为附属任务训练目标。最后再12NLP任务上进行了实验,9个任务得到了SOTA

3.2 方法

首先咱们来看一下他们无监督预训练时的语言模型。他们仍然使用的是标准的语言模型目标函数,即经过前k个词预测当前词,可是在语言模型网络上他们使用了google团队在《Attention is all your need》论文中提出的Transformer解码器做为语言模型。Transformer模型主要是利用自注意力(self-attention)机制的模型,这里我就很少进行介绍,你们能够看论文或者参考我以前的博客(https://www.cnblogs.com/robert-dlut/p/8638283.html)。

而后再具体NLP任务有监督微调时,与ELMo当成特征的作法不一样,OpenAI GPT不须要再从新对任务构建新的模型结构,而是直接在transformer这个语言模型上的最后一层接上softmax做为任务输出层,而后再对这整个模型进行微调。他们额外发现,若是使用语言模型做为辅助任务,可以提高有监督模型的泛化能力,而且可以加速收敛。

因为不一样NLP任务的输入有所不一样,在transformer模型的输入上针对不一样NLP任务也有所不一样。具体以下图,对于分类任务直接讲文本输入便可;对于文本蕴涵任务,须要将前提和假设用一个Delim分割向量拼接后进行输入;对于文本类似度任务,在两个方向上都使用Delim拼接后,进行输入;对于像问答多选择的任务,就是将每一个答案和上下文进行拼接进行输入。

3.3 实验

下面我简单的列举了一下不一样NLP任务上的实验结果。

语言推理任务:

问答和常识推理任务:

语义类似度和分类任务:

能够看到在多项任务上,OpenAI GPT的效果要比ELMo的效果更好。从下面的消除实验来看,在去掉预训练部分后,全部任务都大幅降低,平均降低了14.8%,说明预训练颇有效;在大数据集上使用语言模型做为附加任务的效果更好,小数据集否则;利用LSTM代替Transformer后,结果平均降低了5.6%,也体现了Transformer的性能。

4. BERT

4.1引言

上周Google放出了他们的语言模型预训练方法,瞬时受到了各界普遍关注,很多媒体公众号也进行了相应报道,那咱们来看看这篇论文《BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding》。这篇论文把预训练语言表示方法分为了基于特征的方法(表明ELMo)和基于微调的方法(表明OpenAI GPT)。而目前这两种方法在预训练时都是使用单向的语言模型来学习语言表示。

这篇论文中,做者们证实了使用双向的预训练效果更好。其实这篇论文方法的总体框架和GPT相似,是进一步的发展。具体的,他们BERT是使用Transformer的编码器来做为语言模型,在语言模型预训练的时候,提出了两个新的目标任务(即遮挡语言模型MLM和预测下一个句子的任务),最后在11NLP任务上取得了SOTA

4.2方法

在语言模型上,BERT使用的是Transformer编码器,而且设计了一个小一点Base结构和一个更大的Large网络结构。

对比一下三种语言模型结构,BERT使用的是Transformer编码器,因为self-attention机制,因此模型上下层直接所有互相链接的。而OpenAI GPT使用的是Transformer解码器,它是一个须要从左到右的受限制的Transformer,而ELMo使用的是双向LSTM,虽然是双向的,可是也只是在两个单向的LSTM的最高层进行简单的拼接。因此做者们任务只有BERT是真正在模型全部层中是双向的。

而在模型的输入方面,BERT作了更多的细节,以下图。他们使用了WordPiece embedding做为词向量,并加入了位置向量和句子切分向量。并在每个文本输入前加入了一个CLS向量,后面会有这个向量做为具体的分类向量。

在语言模型预训练上,他们不在使用标准的从左到右预测下一个词做为目标任务,而是提出了两个新的任务。第一个任务他们称为MLM,即在输入的词序列中,随机的挡上15%的词,而后任务就是去预测挡上的这些词,能够看到相比传统的语言模型预测目标函数,MLM能够从任何方向去预测这些挡上的词,而不只仅是单向的。可是这样作会带来两个缺点:1)预训练用[MASK]提出挡住的词后,在微调阶段是没有[MASK]这个词的,因此会出现不匹配;2)预测15%的词而不是预测整个句子,使得预训练的收敛更慢。可是对于第二点,做者们以为虽然是慢了,可是效果提高比较明显能够弥补。

对于第一点他们采用了下面的技巧来缓解,即不是老是用[MASK]去替换挡住的词,在10%的时间用一个随机词取替换,10%的时间就用这个词自己。

而对于传统语言模型,并无对句子之间的关系进行考虑。为了让模型可以学习到句子之间的关系,做者们提出了第二个目标任务就是预测下一个句子。其实就是一个二元分类问题,50%的时间,输入一个句子和下一个句子的拼接,分类标签是正例,而另50%是输入一个句子和非下一个随机句子的拼接,标签为负例。最后整个预训练的目标函数就是这两个任务的取和求似然。

在微调阶段,不一样任务的模型以下图,只是在输入层和输出层有所区别,而后整个模型全部参数进行微调。

4.3 实验

下面咱们列出一下不一样NLPBERT的效果。

GLUE结果:

QA结果:

实体识别结果:

SWAG结果:

能够看到在这些全部NLP任务上,BERT都取得了SOTA,并且相比EMLoGPT的效果提高仍是比较大的。

在预训练实验分析上,能够看到本文提出的两个目标任务的做用仍是颇有效的,特别是在MLM这个目标任务上。

做者也作了模型规模的实验,大规模的模型效果更好,即便在小数据集上。

此外,做者也作了像ELMo当成特征加入的实验,从下图能够看到,当成特征加入最好效果能达到96.1%和微调的96.4%差很少,说明BERT对于基于特征和基于微调这两种方法都是有效的。

 

5. 总结

最后进行简单的总结,和传统的词向量相比,使用语言模型预训练其实能够当作是一个句子级别的上下文的词表示,它能够充分利用大规模的单语语料,而且能够对一词多义进行建模。并且从后面两篇论文能够看到,经过大规模语料预训练后,使用统一的模型或者是当成特征直接加到一些简单模型上,对各类NLP任务都能取得不错的效果,说明很大程度上缓解了具体任务对模型结构的依赖。在目前不少评测上也都取得了SOTAELMo也提供了官网供你们使用。可是这些方法在空间和时间复杂度上都比较高,特别是BERT,在论文中他们训练base版本须要在16TGPU上,large版本须要在64TPU上训练4天,对于通常条件,一个GPU训练的话,得用上1年。还有就是能够看出这些方法里面都存在不少工程细节,一些细节作得很差的话,效果也会大大折扣。

 

参考文献

[1] Peters, M. E. et al. Deep contextualized word representations. naacl (2018).

[2] Radford, A. & Salimans, T. Improving Language Understanding by Generative Pre-Training. (2018).

[3] Devlin, J., Chang, M.-W., Lee, K. & Toutanova, K. BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding. (2018).

[4] Peters, M. E., Ammar, W., Bhagavatula, C. & Power, R. Semi-supervised sequence tagging with bidirectional language models. Acl (2017).