Transformer模型自提出以来,已经在很多地方都取得了不错的成果,尤其是在nlp领域,它取得的成果是令人瞩目的,相比于之前的模型,transformer模型的attention机制更够更好地学习到句子当中单词与单词之间的联系,从而能够结合上下文语境来提高准确度。

更重要的是,transformer的这种attention机制是一种底层的方法,我们基于它可以构造出一些新的模型,而这些模型在nlp中往往有著出色的表现,下面介绍的BERT模型就是其中之一。

如果对Transformer模型还不熟悉的话,可以看我之前的文章:Transformer模型浅析

一、预训练过程

BERT是一种预训练语言模型,因此在介绍它之前,先简单说一下什么是nlp中的预训练过程。顾名思义,预训练就是在拿样本数据对模型进行训练之前做的训练,那么为什么要有预训练呢?其实在nlp的下游任务(比如机器翻译、阅读理解等)中,可以使用的样本数据是比较少的,因为这些任务需要的都是经过专门标注的数据,这样就使得拿这些样本数据直接训练出来的模型效果比较一般,因此就需要对模型进行预训练了。

预训练的目的就是,提前训练好这些下游任务中底层的、共性的部分模型,然后再用下游任务各自的样本数据来训练各自的模型,这样就可以极大地加快收敛速度。在这里举一个cv的例子,对于人脸识别和数字识别两种任务,显然它们有很多的区别,然而在用CNN进行训练的时候,其实比较浅的几层网路学习到的特征是很相似的,都是类似于边角线的这类基础特征(下图红色框部分),因此我们可以认为这几层网路可以共用,如果我们能够预先训练好这部分,那么模型的训练收敛速度将会大大加快。

用于人脸识别的神经网路

对于nlp的下游任务,尽管它们的最终目标各不相同,但是它们也有著共同的、也是必须首先要做的东西,那就是要让模型理解文档中的单词和句子,具体说就是将文本中的无法直接计算的单词转变为可以计算的向量或者矩阵等形式,并且这些数字化的向量要能够比较好地反映出对应单词在句子中的含义,这就nlp中预训练的目的。在nlp中采用的是语言模型来做预训练,从最初的word embedding到ELMO、再到GPT,以及现在的BERT,其实做的都是上面说的这件事,只不过效果变得越来越好。

二、语言模型和word embedding

我们知道,一句话不是由一些单词简单地组合就能得到的,它必须要符合人类的语言习惯,而语言模型就是用来判断一句话是不是符合人类的习惯,具体地说就是给定句子中在某一单词前面的单词(也可以是上下文),然后预测该单词出现的概率。如下图所示,对于一句话来说,如果把每一个位置的条件概率都相乘,那么概率越大越能说明它更像一句人说的话。如果我们想训练一个语言模型,只需要选择一个单词并通过它的上下文来预测该单词的概率,然后最大化这个概率就行了。

而语言模型除了能看句子是不是更符合人类习惯之外,是否还有别的作用呢?当然有,那就上面提到的word embedding,这其实是一个副产品,在模型的训练过程中,首先需要将句子中的前面的单词都转化为对应的向量,然后再通过隐层和softmax来预测后面接的单词概率,如果模型能够预测得很好的话,那么就可以认为第一步得到的向量能够很好地反应出对应单词的含义。这样就可以认为得到了一个单词表,每一个单词都可以在表中找到对应的向量,而这个过程就是word embedding,在这之后就可以让word embedding接到具体的下游任务中,这样通过语言模型就实现了对于nlp任务的预训练。

语言模型

可以看出,语言模型的训练不需要预先对数据进行标注,因此可以使用的语料库是相当庞大的,而这也是采用语言模型来做nlp预训练的原因,大量的训练数据使得word embedding的效果更佳,从而使得预训练后的下游任务模型更优。

