从Word Embedding到Bert模型—天然语言处理中的预训练技术发展史

从Word Embedding到Bert模型—天然语言处理中的预训练技术发展史

Bert最近很火,应该是最近最火爆的AI进展,网上的评价很高,那么Bert值得这么高的评价吗?我我的判断是值得。那为何会有这么高的评价呢?是由于它有重大的理论或者模型创新吗?其实并无,从模型创新角度看通常,创新不算大。可是架不住效果太好了,基本刷新了不少NLP的任务的最好性能,有些任务还被刷爆了,这个才是关键。另一点是Bert具有普遍的通用性,就是说绝大部分NLP任务均可以采用相似的两阶段模式直接去提高效果,这个第二关键。客观的说,把Bert当作最近两年NLP重大进展的集大成者更符合事实。react

本文的主题是天然语言处理中的预训练过程,会大体说下NLP中的预训练技术是一步一步如何发展到Bert模型的,从中能够很天然地看到Bert的思路是如何逐渐造成的,Bert的历史沿革是什么,继承了什么,创新了什么,为何效果那么好,主要缘由是什么,以及为什么说模型创新不算太大,为什么说Bert是近年来NLP重大进展的集大成者。咱们一步一步来说,而串起来这个故事的脉络就是天然语言的预训练过程,可是落脚点仍是在Bert身上。要讲天然语言的预训练,得先从图像领域的预训练提及。算法

 

图像领域的预训练

自从深度学习火起来后,预训练过程就是作图像或者视频领域的一种比较常规的作法,有比较长的历史了,并且这种作法颇有效,能明显促进应用的效果。网络

 

 

 

那么图像领域怎么作预训练呢,上图展现了这个过程,咱们设计好网络结构之后,对于图像来讲通常是CNN的多层叠加网络结构,能够先用某个训练集合好比训练集合A或者训练集合B对这个网络进行预先训练,在A任务上或者B任务上学会网络参数,而后存起来以备后用。假设咱们面临第三个任务C,网络结构采起相同的网络结构,在比较浅的几层CNN结构,网络参数初始化的时候能够加载A任务或者B任务学习好的参数,其它CNN高层参数仍然随机初始化。以后咱们用C任务的训练数据来训练网络,此时有两种作法,一种是浅层加载的参数在训练C任务过程当中不动,这种方法被称为“Frozen”;另一种是底层网络参数尽管被初始化了,在C任务训练过程当中仍然随着训练的进程不断改变,这种通常叫“Fine-Tuning”,顾名思义,就是更好地把参数进行调整使得更适应当前的C任务。通常图像或者视频领域要作预训练通常都这么作。app

这么作有几个好处,首先,若是手头任务C的训练集合数据量较少的话,现阶段的好用的CNN好比Resnet/Densenet/Inception等网络结构层数很深,几百万上千万参数量算起步价,上亿参数的也很常见,训练数据少很难很好地训练这么复杂的网络,可是若是其中大量参数经过大的训练集合好比ImageNet预先训练好直接拿来初始化大部分网络结构参数,而后再用C任务手头比较可怜的数据量上Fine-tuning过程去调整参数让它们更适合解决C任务,那事情就好办多了。这样原先训练不了的任务就能解决了,即便手头任务训练数据也很多,加个预训练过程也能极大加快任务训练的收敛速度,因此这种预训练方式是老小皆宜的解决方案,另外疗效又好,因此在作图像处理领域很快就流行开来。机器学习

那么新的问题来了,为何这种预训练的思路是可行的?ide

 

目前咱们已经知道,对于层级的CNN结构来讲,不一样层级的神经元学习到了不一样类型的图像特征,由底向上特征造成层级结构,如上图所示,若是咱们手头是我的脸识别任务,训练好网络后,把每层神经元学习到的特征可视化肉眼看一看每层学到了啥特征,你会看到最底层的神经元学到的是线段等特征,图示的第二个隐层学到的是人脸五官的轮廓,第三层学到的是人脸的轮廓,经过三步造成了特征的层级结构,越是底层的特征越是全部不论什么领域的图像都会具有的好比边角线弧线等底层基础特征,越往上抽取出的特征越与手头任务相关。正由于此,因此预训练好的网络参数,尤为是底层的网络参数抽取出特征跟具体任务越无关,越具有任务的通用性,因此这是为什么通常用底层预训练好的参数初始化新任务网络参数的缘由。而高层特征跟任务关联较大,实际能够不用使用,或者采用Fine-tuning用新数据集合清洗掉高层无关的特征抽取器。函数

通常咱们喜欢用ImageNet来作网络的预训练,主要有两点,一方面ImageNet是图像领域里有超多事先标注好训练数据的数据集合,份量足是个很大的优点,量越大训练出的参数越靠谱;另一方面由于ImageNet有1000类,类别多,算是通用的图像数据,跟领域没太大关系,因此通用性好,预训练完后哪哪都能用,是个万金油。份量足的万金油固然老小通吃,人人喜好。工具

