赞
踩
其实Bert并没有重大的理论或者模型创新,创新并不算大。主要原因是效果太好了,刷新了很多NLP任务的最好性能,有些任务还被刷爆了。另外一点是Bert具备广泛的通用性,绝大部分的NLP任务都可以采用类似的两阶段模式直接去提升效果。
要将NLP中的预训练,首先要从图像领域的预训练说起。预训练过程是图像或者视频领域的一种比较常规的做法,这种做法很有效,能明显促进应用的效果。
1.图像领域的预训练过程
设计好网络结构之后,对于图像来说一般是CNN的多层叠加网络结构,可以采用某个训练集合对网络进行训练,在A任务上学习网络参数,存起来备用。当面临第二个任务C,采取相同的网络结构。比较浅的几层CNN结构中的参数可以加载任务A学习好的参数啦初始化,其它高层的参数仍然随机初始化。
此时有两种做法:
1.“Frozen” :前层加载的参数在训练任务C过程中保持不变。
2.“Fine-Tuning”:将参数进行调整使得更适用于当前的C任务。
1.1 预训练的好处
1.2 为什么这种预训练可行?
对于层级的CNN结构来说,不同层级的神经元学习到了不同类型的图像特征,由底向上特征形成层级结构。如上图所示,如果我们手头是个人脸识别任务,训练好网络后,把每层神经元学习到的特征可视化肉眼看一看每层学到了啥特征,你会看到最底层的神经元学到的是线段等特征,图示的第二个隐层学到的是人脸五官的轮廓,第三层学到的是人脸的轮廓,通过三步形成了特征的层级结。不论什么领域的图像都会具备比如边角线弧线等底层的基础特征,所以越是底层的网络参数抽取出的特征与具体任务越无关,越具备任务的通用性,而越往上抽取出的特征越与手头任务相关。这就是为什么一般用底层的参数初始化新任务网络参数的原因。
word-embedding其实就是NLP中的早期预训练技术。在说word embedding之前,粗略的说下语言模型,一般NLP里面做预训练一般的选择是用语言模型任务来做。
该模型就是“神经网络语言模型”
学习任务是输入某个句子中的单词
W
t
=
"
B
e
r
t
"
W_t="Bert"
Wt="Bert"前面的
t
−
1
t-1
t−1个单词,要求网络正确预测单词Bert。
前面任意单词
W
i
W_i
Wi 用Onehot编码(比如:0001000)作为原始单词输入,之后乘以矩阵
Q
Q
Q后获得向量
C
(
W
i
)
C(W_i )
C(Wi) ,每个单词的
C
(
W
i
)
C(W_i )
C(Wi) 拼接,上接隐层,然后接softmax去预测后面应该后续接哪个单词。这个
C
(
W
i
)
C(W_i )
C(Wi)是什么?这其实就是单词对应的Word Embedding值,那个矩阵
Q
Q
Q包含V行,V代表词典大小,每一行内容代表对应单词的Word embedding值。只不过
Q
Q
Q的内容也是网络参数,需要学习获得,训练刚开始用随机值初始化矩阵
Q
Q
Q,当这个网络训练好之后,矩阵
Q
Q
Q的内容被正确赋值,每一行代表一个单词对应的Word embedding值。所以你看,通过这个网络学习语言模型任务,这个网络不仅自己能够根据上文预测后接单词是什么,同时获得一个副产品,就是那个矩阵
Q
Q
Q,这就是单词的Word Embedding是被如何学会的。
2013年最火的语言模型做word embedding的工具是word2vec,后来又出了Glove。Word2Vec和NNLM不一样,NNLM的主要任务是要学习一个解决语言模型任务的网络结构,语言模型就是要看到上文预测下文,而word embedding只是无心插柳的一个副产品。但是Word2Vec目标不一样,它单纯就是要word embedding的,这是主产品。使用Word2Vec或者Glove,通过做语言模型任务,就可以获得每个单词的Word Embedding,那么这种方法的效果如何呢?上图给了网上找的几个例子,可以看出有些例子效果还是很不错的,一个单词表达成Word Embedding后,很容易找出语义相近的其它词汇。
是多义词问题。比如说多义词Bank,有两个常用含义,但是word embedding在对bank这个单词进行编码的时候,无法区分这两个含义。因为尽管上下文环境出现的单词不同,但是不论什么上下文的句子经过word2vec,都是预测相同的单词bank,而同一个单词占的是同一行的参数空间,这会导致两种不同的上下文信息都会编码到相同的word embedding。所以word2vec无法区分多义词的不同语义,这是一个比较严重的问题。
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表示,这样通过调整后的word wembedding更能表达在这个上下文中的具体含义,自然也就解决了多义词的问题。
网络结构采用双层双向的LSTM。目前语言模型训练的任务目标是根据单词
W
i
W_i
Wi 的上下文去正确预测单词
W
i
W_i
Wi,
W
i
W_i
Wi 之前的单词序列Context-before称为上文,之后的单词序列Context-after称为下文。图中左端的前向双层LSTM代表正方向编码器,输入的是从左到右顺序的除了预测单词外
W
i
W_i
Wi 的上文Context-before;右端的逆向双层LSTM代表反方向编码器,输入的是从右到左的逆序的句子下文Context-after;每个编码器的深度都是两层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”。至于为何这么做能够达到区分多义词的效果?
ELMO引入上下文动态调整单词的embedding后多义词问题解决了吗?解决了,而且比我们期待的解决得还要好。上图给了个例子,对于Glove训练出的Word Embedding来说,多义词比如play,根据它的embedding找出的最接近的其它单词大多数集中在体育领域,这很明显是因为训练数据中包含play的句子中体育领域的数量明显占优导致;而使用ELMO,根据上下文动态调整后的embedding不仅能够找出对应的“演出”的相同语义的句子,而且还可以保证找出的句子中的play对应的词性也是相同的,这是超出期待之处。之所以会这样,是因为我们上面提到过,第一层LSTM编码了很多句法信息,这在这里起到了重要作用。
ELMO经过这般操作,在6个NLP任务中性能都有幅度不同的提升,最高的提升达到25%左右,而且这6个任务的覆盖范围比较广,包含句子语义关系判断,分类任务,阅读理解等多个领域,这说明其适用范围是非常广的,普适性强,这是一个非常好的优点。
与Bert的对比:
1.LSTM抽取特征能力远弱于Transformer
2.拼接方式双向融合特征能力偏弱
从当前结点看,ELMO使用的是LSTM而不是Transformer,Transformer是谷歌在17年做机器翻译任务的“Attention is all you need”的论文中提出的,引起了相当大的反响,很多研究已经证明了Transformer提取特征的能力是要远强于LSTM的。另外一点,ELMO采取双向拼接这种融合特征的能力可能比Bert一体化的融合特征方式弱。
如果把ELMO这种预训练方法和图像领域的预训练方法对比,发现两者模式看上去还是有很大差异的。除了以ELMO为代表的这种基于特征融合的预训练方法外,NLP里还有一种典型做法,这种做法和图像领域的方式就是看上去一致的了,一般将这种方法称为“基于Fine-tuning的模式”,而GPT就是这一模式的典型开创者。
GPT:“Generative Pre-Training”,意为生成式的预训练。GPT也采用两阶段过程。第一阶段是利用语言模型进行预训练,第二阶段通过Fine-tuning的模式解决下游任务。上图为GPT的预训练过程,与EMLO的不同主要为两点:1.特征抽取器用的是Transformer,而不是RNN,它的特征抽取能力有强于RNN。2.GPT的预训练虽然仍然是以语言模型作为目标任务,但是采用的是单向的语言模型,只采用这个单词的Context-before(上文)来进行预测,而抛开了下文。而EMLO在做语言模型预训练的时候,预测单词
W
i
W_i
Wi同时使用了上文和下文(Context-after)。现在看到这不是一个太好的选择,因为它没有把单词的下文融合进来,这限制了其在更多应用场景的效果,比如阅读理解,需要同时看到上文和下文一起做决策。如果预训练时候不把单词的下文嵌入到word embedding中,会白白丢失掉很多信息。
Transformer是一个叠加的“自注意力机制”构成的深度网络,是目前NLP里最强的特征提取器,注意力这个机制在此被发扬光大,从任务的配角不断抢戏,直到Transformer一跃成为踢开RNN和CNN传统特征提取器。
其次,我的判断是Transformer在未来会逐渐替代掉RNN成为主流的NLP工具,RNN一直受困于其并行计算能力,这是因为它本身结构的序列性依赖导致的,尽管很多人在试图通过修正RNN结构来修正这一点,但是我不看好这种模式,因为给马车换轮胎不如把它升级到汽车,这个道理很好懂,更何况目前汽车的雏形已经出现了,干嘛还要执着在换轮胎这个事情呢?是吧?再说CNN,CNN在NLP里一直没有形成主流,CNN的最大优点是易于做并行计算,所以速度快,但是在捕获NLP的序列关系尤其是长距离特征方面天然有缺陷,不是做不到而是做不好,目前也有很多改进模型,但是特别成功的不多。综合各方面情况,很明显Transformer同时具备并行性好,又适合捕获长距离特征,没有理由不在赛跑比赛中跑不过RNN和CNN。
那么接下来的问题就是对于NLP各种不同任务如果改造才能够靠近GPT的网络结构?
GPT论文给了一个改造施工图如上,其实也很简单:对于分类问题,不用怎么动,加上一个起始和终结符号即可;对于句子关系判断问题,比如Entailment,两个句子中间再加个分隔符即可;对文本相似性判断问题,把两个句子顺序颠倒下做出两个输入即可,这是为了告诉模型句子顺序不重要;对于多项选择问题,则多路输入,每一路把文章和答案选项拼接作为输入即可。从上图可看出,这种改造还是很方便的,不同任务只需要在输入部分施工即可。
GPT的效果是非常令人惊艳的,在12个任务里,9个达到了最好的效果,有些任务性能提升非常明显。
Bert采用与GPT完全相同的两阶段模型,首先是语言模型预训练,其次是使用Fine-Tuning模式解决下游任务。和GPT的最主要的不同在于在预训练阶段采用了类似ELMO的双向语言模型,而且语言模型的数据规模要比GPT大。
第二阶段,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方法,它的核心思想是:在做语言模型任务的时候,我把要预测的单词抠掉,然后根据它的上文Context-Before和下文Context-after去预测单词。其实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的一个创新。
顺带讲解下Bert的输入部分,也算是有些特色。它的输入部分是个线性序列,两个句子通过分隔符分割,最前面和最后增加两个标识符号。每个单词有三个embedding:位置信息embedding,这是因为NLP中单词顺序是很重要的特征,需要在这里对位置信息进行编码;单词embedding,这个就是我们之前一直提到的单词embedding;第三个是句子embedding,因为前面提到训练数据都是由两个句子构成的,那么每个句子有个句子整体的embedding项对应给每个单词。把单词对应的三个embedding叠加,就形成了Bert的输入。
我们说过Bert效果特别好,那么到底是什么因素起作用呢?如上图所示,对比试验可以证明,跟GPT相比,双向语言模型起到了最主要的作用,对于那些需要看到下文的任务来说尤其如此。而预测下个句子来说对整体性能来说影响不算太大,跟具体任务关联度比较高。
Bert是NLP里里程碑式的工作,对于后面NLP的研究和工业应用会产生长久的影响,这点毫无疑问。但是从上文介绍也可以看出,从模型或者方法角度看,Bert借鉴了ELMO,GPT及CBOW,主要提出了Masked 语言模型及Next Sentence Prediction,但是这里Next Sentence Prediction基本不影响大局,而Masked LM明显借鉴了CBOW的思想。所以说Bert的模型没什么大的创新,更像最近几年NLP重要进展的集大成者。如果归纳一下这些进展就是:
Bert最大的亮点在于效果好及普适性强,几乎所有NLP任务都可以套用Bert这种两阶段解决思路,而且效果应该会有明显提升。可以预见的是,未来一段时间在NLP应用领域,Transformer将占据主导地位,而且这种两阶段预训练方法也会主导各种应用。
本质上预训练是通过设计好一个网络结构来做语言模型任务,然后把大量甚至是无穷尽的无标注的自然语言文本利用起来,预训练任务把大量语言学知识抽取出来编码到网络结构中,当手头任务带有标注信息的数据有限时,这些先验的语言学特征当然会对手头任务有极大的特征补充作用,因为当数据有限的时候,很多语言学现象是覆盖不到的,泛化能力就弱,集成尽量通用的语言学知识自然会加强模型的泛化能力。如何引入先验的语言学知识其实一直是NLP尤其是深度学习场景下的NLP的主要目标之一,不过一直没有太好的解决办法,而ELMO/GPT/Bert的这种两阶段模式看起来无疑是解决这个问题自然又简洁的方法,这也是这些方法的主要价值所在。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。