在自然语言处理(NLP)领域中,使用语言模型预训练方法在多项NLP任务上都获得了很好的提升,也十分吸引大家的眼球。就此,我将最近看的一些相关论文和博文进行总结,选取了几个代表性模型(包括ELMo ,OpenAI GPT 和BERT)和大家一起学习分享。
一个对文本有效的抽象方法可以减轻NLP对监督学习的依赖。大多数深度学习方法需要大量的人工标注信息,这限制了在很多领域的应用。在这些情况下,利用来未标记数据的语言信息的模型来产生更多的注释,这可能既耗时又昂贵。此外,即使在可获得相当大的监督的情况下,以无人监督的方式学习良好的表示也可以提供显著的性能提升。到目前为止,最引人注目的证据是广泛使用预训练词嵌入来提高一系列NLP任务的性能。
1.1 ELMo的优势
(1)ELMo能够学习到词汇用法的复杂性,比如语法、语义。
(2)ELMo能够学习不同上下文情况下的词汇多义性。
相比word2vec:
ELMo的假设前提一个词的词向量不应该是固定的,所以在一词多意方面ELMo的效果一定比word2vec要好。
word2vec的学习词向量的过程是通过中心词的上下窗口去学习,学习的范围太小了,而ELMo在学习语言模型的时候是从整个语料库去学习的,而后再通过语言模型生成的词向量就相当于基于整个语料库学习的词向量,更加准确代表一个词的意思。
ELMo还有一个优势,就是它建立语言模型的时候,可以运用非任务的超大语料库去学习,一旦学习好了,可以平行的运用到相似问题。
1.2 ELMo的模型简介
2018年3月份出现了ELMo。在之前2013年的word2vec及2014年的GloVe的工作中,每个词对应一个vector,对于多义词无能为力。ELMo的工作对于此,提出了一个较好的解决方案。不同于以往的一个词对应一个向量,是固定的。在ELMo世界里,预训练好的模型不再只是向量对应关系,而是一个训练好的模型。使用时,将一句话或一段话输入模型,模型会根据上下文来推断每个词对应的词向量。这样做之后明显的好处之一就是对于多义词,可以结合前后语境对多义词进行理解。比如apple,可以根据前后文语境理解为公司或水果。
说到词向量,我们一定会联想到word2vec,因为在它提出的词向量概念给NLP的发展带来了巨大的提升。而ELMo的主要做法是先训练一个完整的语言模型,再用这个语言模型去处理需要训练的文本,生成相应的词向量,所以在文中一直强调ELMo的模型对同一个字在不同句子中能生成不同的词向量。
原理:
他们使用的是一个双向的LSTM语言模型,由一个前向和一个后向语言模型构成,目标函数就是取这两个方向语言模型的最大似然。
上图中的结构使用字符级卷积神经网络(convolutional neural network, CNN)来将文本中的词转换成原始词向量(raw word vector)
①将这些原始词向量输入双向语言模型中第一层
②前向迭代中包含了该词以及该词之前的一些词汇或语境的信息
③后向迭代中包含了该词之后的信息
④这两种迭代的信息组成了中间词向量(intermediate word vector),这些中间词向量被输入到模型的下一层
⑤最终表示(ELMo)就是原始词向量和两个中间词向量的加权和
因为双向语言模型的输入度量是字符而不是词汇,该模型能捕捉词的内部结构信息。比如beauty和beautiful,即使不了解这两个词的上下文,双向语言模型也能够识别出它们的一定程度上的相关性。
所谓ELMo不过是一些网络层的组合。都有哪些网络层呢?对于每个单词(token)tk,对于L层的双向lstm语言模型,一共有2L+1个表征(representations),如下所示:
ELMo 的方法不局限于sequence labeling, 而是作为一个一般性的词向量表示方法; 其次, ELMo 不仅仅使用了neural language model 的最后一层的输出, 而是对所有层的输出做了加权平均来构造最后的向量 (如下所示).
其中s 是由softmax 算出来的,可以看成是对特定任务学习到的三个词向量的权重进行的softmax归一化, 每一个特定任务的归一化因子是相同的。gamma 是一个需要学习的变量,缩放因子,在具体的任务模型中学习到,调整的是elmo学习到的词向量占特定任务中词向量的权重。 加不加这个变量对performance 的影响是比较大的。
以上两个参数在elmo模型训练好之后还需要在下游模型进行训练,相当于在下游模型中增加了两个参数。
在实验中还发现不同层的biLM输出的token表示对于不同任务效果不同。
ELMo采用典型的两阶段过程,第一个阶段是利用语言模型进行预训练,第二个阶段是在做下游任务时,从预训练网络中提取对应单词的网络各层的Word Embedding作为新特征补充到下游任务中。
将emlo用于下游的任务,论文中提到了三种方式:
(1)中间层和输入词向量x进行concat
(2)中间层和最后一层的隐藏状态concat
(3)同时使用(1)和(2)
缺点:不适合特定任务
2.1 GPT基本原理
GPT提出一种半监督的方式来处理语言理解的任务。使用非监督的预训练和监督方式的微调。我们的目标是学习一个通用的语言模型,可以经过很小的调整就应用在各种任务中。
GPT模型图:
这个模型的设置不需要目标任务和非标注的数据集在同一个领域。模型的构建可以看成以下两个过程。
1.对大量非标记数据集使用语言模型学习一个深度模型(非监督预训练)
2.随后,使用相应的监督目标将这些参数调整到目标任务(监督微调fine-tuning)
第一步,输入:输入词向量和每个词的位置编码。
第二步,Masked Attention:
在这里我们先介绍一下:self-attention
首先,每个词都要通过三个矩阵Wq, Wk, Wv进行一次线性变化,一分为三,生成每个词自己的query, key, vector三个向量。以一个词为中心进行Self Attention时,都是用这个词的key向量与每个词的query向量做点积,再通过Softmax归一化出权重。然后通过这些权重算出所有词的vector的加权和,作为这个词的输出。归一化之前需要通过除以向量的维度dk来进行标准化,所以最终Self Attention用矩阵变换的方式可以表示为
最终每个Self Attention接受n个词向量的输入,输出n个加权向量。
Masked Attention
从上图中,我们发现先经过一个Masked Attention层。那么Masked的与普通版本的Attention有什么区别呢?
在transformer中,Encoder因为要编码整个句子,所以每个词都需要考虑上下文的关系。所以每个词在计算的过程中都是可以看到句子中所有的词的。但是Decoder与Seq2Seq中的解码器类似,每个词都只能看到前面词的状态,所以是一个单向的Self-Attention结构。
Masked Attention的实现也非常简单,只要在普通的Self Attention的Softmax步骤之前,与按位乘上一个下三角矩阵M就好了
第三步:残差网络:残差网络,将一层的输入与其标准化后的输出进行相加即可。Transformer中每一个()Attention层与FFN层后面都会连一个Add & Norm层。下图展示的是encoder模块中的残差网络,在我们GPT中的残差网络原理是一样的。
第四步:神经网络
第五步:残差网络
第六步:预测与下游任务
2.1.1非监督预训练
文章中使用的是多层Transformer的decoder块的语言模型。这个多层的结构应用multi-headed self-attention在处理输入的文本加上位置信息的前馈网络,输出是词的概率分布。训练的过程其实非常的简单,就是将句子n个词的词向量(第一个为<SOS>)加上Positional Encoding后输入到前面提到的模型中,n个输出分别预测该位置的下一个词(<SOS>预测句子中的第一个词,最后一个词的预测结果不用于语言模型的训练,因为是一个结束符)。
2.1.2监督微调fine-tuning
我们增加了语言模型去辅助微调,提高了监督模型的结果。为避免Fine-Tuning使得模型陷入过拟合,文中还提到了辅助训练目标的方法,类似于一个多任务模型或者半监督学习。具体方法就是在使用最后一个词的预测结果进行监督学习的同时,前面的词继续上一步的无监督训练,使得最终的损失函数成为:
模型结构如下:
1) Classification:对于分类问题,不需要做什么修改
2) Entailment:对于推理问题,可以将先验与假设使用一个分隔符分开
3) Similarity:对于相似度问题,由于模型是单向的,但相似度与顺序无关。所以需要将两个句子顺序颠倒后两次输入的结果相加来做最后的推测
4)Multiple Choice:对于问答问题,则是将上下文、问题放在一起与答案分隔开,然后进行预测。
适用场景:分类、推理、问答、相似度等应用的场景。
3.1.bert简介
Bert是谷歌于2018年发布的NLP领域的预训练模型,BERT等经过预处理的语言模型在问答、命名实体识别、自然语言推理、文本分类等自然语言处理任务中发挥着重要作用。bert模型是使用双向Transformer模型的EncoderLayer进行特征提取(bert中没有Decoder模块)。前面一章我们介绍了Transformer的工作原理,这里就不加赘述啦。
在bert中的Encoder block的结构如下图:
BERT模型如下图中左边第一个所示,它与OpenAI GPT的区别就在于采用了Transformer Encoder,也就是每个时刻的Attention计算都能够得到全部时刻的输入,而OpenAI GPT采用了Transformer Decoder,每个时刻的Attention计算只能依赖于该时刻前的所有时刻的输入,因为OpenAI GPT是采用了单向语言模型。
从图中可以看出BERT、GPT和ELMO三个模型的区别:
BERT VS GPT :BERT 模型使用多层双向Transformer作为特征提取器,同时提取上下文信息,GPT模型使用多层单向Transformer作为特征提取器,用于提取上文信息 。相较于GPT,BERT 多使用了下文信息 ;
BERT VS ELMO:BERT 模型使用多层双向Transformer作为特征提取器,同时提取 上下文信息,ELMO模型使用两对双层双向LSTM分别提取上文信息和下文信息 ,然后将提取的信息进行拼接后使用。相较于ELMO,BERT使用了更强大的Transformer作为特征提取器,且BERT是同时提取上下文信息,相较于ELMO分别提取上文信息和下文信息,更加的“浑然天成”。
3.2 Bert模型的构建
其实bert也是由两个阶段构成:
1. pre-train:用大量的无监督文本通过自监督训练的方式进行训练,bert是一个多任务模型,它的任务就是由两个自监督任务组成,即MLM和NSP。
2. fine-tune阶段:使用预训练的模型,在特定的任务中进行微调,得到用于解决该任务的定制模型。
第一部分:输入表示
如上图所示,BERT模型有两个特殊的token:CLS(用于分类任务)、 SEP(用于断句),以及三个embedding:
(1)token embedding:输入的文本经过tokenization之后,将 CLS插入tokenization结果的开头, SEP 插入到tokenization结果的结尾。然后进行 token embedding look up 。shape为:[seq_length, embedding_dims]’。流程如下图所示:
(2)segment embedding:在NSP任务中,用于区分第一句和第二句。segment embedding中只有0和1两个值,第一句所有的token(包括 cls 和紧随第一句的sep)的segment embedding的值为0,第二句所有的token(包括紧随第二句的sep)的segment embdding的值为1。shape为:[seq_length, embedding_dims]。流程如下图所示:
(3)position embedding:因Transformer-encoderlayer无法捕获文本的位置信息,而文本的位置信息又非常重要(“你欠我500万”和“我欠你500万”的感觉肯定不一样),因此需要额外把位置信息输入到模型中。 BERT的位置信息是通过 sin函数和cos函数算出来的,shape为:[seq_length, embedding_dims]。该部分参数在训练时不参与更新。
备注:BERT的输入为:token_embedding + segment_embedding + position_embedding。
3.2.1预训练
下面我们开始讲讲预训练部分
预训练任务1:
遮掩语言模型(Masked Language Modeling)。标准的语言模型(LM)是从左到右或者从右到左进行训练,因为双向的训练会让每个词都可以通过多层的上下文看到他自己。故BERT模型为了多层双向进行训练,就简单的使用了随机遮盖住一定比例的输入标记,然后仅仅预测这些遮住的输入标记。我们把这种方式称为"masked LM"(MLM)。在这种情况下,被遮盖的标记对应的最终的隐藏向量与其他标准语言模型所得的最终隐藏向量一样被进行softmax到词汇表上。在我们所有的实验中,我们在每一个序列中随机的遮盖了15%的WordPiece标记,并且我们只预测被遮盖的词语,而不是重构整个输入。
虽然这允许我们做双向的与训练模型,但是这种方法仍然有两个弊端。第一个是这种方法会让预训练和微调不能相互匹配,因为[MASK]标记在微调中是不存在的。为了减轻这种弊端,我们并不总是把15%随机产生的tokens都用[MASK]表示,而是,比如,在句子"my dog is hairy"中选择"hairy",然后通过以下的方式产生标记:
* 并不总是用[MASK]替换选择的词,数据通过如下方式产生:
* 80%的情况下:把选择的词替换成[MASK],比如:"my dog is hairy" → "my dog is [MASK]"
* 10%的情况下替换选中的词为随机词,比如:"my dog is hairy" → "my dog is apple"
* 10% 的情况下保持原词不变,比如:"my dog is hairy" → "my dog is hairy"。
这么做的原因是如果句子中的某个token100%都会被mask掉,那么在fine-tuning的时候模型就会有一些没有见过的单词。加入随机token的原因是因为Transformer要保持对每个输入token的分布式表征,否则模型就会记住这个[mask]是token ‘hairy’。至于单词带来的负面影响,因为一个单词被随机替换掉的概率只有15%*10% =1.5%,这个负面影响其实是可以忽略不计的。
第二个弊端是使用一个MLM意味着每个batch中只有15%的标记会被预测,所以在预训练的时候收敛需要更多步。在5.3中我们会阐述MLM的收敛速度比从左至右的模型(预测每一个标记)慢,但是和MLM带来的巨大提升相比,这么做是值得的。
预训练任务二:
Next Sentence Prediction(NSP)的任务是判断句子B是否是句子A的下文。如果是的话输出‘IsNext’,否则输出‘NotNext’。训练数据的生成方式是从平行语料中随机抽取的连续两句话,其中50%保留抽取的两句话,它们符合IsNext关系,另外50%的第二句话是随机从预料中提取的,它们的关系是NotNext的。这个关系保存在[CLS]符号中。
我们要求模型除了做上述的Masked语言模型任务外,附带再做个句子关系预测,判断第二个句子是不是真的是第一个句子的后续句子。之所以这么做,是考虑到很多NLP任务是句子关系判断任务时,单词预测粒度的训练到不了句子关系这个层级,故增加这个任务有助于下游句子关系判断任务。所以可以看到,bert的预训练是个多任务过程。这也是Bert的一个创新。其实这个下一句的预测就变成了二分类问题了,如下:
Input: the man went to the store [SEP] he bought a gallon of milk
Label: IsNext
Input: the man went to the store [SEP] penguins are flightless birds
Label: NotNext
Bert预训练所使用的语料是:BooksCorpus(800M words)和EnglishWikipedia(2500M words)加在一起使用。对于维基的数据我们仅仅提取了文章部分,忽略了列表,表格和头部信息。
3.2.2 fine-tuning
微调的主要任务可以分为下面几个部分:
(a)基于句子对的分类任务:
MNLI:给定一个前提 (Premise) ,根据这个前提去推断假设 (Hypothesis) 与前提的关系。该任务的关系分为三种,蕴含关系 (Entailment)、矛盾关系 (Contradiction) 以及中立关系 (Neutral)。所以这个问题本质上是一个分类问题,我们需要做的是去发掘前提和假设这两个句子对之间的交互信息。
QQP:基于Quora,判断 Quora 上的两个问题句是否表示的是一样的意思。
QNLI:用于判断文本是否包含问题的答案,类似于我们做阅读理解定位问题所在的段落。
STS-B:预测两个句子的相似性,包括5个级别。
MRPC:也是判断两个句子是否是等价的。
RTE:类似于MNLI,但是只是对蕴含关系的二分类判断,而且数据集更小。
SWAG:从四个句子中选择最可能为前句下文的那个。
(b)基于单个句子的分类任务
SST-2:电影评价的情感分析。
CoLA:句子语义判断,是否是可接受的(Acceptable)。
对于GLUE数据集的分类任务(MNLI,QQP,QNLI,SST-B,MRPC,RTE,SST-2,CoLA),BERT的微调方法是根据[CLS]标志生成一组特征向量,并通过一层全连接进行微调。损失函数根据任务类型自行设计,例如多分类的softmax或者二分类的sigmoid。
SWAG的微调方法与GLUE数据集类似,只不过其输出是四个可能选项的softmax:
(c)问答任务
SQuAD v1.1:给定一个句子(通常是一个问题)和一段描述文本,输出这个问题的答案,类似于做阅读理解的简答题。如图(c)表示的,SQuAD的输入是问题和描述文本的句子对。输出是特征向量,通过在描述文本上接一层激活函数为softmax的全连接来获得输出文本的条件概率,全连接的输出节点个数是语料中Token的个数。
(d)命名实体识别
CoNLL-2003 NER:判断一个句子中的单词是不是Person,Organization,Location,Miscellaneous或者other(无命名实体)。微调CoNLL-2003 NER时将整个句子作为输入,在每个时间片输出一个概率,并通过softmax得到这个Token的实体类别。
BERT的缺点:
BERT的预训练任务MLM使得能够借助上下文对序列进行编码,但同时也使得其预训练过程与中的数据与微调的数据不匹配,难以适应生成式任务
另外,BERT没有考虑预测[MASK]之间的相关性,是对语言模型联合概率的有偏估计
由于最大输入长度的限制,适合句子和段落级别的任务,不适用于文档级别的任务(如长文本分类);
适合处理自然语义理解类任务(NLU),而不适合自然语言生成类任务(NLG)
参考文献
[1] https://blog.csdn.net/cpluss/article/details/81451264
[2] https://blog.csdn.net/s1434088958/article/details/93360013
[3] https://blog.csdn.net/triplemeng/article/details/82380202
[4] https://blog.csdn.net/nht1996/article/details/93777237
[5] https://blog.csdn.net/zyq11223/article/details/93595905
[6] https://zhuanlan.zhihu.com/p/69290203
[7] http://www.sohu.com/a/332894905_680233
[8] https://zhuanlan.zhihu.com/p/46833276
[9] https://zhuanlan.zhihu.com/p/48612853
[10] https://www.jianshu.com/p/2045dbe7ff9d
[11] https://www.tuicool.com/articles/iaANfqV
(部分文字、图片来自网络,如涉及侵权,请及时与我们联系,我们会在第一时间删除或处理侵权内容。电话:4006770986 邮箱:zhangming [at]eefung.com 负责人:张明)