听完上述话,若是你是具有研究素质的人,也就是说具有好奇心,你必定会问下面这个问题:”既然图像领域预训练这么好用,那干吗天然语言处理不作这个事情呢?是否是搞NLP的人比搞CV的傻啊?就算你傻,你看见人家这么作,有样学样不就好了吗?这不就是创新吗,也许能成,万一成了,你看,你的成功来得就是这么忽然!”性能

嗯,好问题,其实搞NLP的人一点都不比你傻,早就有人尝试过了,不过整体而言不太成功而已。据说过word embedding吗?2003年出品,陈年技术,馥郁芳香。word embedding其实就是NLP里的早期预训练技术。固然也不能说word embedding不成功,通常加到下游任务里,都能有1到2个点的性能提高,只是没有那么耀眼的成功而已。

没听过?那下面就把这段陈年老帐讲给你听听。

 

Word Embedding考古史

这块大体讲讲Word Embedding的故事,很粗略,由于网上关于这个技术讲的文章太多了,汗牛冲动,我不属牛,此刻更没有流汗,因此其实丝毫没有想讲Word Embedding的冲动和激情,可是要说预训练又得从这开始,那就粗略地讲讲,主要是引出后面更精彩的部分。在说Word Embedding以前,先更粗略地说下语言模型,由于通常NLP里面作预训练通常的选择是用语言模型任务来作。

 

 

什么是语言模型?其实看上面这张PPT上扣下来的图就明白了,为了可以量化地衡量哪一个句子更像一句人话,能够设计如上图所示函数,核心函数P的思想是根据句子里面前面的一系列前导单词预测后面跟哪一个单词的几率大小(理论上除了上文以外,也能够引入单词的下文联合起来预测单词出现几率)。句子里面每一个单词都有个根据上文预测本身的过程,把全部这些单词的产生几率乘起来,数值越大表明这越像一句人话。语言模型压下暂且不表,我隐约预感到我这么讲你可能仍是不太会明白,可是大概这个意思,不懂的能够去网上找,资料多得同样地汗牛冲动。

假设如今让你设计一个神经网络结构,去作这个语言模型的任务,就是说给你不少语料作这个事情,训练好一个神经网络,训练好以后,之后输入一句话的前面几个单词,要求这个网络输出后面紧跟的单词应该是哪一个,你会怎么作?

 

 

你能够像上图这么设计这个网络结构,这其实就是大名鼎鼎的中文人称“神经网络语言模型”,英文小名NNLM的网络结构,用来作语言模型。这个工做有年头了,是个陈年老工做,是Bengio 在2003年发表在JMLR上的论文。它生于2003,火于2013,之后是否会不朽暂且不知,可是不幸的是出生后应该没有引发太大反响,沉寂十年终于时来运转沉冤得雪,在2013年又被NLP考古工做者从海底湿淋淋地捞出来了祭入神殿。为何会发生这种技术奇遇记?你要想一想2013年是什么年头,是深度学习开始渗透NLP领域的光辉时刻,万里长征第一步,而NNLM能够算是南昌起义第一枪。在深度学习火起来以前,极少有人用神经网络作NLP问题,若是你10年前坚持用神经网络作NLP,估计别人会认为你这人神经有问题。所谓红尘滚滚,谁也挡不住历史发展趋势的车轮,这就是个很好的例子。

上面是闲话,闲言碎语不要讲,咱们回来说一讲NNLM的思路。先说训练过程,如今看其实很简单,见过RNN、LSTM、CNN后的大家回头再看这个网络甚至显得有些简陋。学习任务是输入某个句中单词 W_t=“Bert” 前面句子的t-1个单词,要求网络正确预测单词Bert,即最大化:

  P(W_t=“Bert”|W_1,W_2,…W_(t-1);θ)

前面任意单词 W_i 用Onehot编码(好比:0001000)做为原始单词输入,以后乘以矩阵Q后得到向量 C(W_i ) ,每一个单词的 C(W_i ) 拼接,上接隐层,而后接softmax去预测后面应该后续接哪一个单词。这个 C(W_i ) 是什么?这其实就是单词对应的Word Embedding值,那个矩阵Q包含V行,V表明词典大小,每一行内容表明对应单词的Word embedding值。只不过Q的内容也是网络参数,须要学习得到,训练刚开始用随机值初始化矩阵Q,当这个网络训练好以后,矩阵Q的内容被正确赋值,每一行表明一个单词对应的Word embedding值。因此你看,经过这个网络学习语言模型任务,这个网络不只本身可以根据上文预测后接单词是什么,同时得到一个副产品,就是那个矩阵Q,这就是单词的Word Embedding是被如何学会的。

2013年最火的用语言模型作Word Embedding的工具是Word2Vec,后来又出了Glove,Word2Vec是怎么工做的呢?看下图。

 

 