然而在实际实验中,采用word embedding的预训练技术加到下游任务后,却并没有取得很大的提升,其主要原因是:对于word embedding,一个单词唯一对应一个向量,但是有些单词在不同的句子中往往对应著不同的含义,对于这类多义词,是无法只用一个向量来进行表示的,一个向量只能做到「四不像」——平均该单词的每一种含义,这样显然会对之后的模型学习造成影响,因此需要对预训练的语言模型进行改进,而BERT就是较好地解决了这个问题

三、从word embedding到BRET

BERT的全称是Bidirectional Encoder Representations from Transformer,也就是基于Transformer的双向编码器表征。顾名思义,BERT采用的是Transformer,并且在处理一个单词的时候,还能够考虑到该词前面的和后面的单词,得到它在上下文中的含义。我们知道,Transformer的attention机制在对语境中的单词进行特征抽取时有著很好的效果,而且从直觉上看,考虑上下文的双向编码要比只考虑上文(或下文)的单向效果更好,下面介绍BERT模型的具体内容。

1.输入表示

如下图所示,BERT的输入是token、segmentation和position embeddings的叠加,也就说每个单词的embedding是三个embedding的叠加。对于token embeddings使用WordPiece嵌入,也就是通过上面单词表来实现的;而positional embeddings用来表示句子中单词的位置信息;segement embeddings则是对于句子整体的,不同的句子有不同的项,它用来实现句子级别的任务。

2.遮蔽语言模型

前面提到了BERT是一种双向语言模型,它需要同时考虑单词的上文和下文,为了实现这一目的,模型采用了一种简单的方法:随机屏蔽(masking)部分输入token,然后训练模型去正确预测那些被屏蔽的token,用到的模型结构和Transformer基本一样。

具体来说,模型会随机选择语料中15%的单词,然后其中的80%会用[Mask]掩码代替原始单词,其中的10%会被随机换为另一个单词,剩下10%保持原单词不变,然后要求模型去正确预测被选中的单词。做这些处理的原因是,[Mask]只在训练中才会出现,如果选中单词都变为了[Mask],这会导致训练出来的模型可能会针对于[Mask],这与实际不符,所以才会有一些概率将[Mask]随机替换,而这个概率大小为10%×15%=1.5%,基本不会损害模型的语言理解能力,而模型为了预测正确,就需要保持每个输入token的分散式上下文表示,从而实现了对上下文进行特征提取的目的。

3.下一句预测

前面的遮蔽语言模型是针对於单词量级的训练,而nlp中有许多任务是在句子量级上的,这就需要语言模型还要理解句子之间的关系,这有助于下游句子关系判断任务,而BERT中的下一句预测(Next Sentence Prediction)就是为了这一目的。它的原理也很简单,就是预训练一个二值化的下一句预测任务,具体来说,选择句子A和B作为训练样本:A的下一句有50%的可能是B,另外50%的可能B是随机取自语料库的,模型需要正确预测B是不是A的下一句。

4.微调

通过上面的方法,我们就实现了BERT模型的预训练,对于特定下游任务的模型,可以通将BERT与一个额外的输出层结合而形成,这样需要重新学习的参数量就会比较小,如下图所示,只需要按BERT模型要求的格式输入训练数据,就可以完成不同的下游任务。

总结

从整体上看,BERT模型采用了目前流行的特征提取器Transformer,同时还实现了双向语言模型,采众家之长使得它具有更好的性能——在11项NLP任务中都刷新了性能表现记录。不过BERT也还有可以改进的地方,比如说BERT采用的是原始的Transformer,Transformer固然强大,不过现在已经也有了一些更强的改进版;另外就是BERT的Mask机制,虽然通过它可以实现双向语言模型的训练,但是这样会导致预训练和在下游任务上进行微调时的不一致(后者语料中没有[Mask]掩码),而如果能够在这些方面做出改进,那么相信模型的性能会有进一步的提高。

参考资料

[1] BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding

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


推荐阅读:
相关文章