还在用RNN做NLP吗?NLP开创了新纪元!快来学习最流行的BERTTransformer模型吧。谷歌团队在2018年提出的生成词向量的BERT算法在11个NLP任务上取得了显着的提升,堪称2018年深度学习领域最振奋人心的消息。BERT算法中最重要的部分是Google团队在2017年发表的论文《Attention Is All You Need》中提出的Transformer的概念。首先我们回顾一下基于RNN的Seq2Seq模型中的注意力机制,并通过下面的动画大致了解一下注意力是什么机制用于。在机器翻译中常用的Seq2Seq模型中,加入了attention机制,将每个encoder的RNN的hiddenlayer传递给decoder,decoder再进行下面的attention分析。下图展示了attention分析的细节:attention机制是decoder的对每个encoder的hiddenstate和hiddenstate的匹配度做一个分析,然后给出一个分数。这里有很多计分机制。可以使用小型网络或者线性计算,然后将这些分数用Softemax归一化,然后乘以对应的hi,然后将所有的hi加起来形成一个新的hiddenstate。也就是说,分值高的hiddenstates占比多,分值低的hiddenstates占比少。首先初始化一个隐藏状态和一个结束标记的向量作为输入,得到一个隐藏状态:h4,然后对h4和之前在encoder中得到的所有隐藏状态h1、h2、h3进行注意力分析,得到最终的C4,以及然后将C4和h4放在一起输入一个前馈网络得到第一个词的输出。接下来就是将第一层的输出和得到的h4作为下一层的输入,做同样的操作,如此继续下去,直到输出结束标记。
有了大概的attention概念之后,我们就正式来说说这篇论文。论文作者提出了一个Transformer模型。该模型的主要特点是完全基于注意力机制。NLP直接抛弃了RNN和CNN,这也是为什么这篇论文叫做AttentionIsAllYouNeed。放弃RNN后有一个很大的好处就是整个模型在训练的时候有更好的并行性,可以大大减少训练时间,因为使用RNN模型的时候,encoder里面的词必须一个一个输入,而如果使用Transformer,可以直接输入一句话。模型结构如下图所示:
!b33e0ac499c3.png#align=left&display=inline&height=481&name=Transformer-model.png&originHeight=1154&originWidth=1113&size=106833&status=done&width=464)
这个模型看起来很复杂,其实比RNN简单,下面说说关于它一点一点。
在Transformer中,还有编码器和解码器。编码器对输入进行编码,解码器对编码结果进行解码。下图以黑盒的形式展示了模型的主要结构。输入被传输到编码器中,编码器会将部分内容发送给解码器,部分内容会发送给下一层的编码器。编码器和解码器都有Self-Attention模块和前馈网络模块。解码器比编码器多了一个Encoder-DecoderAttention模块