Word2Vec的网络结构其实和NNLM是基本相似的,只是这个图长得清晰度差了点,看上去不像,其实它们是亲兄弟。不过这里须要指出:尽管网络结构相近,并且也是作语言模型任务,可是其训练方法不太同样。Word2Vec有两种训练方法,一种叫CBOW,核心思想是从一个句子里面把一个词抠掉,用这个词的上文和下文去预测被抠掉的这个词;第二种叫作Skip-gram,和CBOW正好反过来,输入某个单词,要求网络预测它的上下文单词。而你回头看看,NNLM是怎么训练的?是输入一个单词的上文,去预测这个单词。这是有显著差别的。为何Word2Vec这么处理?缘由很简单,由于Word2Vec和NNLM不同,NNLM的主要任务是要学习一个解决语言模型任务的网络结构,语言模型就是要看到上文预测下文,而word embedding只是无意插柳的一个副产品。可是Word2Vec目标不同,它单纯就是要word embedding的,这是主产品,因此它彻底能够随性地这么去训练网络。

为何要讲Word2Vec呢?这里主要是要引出CBOW的训练方法,BERT其实跟它有关系,后面会讲它们之间是如何的关系,固然它们的关系BERT做者没说,是我猜的,至于我猜的对不对,后面你看后本身判断。

 

使用Word2Vec或者Glove,经过作语言模型任务,就能够得到每一个单词的Word Embedding,那么这种方法的效果如何呢?上图给了网上找的几个例子,能够看出有些例子效果仍是很不错的,一个单词表达成Word Embedding后,很容易找出语义相近的其它词汇。

咱们的主题是预训练,那么问题是Word Embedding这种作法能算是预训练吗?这其实就是标准的预训练过程。要理解这一点要看看学会Word Embedding后下游任务是怎么用它的。

 

假设如上图所示,咱们有个NLP的下游任务,好比QA,就是问答问题,所谓问答问题,指的是给定一个问题X,给定另一个句子Y,要判断句子Y是不是问题X的正确答案。问答问题假设设计的网络结构如上图所示,这里不展开讲了,懂得天然懂,不懂的也不要紧,由于这点对于本文主旨来讲不关键,关键是网络如何使用训练好的Word Embedding的。它的使用方法其实和前面讲的NNLM是同样的,句子中每一个单词以Onehot形式做为输入,而后乘以学好的Word Embedding矩阵Q,就直接取出单词对应的Word Embedding了。这乍看上去好像是个查表操做,不像是预训练的作法是吧?其实否则,那个Word Embedding矩阵Q其实就是网络Onehot层到embedding层映射的网络参数矩阵。因此你看到了,使用Word Embedding等价于什么?等价于把Onehot层到embedding层的网络用预训练好的参数矩阵Q初始化了。这跟前面讲的图像领域的低层预训练过程实际上是同样的,区别无非Word Embedding只能初始化第一层网络参数,再高层的参数就无能为力了。下游NLP任务在使用Word Embedding的时候也相似图像有两种作法,一种是Frozen,就是Word Embedding那层网络参数固定不动;另一种是Fine-Tuning,就是Word Embedding这层参数使用新的训练集合训练也须要跟着训练过程更新掉。

上面这种作法就是18年以前NLP领域里面采用预训练的典型作法,以前说过,Word Embedding其实对于不少下游NLP任务是有帮助的,只是帮助没有大到闪瞎忘记戴墨镜的围观群众的双眼而已。那么新问题来了,为何这样训练及使用Word Embedding的效果没有期待中那么好呢?答案很简单,由于Word Embedding有问题呗。这貌似是个比较弱智的答案,关键是Word Embedding存在什么问题?这实际上是个好问题。

 

 

这片在Word Embedding头上笼罩了好几年的乌云是什么?是多义词问题。咱们知道,多义词是天然语言中常常出现的现象,也是语言灵活性和高效性的一种体现。多义词对Word Embedding来讲有什么负面影响?如上图所示,好比多义词Bank,有两个经常使用含义,可是Word Embedding在对bank这个单词进行编码的时候,是区分不开这两个含义的,由于它们尽管上下文环境中出现的单词不一样,可是在用语言模型训练的时候,不论什么上下文的句子通过word2vec,都是预测相同的单词bank,而同一个单词占的是同一行的参数空间,这致使两种不一样的上下文信息都会编码到相同的word embedding空间里去。因此word embedding没法区分多义词的不一样语义,这就是它的一个比较严重的问题。

你可能以为本身很聪明,说这能够解决啊,确实也有不少研究人员提出不少方法试图解决这个问题,可是从今天往回看,这些方法看上去都成本过高或者太繁琐了,有没有简单优美的解决方案呢?

ELMO提供了一种简洁优雅的解决方案。

 

从Word Embedding到ELMO

