探秘Transformer系列之(1):注意力机制
因为各种事情好久没有写博客了之前写得一些草稿也没有时间整理都没有时间登录博客和微信导致最近才发现好多未读消息和私信在这里和各位朋友说下万分抱歉。现在恢复更新是因为最近有些从非AI领域转过来的新同学来找我询问是否有比较好的学习资料他们希望在短期内迅速上手 Transformer。我在网上找了下但是没有找到非常合适的系统的学习资料于是就萌发了自己写一个系列的想法遂有此系列。在整理过程中我也发现了自己很多似是而非的错误理解因此这个系列也是自己一个整理、学习和提高的过程。本系列试图从零开始解析Transformer目标是解析Transformer如何运作以及为何如此运作让新同学可以入门Transformer。力争融入一些比较新的或者有特色的论文或者理念让老鸟也可以通过阅读本系列来了解一些新观点有所收获。几点说明本系列是对论文、博客和代码的学习和解读借鉴了很多网上朋友的文章在此表示感谢并且会在参考中列出。因为本系列参考文章太多可能有漏给出处的现象。如果原作者发现还请指出我在参考文献中进行增补。本系列有些内容是个人梳理和思考的结果反推或者猜测可能和原始论文作者的思路或者与实际历史发展轨迹不尽相同。这么写是因为这样推导让我觉得可以给出直观且合理的解释。如果理解有误还请各位读者指出。对于某些领域这里会融入目前一些较新的或者有特色的解释因为笔者的时间和精力有限难以阅读大量文献。如果有遗漏的精品文献也请各位读者指出。本文为系列第一篇主要目的是引入Transformer概念和其相关背景。在2017年Google Brain的Vaswani等人在论文”Attention is All You Need“中发布了Transformer。原始论文中给出Transformer的定义如下Transformer is the first transduction model relying entirely on self-attention to compute representations of its input and output without using sequence aligned RNNs or convolution。其中提到了sequenceRNNconvolutionself-attention等概念所以我们接下来就从这些概念入手进行分析。我们先开始从Seq2Seq介绍然后逐渐切换到注意力机制最后再导出Transformer模型架构。0x01 背景知识本节我们将介绍一些背景知识和概念。1.1 seq2seqseq2seqSequence to Sequence/序列到序列概念最早由Bengio在2014年的论文“Learning Phrase Representations using RNN Encoder–Decoder for Statistical Machine Translation”中提出其代表从一个源序列生成一个目标序列的操作。因为机器翻译是大家较熟悉且容易理解的领域因此后续我们主要使用机器翻译来进行讲解避免引入过多概念。1.2 文本生成机制机器翻译其实就是文本生成。语言模型将文本看作是时间序列。在此视角下每个单词都和它之前的单词相关通过学习前面单词序列的统计规律就可以预测下一个单词。因此机器翻译会从概率角度对语言建模让新预测的单词和之前单词连成整个句子后最合理即原有句子加上新预测单词后成为整个句子的概率最大。这就涉及到自回归模型。1.3 自回归模型自回归Autoregressive模型是一种生成模型其语言建模目标是根据给定的上下文来预测下一个单词。遵循因果原则当前单词只受到其前面单词的影响自回归模型的核心思想是利用一个变量的历史值来预测其未来的值其将序列数据的生成建模为一个逐步预测每个新元素的条件概率的过程。在每个时间步模型根据之前生成的元素预测当前元素的概率分布。下图给出了自回归模型的示例。模型每次推理只会预测输出一个 token当前轮输出token 与历史输入 token 拼接作为下一轮的输入 token这样逐次生成后面的预测token直到新输出一个结束符号或者句子长度达到预设的最大阈值。就下图来说模型执行序列如下第一轮模型的输入是“You should”。第一轮模型推理输出“wear”。将预测出的第一个单词“wear”结合原输入一起提供给模型即第二次模型的输入是“You should wear”。第二次模型推理输出“shoes”。将预测出的第二个单词“shoes”结合原输入一起提供给模型即第三次模型的输入是“You should wear shoes”。第三次推理输出结束符号本次预测结束。该过程中的每一步预测都需要依赖上一步预测的结果且从第二轮开始前后两轮的输入只相差一个 token。自回归模式有几个弊端容易累积错误导致训练效果不佳因为后面的推理对之前推理的输出会有依赖。在训练初期模型尚不成熟几次随机输出会导致随后的训练很难学到任何东西。“一步错步步错”训练会变得极不稳定很难收敛浪费训练资源。只能以串行方式进行这意味着很难以并行化的方式开展训练、提升效率。1.4 隐变量自回归模型隐变量模型是一种引入隐变量来表示过去信息的模型。自回归模型在预测时会把过去观测到的信息总结起来记作ht并且更新预测xt。即总结htg(ht−1,xt−1)然后基于xtP(xt∣ht)来估计xt。由于ht从未被观测到因此ht就是隐变量这类模型也被称为隐变量自回归模型latent autoregressive models。有了ht之后其实预测变换为两个子问题。一个问题是如何根据之前的隐变量 ht−1 和之前的输入信息xt−1得到现在的隐变量ht另一个问题是如何根据当前的隐变量ht和之前的输入xt−1得到当前的xt 。其实这就是编码器-解码器模型要面对的问题。1.5 编码器-解码器模型目前处理序列转换的神经网络模型大多是编码器-解码器Encoder-Decoder模型。传统的RNN架构仅适用于输入和输出等长的任务。然而大多数情况下机器翻译的输出和输入都不是等长的因此对于输入输出都是变长的序列研究人员决定使用一个定长的状态机来作为输入和输出之间的桥梁。于是人们使用了一种新的架构前半部分的RNN只有输入后半部分的RNN只有输出上一轮的输出会当作下一轮的输入以补充信息两个部分通过一个隐状态hidden state来传递信息。把隐状态看成对输入信息的一种编码的话前半部分可以叫做编码器Encoder后半部分可以叫做解码器Decoder。这种架构因而被称为编码器-解码器架构所用到的模型就是编码器-解码器模型具体如下图所示图中编码器和解码器通过一个中间隐状态C来完成信息交互。编码器和解码器的作用分别如下编码器把输入句子的所有语义信息压缩成一个固定长度的中间语义向量也称为上下文向量或隐向量或隐状态该向量包含了可供计算与学习的、代表句子语言特点和含义的特征信息是输入的浓缩摘要。具体逻辑为编码器会对输入句子 X(x1,...,xn) 的每个词进行处理处理每个词之后会产生一个隐状态。从输入的第二个词开始编码器每个时刻的输入是上一个时刻的隐状态和输入的新单词。编码器输出的最后一个时刻的隐状态就是编码了整个句子语义的语义上下文context这是一个固定长度的高维特征向量C(z1,...,zn)输入句子每个时间步的信息都包含在了这个上下文中。解码器会把这个中间语义上下文向量C解码成输出句子Y(y1,...,ym)即解码器将编码器学习到的特征信息再转化为相应的句子。具体逻辑为在每个时刻解码器都是自回归的即上一个时刻的输出产生的字符yt−1作为下当前时刻t的输入之一生成当前时刻的字符yt。解码器最初的输入是中间语义上下文向量C解码器依据C计算出第一个输出词和新的隐状态即解码器的每个预测都受到先前输出词和隐状态的微妙影响。解码器接着用新的隐状态和第一个输出词作为联合输入来计算第二个输出词以此类推直到解码器产生一个 EOSEnd Of Service/序列结束标记或者达到预定序列长度的边界。从宏观角度看序列建模的核心就是研究如何把长序列的上下文压缩到一个较小的状态中。1.6 如何压缩如何压缩人们很容易想到马尔可夫假设即系统的未来状态只与当前状态有关。这也被称为近因效应从文本生成角度看就是当前词只与距离它比较近的个词更加相关。如果考虑前面n个单词这就得到了N-gram模型即当前单词的概率取决于前n个单词。但是基于马尔科夫假设的模型难以处理句子中的长距离依赖关系某个单词依赖句子中很早的单词也没有考虑深层语义关系。而且N-gram模型的大小几乎是n的指数倍如果n数目太大则n个单词组合数可能性太多对资源消耗过大因此需要新的模型。新模型应该不仅仅简单的关注单词的频率和顺序还可以考虑更长距离的依赖关系却又不必显式考虑那么多单词组合可能性于是人们想到使用神经网络来拟合。MLP 是最基本的神经网络模型之一它可以将词向量序列映射到一个固定长度的向量表示然后将这个向量输入到一个softmax层中计算出下一个词的概率分布。MLP虽然理论上没有距离长依赖问题但是很难训练好。CNN/RNN/Transformer等网络结构都可以看作是在MLP上添加的约束条件。通过这些先验约束同等参数量下的优化难度被降低模型更容易找到最优解。前面提到的“使用神经网络来拟合”就是使用CNNRNN或者Transformer来实现编码器和解码器。因为我们本系列介绍的主角是Transformer就说明Transformer在实现编码器和解码器上是存在优势的因此我们先来看看CNN和RNN方案的问题所在。0x02 CNN和RNN方案注本节只是从普遍意义或者说是在典型问题上进行阐释并非定论。因为CNN和RNN方案也是在不停的发展其某一个阶段的方案可能解决或者缓解了下面提到的问题。2.1 技术挑战当面临冗长且信息密集的输入序列时编码器-解码器模型在整个解码过程中保持相关性的能力可能会减弱。为了更好的说明我们先看看序列转换面对的主要技术挑战对齐问题和长依赖问题或者说是遗忘问题。对齐我们来看看为什么要对齐。首先在某些领域比如语音识别中虽然输入与输出的顺序相同但是没有一一对应的关系。其次在某些领域比如机器翻译中在处理完整个输入序列后模型的输出序列可能和输入序列的顺序不一致。以机器翻译为例假如我们要让模型将英语 how are you 翻译为中文 你好吗或者将“Where are you”翻译成“你在哪里”我们会发现翻译结果中的语序和原来句子的语序并不相同同时一些翻译结果并不能与英语中的词汇一一对应到。不对齐问题带来的最大困境是在时间序列的 t 时刻我们并不能确定此时的模型是否已经获得了输出正确结果所需要的所有信息。因此人们往往先把所有输入编码到一个隐状态然后逐步对这个隐状态进行解码这样才能确保在解码过程中模型一定收到了所需的全部信息。虽然此方案可以保证输入信息的完整性但却有一个明显缺陷即在解码过程中无法确定贡献度。比如当把”I love you翻译成“我爱你”时“我”应该与“I”对齐因为其贡献最大但是该方案中I,love,you这三个词对“我”的贡献都是一致的。长依赖我们以下面句子为例来进行分析。“秋蝉的衰弱的残声更是北国的特产因为北平处处全长着树屋子又低所以无论在什么地方都听得见它们的啼唱。”将例句从英文翻译成中文时英文和中文明显是有对齐关系的因此需要知道哪个英文单词对应到哪个中文。比如将”它们“翻译成”They“但是“它们”代表什么呢是“树”“屋子“还是”秋蝉“通过”啼唱“和知识我们知道“秋蝉”和“它们”指代是同一个对象但是如果把”听得见它们的啼唱“ 修改为“看见它们的树荫”则“它们”指代的就是“树”了。人类可以很容易的同时看到“秋蝉”和“它们”这两个词然后把这两个词关联起来即人们知道“它们”和“秋蝉”有长距离的依赖关系从而理解整个句子。但是对于计算机或者对于模型来说”秋蝉“和”它们“在例句中的距离太长了很容易被两个词中间的其它词干扰。为了准确给出最终的答案神经网络需要对前面”秋蝉的衰弱的残声“和”它们“之间的交互关系进行建模。然而某些神经网络很难处理长距离依赖关系因为处理这种依赖关系的关键因素之一是信号在网络中穿越路径的长度两个位置之间路径越短神经网络就越容易学习到这种长距离依赖关系两个位置之间距离越远建模难度就越大。如果模型无法处理长距离依赖则会出现长时信息丢失也就是产生了遗忘问题。我们接下来看看CNN方案和RNN方案如何应对这两个技术挑战。2.2 CNN方案CNN的本质是学习空间数据中的局部依赖关系。CNN的卷积操作可以提取重要特征但是因为单个卷积核的长度一般比较小所以CNN的卷积感受视野是局部的提取的是局部特征进行局部信息计算。即CNN对相对位置敏感对绝对位置不敏感难以提取序列的长距离依赖关系。为了让CNN可以处理长序列人们一般会堆叠更多的卷积通过叠加多层卷积区去把局部感受野进行扩大让卷积网络依靠深度来弥补全局信息的缺失从而捕捉长距离依赖。在这种方案中不同卷积层会提供不同层次的特征进而在上层完成长距离信息依赖计算把长序列的信息压缩到一个卷积窗口内部以此来让模型有机会捕捉到长距离依赖和复杂的结构关系。比如下图所示最下层CNN使用滑动窗口作用于这个文本序列每个窗口都对其中的数据进行处理。A1窗口获取到了“秋蝉”这个信息A3窗口获取到了“它们”这个信息。但是因为“秋蝉”和“它们”距离太远所以没有一个单一窗口可以把这两个词建立起依赖关系即没有单一窗口可以同时看到这两个词。因此模型只能持续堆叠卷积网络不断加深整个网络这样C1这个窗口才可以同时包含“秋蝉”和“它们”的信息。但是深度就代表间接间接就代表着流失。在CNN方案中因为信息被“逐级加工层层抽象”而且信息传递过程不够透明信息会在过深的网络传播过程之后只有部分保留导致模型性能下降。所以CNN一般在长依赖关系建模场景使用较少更适合短文本计算。2.3 RNN方案从表象上看RNN是时序结构后面的时刻天然就依赖于前面时刻的输出。从本质上来说RNN是一种连接主义模型具有选择性地在序列步骤间传递信息的能力可以对序列上下文信息以及不同范围元素间的局部依赖关系进行捕捉。RNN的独到之处在于引入了“记忆”功能让网络能记住之前输入的信息。随着数据在RNN中的流动之前时间步的记忆会作为输入参与到当前数据的处理中让模型能够动态地融合时间上下文和序列的历史信息。因为可以有效地处理变长的序列数据理论上RNN可以预测无限长句子利用前面所有信息所以非常适合翻译场景。思路事实上在Transformer出现之前编码器和解码器通常是由RNN或其变体如 LSTM 或 GRU组成的。我们先看看如何用RNN实现编码器。以下图为例编码器需要把“北国的特产”这个句子编码成隐状态。图中的每个方块都是一个简单的RNN单元。每个RNN单元接收两个输入输入词和隐状态输出一个隐状态。模型在第一步得到输入h0和“北”调用函数f()进行计算得到输出h1f(h0, 北)。h0是第一个隐状态通常内容是数值0或者随机值。模型在第二步得到输入h1和“国”同样调用函数f()进行计算得到h2。以此类推模型最终输出h5。在计算过程的每一步t前面所有节点得到的信息都保存在上一步计算出来的中间隐状态ht中因此后一个词的计算都会用到前面所有词的输出结果。可以把隐藏状态ht看作是信息循环的载体其承载的信息可以跨时间步在RNN中进行传递。随着数据在RNN中的流动之前时间步的激活状态会作为输入参与到当前数据的处理中让模型能够动态地融合时间上下文和序列的历史信息。因此从理论上来说RNN可以通过隐状态得到任意两个词的依赖无论这两个词距离多远它们的信息一定会在某一步计算之中汇聚。我们再给出编码器-解码器的结构图其中si是解码器在时刻i的隐状态。编码器读入输入的token xi并对每个token xi生成一个隐状态hi。从第一个h1到最后一个hm这些隐状态不断将前面信息积累。最后的携带整个输入序列信息的hm会作为解码器的输入s0。优点RNN的优点如下适合处理序列数据。RNN天然地适合处理具有时间序列或序列结构的数据如文本、语音和视频等。RNN可以灵活地处理不同长度的输入序列并捕捉序列中的依赖关系。捕捉长期依赖。RNN任意步的隐状态都包含了当前时间步之前所有时间步的几乎所有信息因此RNN可以捕捉序列中的长期依赖关系从而克服了马尔可夫模型的主要局限性这对许多序列学习任务至关重要。权重共享。RNN在处理序列时采用了权重共享的策略即不同时间步使用相同的权重。这可以减少模型参数数量降低过拟合的风险。速度快。每个输入仅仅依赖于对应的h因此所有token推理的消耗基本相同。整体推理速度和上下文长长度线性相关。缺点RNN的缺点同样鲜明。在RNN方案中在每个时间步RNN都会将序列中之前的所有信息压缩到一个固定长度的隐向量最终编码器和解码器之间只通过这个固定长度的隐状态来传递信息。固定长度的隐状态或者说有限的记忆能力在处理长序列时会导致接下来的几个问题比如信息遗失、信息瓶颈等。表达能力缺失RNN的特点会带来表达能力的缺失体现在如下几点既然隐向量长度固定那么这个压缩过程就是有损压缩会导致隐向量保存上下文的能力在本质上是有限的。我们以文本摘要为例如果几百字的散文隐向量还可以存储散文的全部语义信息但是面对几万字的小说隐向量将力有不逮。RNN是个偏序结构。虽然语言本身的词序和语法也构成了一个偏序结构但是通常又有定语后置补语和各种从句等附加方式这导致整个语序并不完全满足偏序结构因此RNN在处理长距离关联的复杂语法结构时力不从心。解码器解码时每个事件步的隐状态都基于编码器生成的同一个隐向量来构建这是不合理的因为不同位置的单词可能需要不同程度和不同方面的信息。而权重共享也导致会对输入中的每个单词都赋予同样权重无法对单词的重要程度进行区分。信息遗失因为RNN的表达能力缺失所以会带来信息遗失问题。信息遗失或者混淆。而且当新输入进入时原有信息可能被新信息覆盖或者被稀释这样模型会更加关注靠近尾部的输入序列早期部分的记忆会随着随着距离的增加产生传播衰减。越往前的输入信息衰减得越多如果关键信息出现在序列头部就容易被忽略。难以捕捉长距离依赖关系。以上图为例h4中包含最多信息的是当前的输入“特”最开始的“北”所携带的信息会被忽略很难有效构建两者的依赖关系。难以并行RNN需要对序列内容进行逐步处理 每一步的输出取决于先前的隐藏状态和当前的输入。RNN这种串行计算在本质上是一种递归其阻碍了训练时的并行计算导致训练效率较低训练时间过长。难以训练RNN的网络结构特点导致难以训练。RNN 用于信息传输通路只有一条并且该通路上的计算包含多次非线性激活操作当 RNN 处理长序列时因为时间步增加带来的多层激活函数的嵌套会导致梯度反传时指数级地衰减消失或增长爆炸这就是梯度消失问题或者梯度爆炸问题。当梯度消失时前面的梯度信息无法有效地传递 到后面也就导致词之间距离越远前面对后面的影响越弱所以RNN网络难以学习远距离依赖关系。当梯度爆炸时网络的权重会变得极大导致网络不稳定。而且当面对长序列时RNN需要大量内存来维持长序列的隐状态比如需要完整理解整个句子乃至整篇文章才能做出判断这些内存负担对训练也造成了很大挑战。2.4 当前问题我们总结CNN和RNN这两个方案的主要问题如下对齐问题。CNN和RNN都难以在源序列和目标序列之间做到完美对齐。隐状态长度固定。这个问题点主要存在于RNN因为其隐向量大小固定所以推理效果受限于信息压缩的能力导致信息遗失。关系距离问题。此问题在RNN和CNN中都存在。序列中两个词之间的关系距离不同当词之间距离过长时两个方案都难以确定词之间的依赖关系。使得当面临冗长且信息密集的输入序列时模型在整个解码过程中保持相关性的能力可能会减弱。我们再仔细看看”关系距离问题“。对于CNN方案序列的第一个词和最后一个词要通过多层卷积后才可以建立联系。下图中的粗线为CNN结构中两个词建立关系所需的最长距离。而RNN方案需要对序列“从头看到尾”才能确定给这两个词建立关系所需的距离。下图中的粗线是RNN结构中两个词建立关系所需的最长距离。因此我们要面对的问题是如何把大量的token压缩到一个隐藏状态中而且该状态还可以有效的捕捉它们的底层结构和关系。如果想从根本上解决问题我们有如下几步可以选择可以通过拓展隐状态的长度或者增加新影响力因子该因子可以反应输入序列各个位置对于解码器当前输出的影响力来增加信息含量。让序列中两个词之间的关系距离更近或者让各个词直接建立联系。比如对于RNN来说需要让隐状态和时序无关从而打破这个顺序结构。平等看待序列中每个单词避免像RNN那样更容易注意到靠后的内容而忽略靠前的输入。对于序列进行”划重点“这样可以区别不同元素所携带的信息量对于不同的元素给予不同的关注度。虽然大多数实时因果数据只知道过去的状态并期望影响未来的决策但是对于某些功能比如翻译我们希望可以做到同时向前预测和向后回顾。我们接下来介绍的注意力机制就可以在一定程度上解决上述问题。0x03 注意力机制注意力Attention机制由Bengio团队2015年在论文“NEURAL MACHINE TRANSLATION BY JOINTLY LEARNING TO ALIGN AND TRANSLATE”中提出其主要思路为通过模仿人类观察事物的行为来降低算法复杂度、提高性能。人类在感知、认知和行为决策过程中会选择性地关注和处理相关信息从而提高认知效率和精度比如人类可以依据兴趣和需求选择关注某些信息而忽略或抑制其它信息并且可以在多任务上分配注意力从而达到同时处理多个信息的目的。大家最熟悉的例子就是当一个人看图片时他会先快速通览然后对重点区域进行特殊关注。而在文本生成的每个阶段并非输入上下文的所有片段都同样重要。比如在机器翻译中句子“A boy is eating the banana”中的“boy”一词并不需要了解整个句子的上下文之后再来进行准确翻译。3.1 原理注意力机制可以从不同角度进行理解人们也做出了很多精彩论断比如注意力机制的本质是上下文决定一切。注意力机制是一种资源分配方案。注意力机制是信息交换或者说是是“全局信息查询”。这些角度彼此联系又各有特色我们逐一进行分析。上下文决定一切注意力机制的本质可以用一句话来总结上下文决定一切context is everything。一个字 / 词在一篇文本中表达的意思通常与它的上下文有关。比如下面两个句子中都有“transformer”这个单词但是第一个“transformer”应该翻译成“变压器”第二个“Transformer”最好不做翻译。Several distributor transformers had fallen from the poles, and secondary wires were down.Transformer models have emerged as the most widely used architecture in applications such as natural language processing and image classification.如何才能对“transformer”这个多义词进行语义区分我们必须考虑单词的上下文才能更好的把单词的语义识别出来即不仅仅要考虑到词本身还要考虑其他词对这个词的影响也就是语境的影响。比如第一个句子的“pole”、”fallen”和“wires”这几个邻近单词暗示了此处的“transformer”和真实物理环境相关。第二个句子的“model”和“natural language processing and image classification”则直接告诉我们此处的“Transformer”是深度学习相关概念。最终我们通过上下文语境可以推断出“Transformer”的准确含义从而把这两个英文句子翻译成如下几个变压器从电线杆上摔下来副线也垂下来。Transformer模型已成为自然语言处理和图像分类等应用中使用最广泛的架构。这就是注意力机制的作用将每个词与序列中的其他词联系起来通过句子中的其它词对我们关注词的语义进行推断。资源分配注意力机制也是一种资源分配方式。目前我们知道了上下文的重要性但是这还不够因为一个单词的上下文包括很多其它单词不同单词对目标单词的影响力往往不同。以翻译为例因为输入语句是一个连贯的整体所以每个输入词Xi都会给每个输出词Yi造成影响。因此在考虑单词上下文时候也需要考虑出上下文中每一个元素应该考虑多少。比如第二个英文句子中“model”对“Transformer”的影响力必然是最大的。所以我们需要一种机制来依据不同的上下文聚焦于不同的信息这样一来可以使得序列中的重要元素被投射以较高注意力重要信息不会被淹没二来可以将有限的计算资源用来处理更重要的信息从而做到提纲挈领。注意力机制就是这种资源分配机制。其在学习的过程中自适应的给予输入的不同词赋予不同的注意力权重从而区分输入的不同部分对输出的影响自适应的学习应该关注的重点位置做出准确判断即注意力赋予了模型分辨的能力。其实论文“Recurrent Models of Visual Attention”中有一段话就深刻的印证了资源分配这个角度。具体如下人类感知的一个重要特性是人们不会一次处理整个场景。相反人类有选择地将注意力集中在视觉空间的某些部分上以在需要的时间和地点获取信息并随着时间的推移将不同注视点的信息结合起来建立场景的内部表示指导未来的眼球运动和决策。将计算资源集中在场景的各个部分可以节省“带宽”因为需要处理的“像素”更少。但它也大大降低了任务的复杂性因为感兴趣的对象可以放置在注视的中心而注视区域外的视觉环境的无关特征“杂乱”自然会被忽略。其英文原文如下信息交换确定了资源分配的原则之后就可以进行信息交换。注意力机制计算过程就是序列中元素交换信息的过程。注意力机制的输入是一个序列或者集合注意力机制会从输入中选择性提取信息据此计算出一组权重。这组权重代表了各个信息的重要程度使用这种权重与原始信息相乘就得到了注意力处理后的加权信息。信息交换在一定程度上起到了RNN中记忆力模块的作用使得注意力编码器也能像RNN一样对一个复杂的语句或者场景进行理解和解析比如将注意力机制应用在序列转换的源序列和目标序列之间可以让两个序列互相交换信息起到信息对齐的目的。将注意力机制应用在一个序列内部这就是人们经常提到的自注意力机制可以让序列中每个词都和序列中其他词关联起来这样序列中每一个元素都有机会根据自身特征有选择性地依据词之间的相关性来吸取整个序列中每一个其他元素的信息对本身进行动态调整。这使得模型能够捕捉长距离依赖关系不受距离的影响。考虑以下两个句子第一句中的“it”就指代猫因此“it”更多吸收了“cat”的信息。第二个句子的“it”指代牛奶因此“it”更多吸收了“milk”的信息。The cat drank the milk because it was hungry.The cat drank the milk because it was sweet.自注意力机制的目的是为当前单词创建抽象的、丰富的表征。这个表征是本单词被相同序列中的其它单词所影响的结果。经过自注意力机制处理之后现在每个新单词都融入了其它单词的部分信息这是一种数据依赖的加权平均这种表征更加丰富。如果非要将自注意力机制和之前的注意力机制进行对比的话自注意力机制中的query相当于注意力机制中的解码器隐藏状态。自注意力机制中的key和value相当于注意力机制中的编码器隐藏状态。3.2 通用结构通过上面的原理分析我们可以知道注意力的核心思想就是帮助模型为输入的不同部分分配不同的权重这样可以提取关键信息让模型判断更精准更加节省算力和存储。但是如何实现注意力机制这就要解决两个问题在哪里做注意力计算如何做注意力计算