这里的Self-Attention模块是整个结构的核心,让我们用一个例子帮助大家理解什么是Self-Attention:
这里有一句话:Theanimaldidn'tcrossthestreetbecauseitwastootired
要让计算机理解这句话,它需要让计算机弄清楚它指的是哪个词,是街道还是动物?即判断输入句子中各个词之间的相关程度。前面RNN例子中的attention是输入和输出之间的attention,self-attention是句子之间的attention。通过attention机制,我们可以得到下图所示的词之间的关联度,其中It和Theanimal的关联度最高。大致了解了什么是Self-Attention之后,我们来看看作者在论文中是如何设计模型来做这个机制的。作者将设计的模型称为ScaledDot-ProductAttention。如下图,作者从输入中提取了三个矩阵:Q,K,V。使用下面的公式来做Self-Attention分析。我们举个机器翻译的例子,看看这三个矩阵是如何提取出来的:在这个例子中,首先使用wordembedding技术,将句子的词汇转化为一个向量,得到这里的x1,x2向量作为model,论文中标准模型的词向量是512维,然后用每个xi向量构造三种向量:q(Query),k(Key),v(Value),构造方法是这里使用xi对Wq、Wk和Wv矩阵作为内积,其中矩阵中的值也是作为参数学习的。得到的三个向量的维度可以和输入的xi不同,论文中使用的是64。那么下图就是打分机制:每个q个向量和其他所有k个向量做内积,得到所有向量在这个qi位置的比例。也就是我们想要的Score,得到的score代表了每个向量在当前位置的权重,然后为了让梯度在学习过程中更稳定,作者对这些scores进行了缩放(除以根dk),即接下来就是将这些新的分数乘以对应词的值向量,最后相加得到这里的z1,也就是我们要处理的Attention之后的结果。小编认为这里作者给vector起的名字的意思是:q(Query)和所有其他词一样是对每个词的查询,k(Key)包含词与词之间关系的信息,给每个词的Query提供关系值。而v(Value)包含词汇信息。但这只是我的猜测,作者并没有在论文中说清楚。数学模型只是向量之间的简单内积。经过这样的例子,相信上面的公式应该很好理解了:在实际的模型中,作者对刚才的模型进行了进一步的改进。作者说这个模型就是Multi-HeadAttention。整个模型主要是将多个ScaleDotmoreSCALEDOT-ProductAttention模型堆叠起来形成一个新的模型(每个小模型对应一个head,所以叫Multi-Head)如下图:我们还是用上面这句话的例子来说明这样做的好处,如下图所示:这张图是两个头得到的attention效果。可以看出,它一个脑袋主要关注动物,另一个脑袋关注疲倦。显然,这样理解语义是有帮助的。我们来看看具体的结构:和前面的模型一样,我们使用输入进行线性运算,生成Q、K、V矩阵。不同的是我们这里定义了8组不同的Wq,Wk,Wv来生成8组不同的Q,K,V矩阵,也就是论文中提到的8个头,然后用这个公式生成8组attentionz0到z7有8个不同的QKV组,然后将z0-z7拼接在一起,在这里和W0做内积,得到最终的编码结果Z用于输入到前向网络。聪明的你一定会发现这个模型直接抛弃了RNN。丢失某些词汇顺序信息会有一个缺点,即哪个词在前,哪个词在后,对句子的意思有影响。所以作者提出用Postionalencoding的方法来弥补这个不足。如下图所示:输入词汇在embedding时,得到的向量并不是直接输入到模型中,而是位置信息的向量。位置向量的计算公式如上图所示。作者在论文中并没有具体说明为什么要用这样的公式,我只是说因为这里使用的三角函数可以让不同位置的PE值线性表示。作者也尝试通过学习来做这个位置信息,也取得了同样好的效果,但是用这里的公式计算速度更快。模型的核心,Self-Attention,到这里就说完了。我们来看看encoder和decoder是如何协同工作的:Input在经过刚才提到的一系列encode过程后,我们将生成每一层encoder生成的K和V矩阵传给decoder,再由decoder输出和之前的RNN模型一样,也是逐字输出。解码器首先对其当前得到的内容做一个self-attention,将生成的编码z输入到前馈网络,网络的输出再输入到下一层的Encoder-DecoderAttention模块(从图中可以看出,作者在网络的设计中,采用了残差网络的结构,将输入加到输出再传递给下一层)。Encoder-DecoderAttention模块的机制与Self-Attention模块相同,只是在使用Q,K,V矩阵时,该模块只为上一层的输入生成Q矩阵,而K和V矩阵是从对应层的编码器中得到的,也就是对编码器中的内容进行解码。当得到最后一层解码器的输出时,我们对输出进行线性运算和softmax归一化,得到每个词的概率,输出概率最大的词。如下图所示:实验:作者使用该模型翻译英文和德文。下图是不同超参数模型的效果对比:可以看出这里最后一行最大的模型获得了最好的BLEUscore效果。同时,作者还做了英法翻译,并与其他模型进行了对比:可以看出,最大的Transformer模型不仅BLEU分数比RNNCNN高,而且计算量也更少。点此观看论文相关直播课程[](https://www.yuque.com/docs/sh...Mo(网址:momodel.cn)是一个支持Python的人工智能在线建模平台,它可以帮助您快速开发、训练和部署模型,Mo人工智能俱乐部是由网站研发和产品设计团队发起的俱乐部,致力于降低人工智能开发和使用门槛,团队拥有大数据经验处理分析、可视化和数据建模,并承担过多领域智能化项目,具备从底层到前端的全线设计开发能力。主要研究方向为大数据管理分析和人工智能技术,并以此促进数据驱动的科学研究。目前,俱乐部每两周在杭州举办线下论文分享和学术交流活动。我们希望把对人工智能感兴趣的各界朋友聚集在一起,继续交流,共同成长,推动人工智能的大众化和普及化。