ELMO是“Embedding from Language Models”的简称,其实这个名字并无反应它的本质思想,提出ELMO的论文题目:“Deep contextualized word representation”更能体现其精髓,而精髓在哪里?在deep contextualized这个短语,一个是deep,一个是context,其中context更关键。在此以前的Word Embedding本质上是个静态的方式,所谓静态指的是训练好以后每一个单词的表达就固定住了,之后使用的时候,不论新句子上下文单词是什么,这个单词的Word Embedding不会跟着上下文场景的变化而改变,因此对于好比Bank这个词,它事先学好的Word Embedding中混合了几种语义 ,在应用中来了个新句子,即便从上下文中(好比句子包含money等词)明显能够看出它表明的是“银行”的含义,可是对应的Word Embedding内容也不会变,它仍是混合了多种语义。这是为什么说它是静态的,这也是问题所在。ELMO的本质思想是:我事先用语言模型学好一个单词的Word Embedding,此时多义词没法区分,不过这不要紧。在我实际使用Word Embedding的时候,单词已经具有了特定的上下文了,这个时候我能够根据上下文单词的语义去调整单词的Word Embedding表示,这样通过调整后的Word Embedding更能表达在这个上下文中的具体含义,天然也就解决了多义词的问题了。因此ELMO自己是个根据当前上下文对Word Embedding动态调整的思路。

ELMO采用了典型的两阶段过程,第一个阶段是利用语言模型进行预训练;第二个阶段是在作下游任务时,从预训练网络中提取对应单词的网络各层的Word Embedding做为新特征补充到下游任务中。上图展现的是其预训练过程,它的网络结构采用了双层双向LSTM,目前语言模型训练的任务目标是根据单词 W_i 的上下文去正确预测单词 W_i , W_i 以前的单词序列Context-before称为上文,以后的单词序列Context-after称为下文。图中左端的前向双层LSTM表明正方向编码器,输入的是从左到右顺序的除了预测单词外 W_i 的上文Context-before和下文Context-after;右端的逆向双层LSTM表明反方向编码器,输入的是从右到左的逆序的句子上文和下文;每一个编码器的深度都是两层LSTM叠加,而每一层的正向和逆向单词编码会拼接到一块儿。这个网络结构其实在NLP中是很经常使用的。使用这个网络结构利用大量语料作语言模型任务就能预先训练好这个网络,若是训练好这个网络后,输入一个新句子 Snew ,句子中每一个单词都能获得对应的三个Embedding:最底层是单词的Word Embedding,往上走是第一层双向LSTM中对应单词位置的Embedding,这层编码单词的句法信息更多一些;再往上走是第二层LSTM中对应单词位置的Embedding,这层编码单词的语义信息更多一些。也就是说,ELMO的预训练过程不只仅学会单词的Word Embedding,还学会了一个双层双向的LSTM网络结构,而这二者后面都有用。

 

 

上面介绍的是ELMO的第一阶段:预训练阶段。那么预训练好网络结构后,如何给下游任务使用呢?上图展现了下游任务的使用过程,好比咱们的下游任务仍然是QA问题,此时对于问句X,咱们能够先将句子X做为预训练好的ELMO网络的输入,这样句子X中每一个单词在ELMO网络中都能得到对应的三个Embedding,以后给予这三个Embedding中的每个Embedding一个权重a,这个权重能够学习得来,根据各自权重累加求和,将三个Embedding整合成一个。而后将整合后的这个Embedding做为X句在本身任务的那个网络结构中对应单词的输入,以此做为补充的新特征给下游任务使用。对于上图所示下游任务QA中的回答句子Y来讲也是如此处理。由于ELMO给下游提供的是每一个单词的特征形式,因此这一类预训练的方法被称为“Feature-based Pre-Training”。至于为什么这么作可以达到区分多义词的效果,你能够想想,其实比较容易想明白缘由。

 

 

上面这个图是TagLM采用相似ELMO的思路作命名实体识别任务的过程,其步骤基本如上述ELMO的思路,因此此处不展开说了。TagLM的论文发表在2017年的ACL会议上,做者就是AllenAI里作ELMO的那些人,因此能够将TagLM看作ELMO的一个前导工做。前几天这个PPT发出去后有人质疑说FastAI的在18年4月提出的ULMFiT才是抛弃传统Word Embedding引入新模式的开山之做,我深不觉得然。首先TagLM出现的更早并且模式基本就是ELMO的思路;另外ULMFiT使用的是三阶段模式,在通用语言模型训练以后,加入了一个领域语言模型预训练过程,并且论文重点工做在这块,方法还相对比较繁杂,这并非一个特别好的主意,由于领域语言模型的限制是它的规模每每不可能特别大,精力放在这里不太合适,放在通用语言模型上感受更合理;再者,尽管ULFMiT实验作了6个任务,可是都集中在分类问题相对比较窄,不如ELMO验证的问题领域广,我以为这就是由于第二步那个领域语言模型带来的限制。因此综合看,尽管ULFMiT也是个不错的工做,可是重要性跟ELMO比仍是差一档,固然这是我我的见解。

 

 

 

前面咱们提到静态Word Embedding没法解决多义词的问题,那么ELMO引入上下文动态调整单词的embedding后多义词问题解决了吗?解决了,并且比咱们期待的解决得还要好。上图给了个例子,对于Glove训练出的Word Embedding来讲,多义词好比play,根据它的embedding找出的最接近的其它单词大多数集中在体育领域,这很明显是由于训练数据中包含play的句子中体育领域的数量明显占优致使;而使用ELMO,根据上下文动态调整后的embedding不只可以找出对应的“演出”的相同语义的句子,并且还能够保证找出的句子中的play对应的词性也是相同的,这是超出期待之处。之因此会这样,是由于咱们上面提到过,第一层LSTM编码了不少句法信息,这在这里起到了重要做用。

 

 

ELMO通过这般操做,效果如何呢?实验效果见上图,6个NLP任务中性能都有幅度不一样的提高,最高的提高达到25%左右,并且这6个任务的覆盖范围比较广,包含句子语义关系判断,分类任务,阅读理解等多个领域,这说明其适用范围是很是广的,普适性强,这是一个很是好的优势。

 

那么站在如今这个时间节点看,ELMO有什么值得改进的缺点呢?首先,一个很是明显的缺点在特征抽取器选择方面,ELMO使用了LSTM而不是新贵Transformer,Transformer是谷歌在17年作机器翻译任务的“Attention is all you need”的论文中提出的,引发了至关大的反响,不少研究已经证实了Transformer提取特征的能力是要远强于LSTM的。若是ELMO采起Transformer做为特征提取器,那么估计Bert的反响远不如如今的这种火爆场面。另一点,ELMO采起双向拼接这种融合特征的能力可能比Bert一体化的融合特征方式弱,可是,这只是一种从道理推断产生的怀疑,目前并无具体实验说明这一点。

咱们若是把ELMO这种预训练方法和图像领域的预训练方法对比,发现二者模式看上去仍是有很大差别的。除了以ELMO为表明的这种基于特征融合的预训练方法外,NLP里还有一种典型作法,这种作法和图像领域的方式就是看上去一致的了,通常将这种方法称为“基于Fine-tuning的模式”,而GPT就是这一模式的典型开创者。

 

从Word Embedding到GPT

 

GPT是“Generative Pre-Training”的简称,从名字看其含义是指的通用的预训练,核心在通用上。GPT也采用两阶段过程,第一个阶段是利用语言模型进行预训练,第二阶段经过Fine-tuning的模式解决下游任务。上图展现了GPT的预训练过程,其实和ELMO是相似的,主要不一样在于两点:首先,特征抽取器不是用的RNN,而是用的Transformer,上面提到过它的特征抽取能力要强于RNN,这个选择很明显是很明智的;其次,GPT的预训练虽然仍然是以语言模型做为目标任务,可是采用的是单向的语言模型,所谓“单向”的含义是指:语言模型训练的任务目标是根据 W_i 单词的上下文去正确预测单词 W_i , W_i 以前的单词序列Context-before称为上文,以后的单词序列Context-after称为下文。ELMO在作语言模型预训练的时候,预测单词 W_i 同时使用了上文和下文,而GPT则只采用Context-before这个单词的上文来进行预测,而抛开了下文。这个选择如今看不是个太好的选择,缘由很简单,它没有把单词的下文融合进来,这限制了其在更多应用场景的效果,好比阅读理解这种任务,在作任务的时候是能够容许同时看到上文和下文一块儿作决策的。若是预训练时候不把单词的下文嵌入到Word Embedding中,是很吃亏的,白白丢掉了不少信息。

这里强行插入一段简单提下Transformer,尽管上面提到了,可是说的还不完整,补充两句。首先,Transformer是个叠加的“自注意力机制(Self Attention)”构成的深度网络,是目前NLP里最强的特征提取器,注意力这个机制在此被发扬光大,从任务的配角不断抢戏,直到Transformer一跃成为踢开RNN和CNN传统特征提取器,荣升头牌,大红大紫。你问了:什么是注意力机制?这里再插个广告,对注意力不了解的能够参考鄙人16年出品17年修正的下文:“深度学习中的注意力模型”,补充下相关基础知识,若是不了解注意力机制你确定会落后时代的发展。而介绍Transformer比较好的文章能够参考“The Annotated Transformer. ”这里不展开介绍。

其次,个人判断是Transformer在将来会逐渐替代掉RNN成为主流的NLP工具,RNN一直受困于其并行计算能力,这是由于它自己结构的序列性依赖致使的,尽管不少人在试图经过修正RNN结构来修正这一点,可是我不看好这种模式,由于给马车换轮胎不如把它升级到汽车,这个道理很好懂,更况且目前汽车的雏形已经出现了,干吗还要执着在换轮胎这个事情呢?是吧?再说CNN,CNN在NLP里一直没有造成主流,CNN的最大优势是易于作并行计算,因此速度快,可是在捕获NLP的序列关系尤为是长距离特征方面自然有缺陷,不是作不到而是作很差,目前也有不少改进模型,可是特别成功的很少。综合各方面状况,很明显Transformer同时具有并行性好,又适合捕获长距离特征,没有理由不在赛跑比赛中跑不过RNN和CNN。

好了,题外话结束,咱们再回到主题,接着说GPT。上面讲的是GPT如何进行第一阶段的预训练,那么假设预训练好了网络模型,后面下游任务怎么用?它有本身的个性,和ELMO的方式大有不一样。

 

 

 

上图展现了GPT在第二阶段如何使用。首先,对于不一样的下游任务来讲,原本你能够任意设计本身的网络结构,如今不行了,你要向GPT的网络结构看齐,把任务的网络结构改形成和GPT的网络结构是同样的。而后,在作下游任务的时候,利用第一步预训练好的参数初始化GPT的网络结构,这样经过预训练学到的语言学知识就被引入到你手头的任务里来了,这是个很是好的事情。再次,你能够用手头的任务去训练这个网络,对网络参数进行Fine-tuning,使得这个网络更适合解决手头的问题。就是这样。看到了么?这有没有让你想起最开始提到的图像领域如何作预训练的过程(请参考上图那句很是容易暴露年龄的歌词)?对,这跟那个模式是如出一辙的。

这里引入了一个新问题:对于NLP各类花样的不一样任务,怎么改造才能靠近GPT的网络结构呢?

 

 

 

GPT论文给了一个改造施工图如上,其实也很简单:对于分类问题,不用怎么动,加上一个起始和终结符号便可;对于句子关系判断问题,好比Entailment,两个句子中间再加个分隔符便可;对文本类似性判断问题,把两个句子顺序颠倒下作出两个输入便可,这是为了告诉模型句子顺序不重要;对于多项选择问题,则多路输入,每一路把文章和答案选项拼接做为输入便可。从上图可看出,这种改造仍是很方便的,不一样任务只须要在输入部分施工便可。

 

 

GPT的效果是很是使人惊艳的,在12个任务里,9个达到了最好的效果,有些任务性能提高很是明显。

 

 

 

那么站在如今的时间节点看,GPT有什么值得改进的地方呢?其实最主要的就是那个单向语言模型,若是改形成双向的语言模型任务估计也没有Bert太多事了。固然,即便如此GPT也是很是很是好的一个工做,跟Bert比,其做者炒做能力亟待提高。

 

Bert的诞生

 

 

咱们通过跋山涉水,终于到了目的地Bert模型了。

Bert采用和GPT彻底相同的两阶段模型,首先是语言模型预训练;其次是使用Fine-Tuning模式解决下游任务。和GPT的最主要不一样在于在预训练阶段采用了相似ELMO的双向语言模型,固然另一点是语言模型的数据规模要比GPT大。因此这里Bert的预训练过程没必要多讲了。

 

 

 

第二阶段,Fine-Tuning阶段,这个阶段的作法和GPT是同样的。固然,它也面临着下游任务网络结构改造的问题,在改造任务方面Bert和GPT有些不一样,下面简单介绍一下。

 

 

在介绍Bert如何改造下游任务以前,先大体说下NLP的几类问题,说这个是为了强调Bert的普适性有多强。一般而言,绝大部分NLP问题能够纳入上图所示的四类任务中:一类是序列标注,这是最典型的NLP任务,好比中文分词,词性标注,命名实体识别,语义角色标注等均可以纳入这一类问题,它的特色是句子中每一个单词要求模型根据上下文都要给出一个分类类别。第二类是分类任务,好比咱们常见的文本分类,情感计算等均可以纳入这一类。它的特色是无论文章有多长,整体给出一个分类类别便可。第三类任务是句子关系判断,好比Entailment,QA,语义改写,天然语言推理等任务都是这个模式,它的特色是给定两个句子,模型判断出两个句子是否具有某种语义关系;第四类是生成式任务,好比机器翻译,文本摘要,写诗造句,看图说话等都属于这一类。它的特色是输入文本内容后,须要自主生成另一段文字。

 

 

 

对于种类如此繁多并且各具特色的下游NLP任务,Bert如何改造输入输出部分使得大部分NLP任务均可以使用Bert预训练好的模型参数呢?上图给出示例,对于句子关系类任务,很简单,和GPT相似,加上一个起始和终结符号,句子之间加个分隔符便可。对于输出来讲,把第一个起始符号对应的Transformer最后一层位置上面串接一个softmax分类层便可。对于分类问题,与GPT同样,只须要增长起始和终结符号,输出部分和句子关系判断任务相似改造;对于序列标注问题,输入部分和单句分类是同样的,只须要输出部分Transformer最后一层每一个单词对应位置都进行分类便可。从这里能够看出,上面列出的NLP四大任务里面,除了生成类任务外,Bert其它都覆盖到了,并且改造起来很简单直观。尽管Bert论文没有提,可是稍微动动脑子就能够想到,其实对于机器翻译或者文本摘要,聊天机器人这种生成式任务,一样能够稍做改造便可引入Bert的预训练成果。只须要附着在S2S结构上,encoder部分是个深度Transformer结构,decoder部分也是个深度Transformer结构。根据任务选择不一样的预训练数据初始化encoder和decoder便可。这是至关直观的一种改造方法。固然,也能够更简单一点,好比直接在单个Transformer结构上加装隐层产生输出也是能够的。不论如何,从这里能够看出,NLP四大类任务均可以比较方便地改形成Bert可以接受的方式。这实际上是Bert的很是大的优势,这意味着它几乎能够作任何NLP的下游任务,具有普适性,这是很强的。

 

 

 

Bert采用这种两阶段方式解决各类NLP任务效果如何?在11个各类类型的NLP任务中达到目前最好的效果,某些任务性能有极大的提高。一个新模型好很差,效果才是王道。

 

 

 

到这里咱们能够再梳理下几个模型之间的演进关系。从上图可见,Bert其实和ELMO及GPT存在千丝万缕的关系,好比若是咱们把GPT预训练阶段换成双向语言模型,那么就获得了Bert;而若是咱们把ELMO的特征抽取器换成Transformer,那么咱们也会获得Bert。因此你能够看出:Bert最关键两点,一点是特征抽取器采用Transformer;第二点是预训练的时候采用双向语言模型。

那么新问题来了:对于Transformer来讲,怎么才能在这个结构上作双向语言模型任务呢?乍一看上去好像不太好搞。我以为吧,其实有一种很直观的思路,怎么办?看看ELMO的网络结构图,只须要把两个LSTM替换成两个Transformer,一个负责正向,一个负责反向特征提取,其实应该就能够。固然这是我本身的改造,Bert没这么作。那么Bert是怎么作的呢?咱们前面不是提过Word2Vec吗?我前面确定不是漫无目的地提到它,提它是为了在这里引出那个CBOW训练方法,所谓写做时候埋伏笔的“草蛇灰线,伏脉千里”,大概就是这个意思吧?前面提到了CBOW方法,它的核心思想是:在作语言模型任务的时候,我把要预测的单词抠掉,而后根据它的上文Context-Before和下文Context-after去预测单词。其实Bert怎么作的?Bert就是这么作的。从这里能够看到方法间的继承关系。固然Bert做者没提Word2Vec及CBOW方法,这是个人判断,Bert做者说是受到完形填空任务的启发,这也极可能,可是我以为他们要是没想到过CBOW估计是不太可能的。

从这里能够看出,在文章开始我说过Bert在模型方面其实没有太大创新,更像一个最近几年NLP重要技术的集大成者,缘由在于此,固然我不肯定你怎么看,是否定同这种见解,并且我也不关心你怎么看。其实Bert自己的效果好和普适性强才是最大的亮点。

 

 

 

那么Bert自己在模型和方法角度有什么创新呢?就是论文中指出的Masked 语言模型和Next Sentence Prediction。而Masked语言模型上面讲了,本质思想实际上是CBOW,可是细节方面有改进。

 

 

 

Masked双向语言模型向上图展现这么作:随机选择语料中15%的单词,把它抠掉,也就是用[Mask]掩码代替原始单词,而后要求模型去正确预测被抠掉的单词。可是这里有个问题:训练过程大量看到[mask]标记,可是真正后面用的时候是不会有这个标记的,这会引导模型认为输出是针对[mask]这个标记的,可是实际使用又见不到这个标记,这天然会有问题。为了不这个问题,Bert改造了一下,15%的被上天选中要执行[mask]替身这项光荣任务的单词中,只有80%真正被替换成[mask]标记,10%被狸猫换太子随机替换成另一个单词,10%状况这个单词还待在原地不作改动。这就是Masked双向语音模型的具体作法。

 

 

 

至于说“Next Sentence Prediction”,指的是作语言模型预训练的时候,分两种状况选择两个句子,一种是选择语料中真正顺序相连的两个句子;另一种是第二个句子从语料库中抛色子,随机选择一个拼到第一个句子后面。咱们要求模型除了作上述的Masked语言模型任务外,附带再作个句子关系预测,判断第二个句子是否是真的是第一个句子的后续句子。之因此这么作,是考虑到不少NLP任务是句子关系判断任务,单词预测粒度的训练到不了句子关系这个层级,增长这个任务有助于下游句子关系判断任务。因此能够看到,它的预训练是个多任务过程。这也是Bert的一个创新。

 

 

上面这个图给出了一个中文训练实例,从中能够体会下上面讲的masked语言模型和下句预测任务。训练数据就长这种样子。

 

 

顺带讲解下Bert的输入部分,也算是有些特点。它的输入部分是个线性序列,两个句子经过分隔符分割,最前面和最后增长两个标识符号。每一个单词有三个embedding:位置信息embedding,这是由于NLP中单词顺序是很重要的特征,须要在这里对位置信息进行编码;单词embedding,这个就是咱们以前一直提到的单词embedding;第三个是句子embedding,由于前面提到训练数据都是由两个句子构成的,那么每一个句子有个句子总体的embedding项对应给每一个单词。把单词对应的三个embedding叠加,就造成了Bert的输入。

 

 

至于Bert在预训练的输出部分如何组织,能够参考上图的注释。

 

 

咱们说过Bert效果特别好,那么究竟是什么因素起做用呢?如上图所示,对比试验能够证实,跟GPT相比,双向语言模型起到了最主要的做用,对于那些须要看到下文的任务来讲尤为如此。而预测下个句子来讲对总体性能来讲影响不算太大,跟具体任务关联度比较高。

 

 

最后,我讲讲我对Bert的评价和见解,我以为Bert是NLP里里程碑式的工做,对于后面NLP的研究和工业应用会产生长久的影响,这点毫无疑问。可是从上文介绍也能够看出,从模型或者方法角度看,Bert借鉴了ELMO,GPT及CBOW,主要提出了Masked 语言模型及Next Sentence Prediction,可是这里Next Sentence Prediction基本不影响大局,而Masked LM明显借鉴了CBOW的思想。因此说Bert的模型没什么大的创新,更像最近几年NLP重要进展的集大成者,这点若是你看懂了上文估计也没有太大异议,若是你有大的异议,杠精这个大帽子我随时准备戴给你。若是概括一下这些进展就是:首先是两阶段模型,第一阶段双向语言模型预训练,这里注意要用双向而不是单向,第二阶段采用具体任务Fine-tuning或者作特征集成;第二是特征抽取要用Transformer做为特征提取器而不是RNN或者CNN;第三,双向语言模型能够采起CBOW的方法去作(固然我以为这个是个细节问题,不算太关键,前两个因素比较关键)。Bert最大的亮点在于效果好及普适性强,几乎全部NLP任务均可以套用Bert这种两阶段解决思路,并且效果应该会有明显提高。能够预见的是,将来一段时间在NLP应用领域,Transformer将占据主导地位,并且这种两阶段预训练方法也会主导各类应用。

另外,咱们应该弄清楚预训练这个过程本质上是在作什么事情,本质上预训练是经过设计好一个网络结构来作语言模型任务,而后把大量甚至是无穷尽的无标注的天然语言文本利用起来,预训练任务把大量语言学知识抽取出来编码到网络结构中,当手头任务带有标注信息的数据有限时,这些先验的语言学特征固然会对手头任务有极大的特征补充做用,由于当数据有限的时候,不少语言学现象是覆盖不到的,泛化能力就弱,集成尽可能通用的语言学知识天然会增强模型的泛化能力。如何引入先验的语言学知识其实一直是NLP尤为是深度学习场景下的NLP的主要目标之一,不过一直没有太好的解决办法,而ELMO/GPT/Bert的这种两阶段模式看起来无疑是解决这个问题天然又简洁的方法,这也是这些方法的主要价值所在。

对于当前NLP的发展方向,我我的以为有两点很是重要,一个是须要更强的特征抽取器,目前看Transformer会逐渐担当大任,可是确定仍是不够强的,须要发展更强的特征抽取器;第二个就是如何优雅地引入大量无监督数据中包含的语言学知识,目前看预训练这种两阶段方法仍是颇有效的,固然后面确定还会有更好的模型出现。

完了,这就是天然语言模型预训练的发展史。

注:本文能够任意转载,转载时请标明做者和出处。

 

 

 

发布于昨天 15:00
机器学习
天然语言处理
深度学习(Deep Learning)
 

文章被如下专栏收录

深度学习前沿笔记
深度学习前沿笔记

推荐阅读

word embedding之GLOVE算法(2)

二· Glove模型 先介绍一些模型中要用到的一些变量:X_{ij} 词 j 出如今词 i 上下文中的次数X_{i}=\sum_{k}{X_{ik}} 词 i 做为其余任意词的背景词的次数P_{ij}= P(j|i) = X_{ij}/X_{i} 词 j…

word embedding之GLOVE算法(1)

GLOVE算法论文连接是http://nlp.stanford.edu/pubs/glove.pdf,该算法是2014年斯坦福发布的。最近阅读了论文,源码,而且本身工做中也用到了这个算法,在这里写一些心得体会,与你们分享。…

YJango的Word Embedding--介绍

YJango的Word Embedding--介绍

word embedding算法系列

提及word embedding你们确定先想到大名鼎鼎Word2Vec算法,的确,word2vec简单好用;并且word2vec也的确带火了一大批算法。我在这里先列一个总纲,之后有机会再逐个细写。1. Word2vec google…