建设网站导航怎么盈利在哪里找人做公司网站
建设网站导航怎么盈利,在哪里找人做公司网站,河南宏业建设管理有限公司网站,苏州网站建设设计公司呐端叶敛探秘Transformer系列之#xff08;1#xff09;#xff1a;注意力机制
0x00 概述
因为各种事情#xff0c;好久没有写博客了#xff0c;之前写得一些草稿也没有时间整理#xff08;都没有时间登录博客和微信#xff0c;导致最近才发现好多未读消息和私信#x…呐端叶敛探秘Transformer系列之1注意力机制0x00 概述因为各种事情好久没有写博客了之前写得一些草稿也没有时间整理都没有时间登录博客和微信导致最近才发现好多未读消息和私信在这里和各位朋友说下万分抱歉。现在恢复更新是因为最近有些从非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 通用结构通过上面的原理分析我们可以知道注意力的核心思想就是帮助模型为输入的不同部分分配不同的权重这样可以提取关键信息让模型判断更精准更加节省算力和存储。但是如何实现注意力机制这就要解决两个问题在哪里做注意力计算如何做注意力计算我们接下来就继续学习。任务模型论文”A General Survey on Attention Mechanisms in Deep Learning“用下图总结了注意力模型的通用结构论文作者把这种通用架构叫做任务模型。任务模型包含四个部分特征模型。我们假设矩阵X为任务模型的输入矩阵的列可能是句子之中的单词。任务模型使用特征模型把X转换为特征向量F。特征模型可能是RNN、CNN、嵌入层或者其他模型。查询模型。q是由查询模型所产生的查询向量用来确定任务模型需要关注X中的哪些向量、提取哪些信息。或者说q可以被解释为一个一般问题哪个特征向量包含对q最重要的信息?注意力模型。特征向量F和查询向量q是注意力模型的输入注意力模型的输出是上下文向量c。我们会在接下来详细论述注意力模型。输出模型。输出模型使用上下文向量c将各个部分组合成最终的高级特征向量^y例如输出模型可以是softmax层它输出一个预测。我们用一个句子“北国的特产”为例来解释下图。图上X就是“北国的特产”这个完整的句子F是从“北国的特产”提取到的特征向量列表Z是“特”q是从“特”提取出来的特征向量我们目的就是要获取特征向量列表中哪个特征向量包含对于”特“最重要的信息。注意力模型注意力模型的内部流程如下图所示该模型的目标是生成V中向量的加权平均值具体计算流程如下。标号1是输入两个输入从输入生成的特征向量F会进一步生成键矩阵K和值矩阵V。标号2使用矩阵K和查询向量q作为输入通过相似度计算函数来计算注意力得分向量e。q表示对信息的请求el表示矩阵K的第l列对于q的重要性。标号3通过对齐层比如softmax函数进一步处理注意力分数进而得到注意力权重a。标号4利用注意力权重a和矩阵V进行计算得到上下文向量c。QKV因为此处提到了Q、K、V这三个术语我们先用文本翻译为例来做初步介绍后续章节会对Q、K、V进行深入分析。从上文的分析可知序列中的每个单词都需要了解序列中其它单词的信息从而才能确定彼此间的相互关系。因此每个单词都要去询问其它单词咱俩之间是否密切其它单词回复关系密切与否。拿到相互关系后每个单词会据此把其它单词的信息吸收进来做信息融合。上述操作其实是一种搜索合并的运算我们需要找到一个适合的机制将这种运算进行落地。而上图注意力模型中有两个输入q正在处理的序列/目标序列和F被关注的序列/源序列F又分别转换为K和V这三个变量综合起来使用就可以满足我们的需求。Q查询矩阵目标序列的每个元素把自己的特征总结到一个向量query之中可以理解为某个单词像其它单词发出询问。目标序列所有元素的query构成了查询矩阵Q。K键矩阵源序列的每个元素都会把自己的特征总结到一个向量key之中。可以理解为某个单词的特征或者说某个单词依据自己特征来回答其它单词的提问。目标序列所有元素的key构成了键矩阵K。V值矩阵源序列的每个单词的实际值最终提供的信息是向量value。源序列所有元素的value构成了值矩阵V。后续我们用 query、key、value 代表相关向量用Q、K、V代表相关向量构成的矩阵。从词典的角度来看也许可以促进理解。query是你要找的内容key是字典的索引字典里面有什么样的信息value是对应的信息。普通的字典查找是精确匹配即依据匹配的键来返回其对应的值。而注意力机制是向量化模糊匹配信息合并。注意力机制不仅查找最佳匹配还要依据匹配程度做加权求和。源序列每个元素转化为对这就构成了源序列的字典。目标序列每个元素提出了query这就是要查询的内容。在查找中目标序列中每个元素会用自己的query去和目标序列每个元素的key计算得到对齐系数。这个对齐系数就是元素之间的相似度或者相关性。query和key越相似就代表value对query的影响力越大query越需要吸收value的信息。随后query会根据两个词之间的亲密关系来决定从V中提取出多少信息出来融入到自身。通过 query、key、value 这三个向量的相互作用模型得以衡量每个单词对其他单词的关注度。最终源序列的每个元素会把自己融合其它单词提供的信息之后得到的真实数据放到一个向量中。我们假设源序列和目标序列为同一个序列下图中给出了序列中”一个“和其它单词之间的相似度。虚线代表key与query的相关度线条的粗细分布就叫做”注意力分布“。或者说线条的粗细就是权重线条越粗表示key与query越相关对理解query越重要value的权重就越大。3.3 计算流程我们把注意力机制引入到seq2seq领域来详细看看它的计算流程。思路我们首先看看总体思路。自注意力层是一种和循环层和卷积层等效的计算单元。它们的目的都是把一个向量序列映射成另一个向量序列比如说编码器把x映射成中间表示z。我们先回想翻译场景。如果是RNN方案则最终编码器会生成一个隐向量然后把这个隐向量传递给解码器进行解码。前面已经分析了这种方案的弊端比如隐向量是固定的。为了克服这种弊端我们应该在每一个时间步t都会产生一个隐向量ht把这些ht保存起来。当产生新输出时我们让模型回顾之前保存的所有隐状态发现隐状态中的关键信息就用上这样就摆脱了RNN中隐向量是固定长度的弊端。但是如何判断某个隐状态对当前生成词是否重要这就需要模型采用某种机制进行学习从而才能了解需要给这个隐状态多少注意力。总而言之注意力机制的任务应该是找到解码器当前隐向量和编码器所有隐向量之间的相互关系。按照上述思路注意力机制的计算总体可以分为两步在所有输入信息上计算注意力分布。编码器不只是传递最后一个隐藏状态而是传入所有的隐藏状态到解码器。根据注意力分布来计算输入信息的加权平均。需要注意这是一种数据依赖的加权平均是一种灵活、高效的全局池化操作。具体我们又可以把这两步拆解为5个详细步骤具体如下生成语义向量。将源序列依次输入编码器编码器依次执行将源序列的信息编译成step_len个语义向量供后续解码器使用。即针对输入序列中的每个单词编码器都会输出一个隐状态向量表示该单词及其上下文信息的表示。计算对齐系数a。对于解码器输出的每个词Yi我们需要关注源序列的所有词和目标序列中当前词的相关性大小。因此会在解码器输出每一个预测值之前会针对编码器输出的所有语义向量来计算一些注意力分数Attention Score。我们可以把源序列认为是key把目标系列认为是query这样就和上面的”注意力模型的内部流程“图对应起来。计算概率分布。将对齐系数进行汇总使用softmax进行归一化得到注意力权重w。对这些分数进行softmax操作的目的是放大高分隐藏状态抑制低分隐藏状态。后续我们将没有做softmax归一化之前的对齐系数称为注意力分数将注意力分数经过softmax归一化后的结果称为注意力权重。计算当前上下文向量Context。使用注意力权重w作为权重对编码器所有的向量进行加权求和得到解码器当前时刻的上下文语义向量Context。注意力权重表示每个输入单词对于当前输出单词的重要程度。上下文向量表示当前输出单词所需的源语言信息。更新解码器状态隐状态Hi。计算输出预测词。把解码器前一次的输出、解码器当前状态和解码器当前时刻的上下文语义向量Context这三者作为输入调用函数f()计算得到解码器本次的输出。这个输出是一个概率分布表示每个可能的目标语言单词作为当前输出单词的概率。然后做一个概率值到目标词表的映射如果注意力机制时用于分类模型那就是做一个到各个分类的映射便可以得到下一个输出单词。以上步骤对应下图中标号1~6。我们以“我吃了一个苹果”为例每次输出的上下文如下输入“我得到C1(我 * 1)。输入”吃了“得到C2(我 * 0.5, 吃了 * 0.5)。输入”一个“得到C3(我 * 0.45, 吃了 * 0.45, 一个* 0.1)。输入”苹果“得到C4(我 * 0.3, 吃了 * 0.3, 一个* 0.1, 苹果 * 0.3)。得到的注意力权重为w3,1,w3,2,w3,3,w3,4softmax(g(Y2,C1,C2,C3,C4))。我们接下来对几个关键概念再进行分析。注意力分数当模型需要决定给予序列中某个单词以多大的“注意力”时它会计算该单词与其他单词之间的注意力分数。注意力分数是衡量序列中不同单词对当前单词的重要性程度的指标或者说是目标单词和输入中某单词对齐的可能性大小。可能性越大就应该赋予更大的权重。大权重代表在生成输出时当下预测单词应该更加关注源文本中其对应单词的信息。注意力分数通过相似度计算函数得到。该函数一般接受key和query向量作为输入输出key和query向量之间的相关性即注意力分数。下图提供了这些函数的概述其中q是查询向量kl是矩阵K的第l列。如果对应到seq2seq则q可以认为是解码器输出的隐向量k可以认为是编码器内部的隐向量。现实中相似度计算函数是通过矩阵形式来计算而非单独计算某一列。注意力权重得到注意力分数之后模型会使用softmax操作将注意力分数进行归一化得到注意力权重这样可以使得所有权重总和为1确保所有源元素贡献的特征总量保持一定也可以更加突出重要的权重。加权求和得到注意力权重之后每个query都能从对应的key上获取相应的信息此时就需要由输出函数Output Function来将各个部分组合成最终的高级特征向量进行输出。在本阶段注意力机制会以加权求和的模式对数据进行加工。这意味着每个单词在新的表示中不只是自身的信息还包含了其他单词的信息这帮助模型捕捉输入序列中的依赖关系。wifscore(Ki,Q)∑fscore(Ki,Q)Out∑fout(wi?Vi)小结我们梳理下计算过程中的重点三步如下计算分数score function。query和所有的key进行相似度计算得到注意力分数。计算公式为sia(q,ki)归一化alignment function。使用softmax操作将权值进行归一化计算公式为asoftmax(si)生成结果context vector function。使用a对value进行加权平均可以理解为输出y是在value之间根据key-query的相似度进行内插值。计算公式为AttentionValue∑iaivi因此注意力的思想可以改写为如下公式通过计算相似性得出权重最后加权求和。Attention(Target,Source)Attention(Query,Source)LengthSource∑i1Similarity(Query,Keyi)?Valuei具体如下图所示。3.4 问题解决回忆下之前提到的RNN方案和CNN方案遇到的问题对齐问题、信息遗失问题和长依赖问题。以及为了从根本上解决这些问题我们提出的几种改进思路通过拓展隐状态的长度或者增加新影响力因子来增加信息含量。让序列中两个词之间的关系距离更近或者让各个词直接建立联系。平等看待序列中每个单词的顺序避免忽略靠前的输入。对于序列进行”划重点“以区别不同元素所携带的信息量。同时向前预测和向后回顾。我们接下来就以自注意力机制为例看看其如何通过自己的优点来解决之前提到的问题顺便也和这两个方案做下对比分析。增大信息含量与RNN、CNN方案相比自注意力机制可以增大信息含量从而有效的解决RNN中的信息遗失问题。从某种程度上来看所有的序列建模都在做如下操作把历史上下文存储到一个隐藏状态。依据一定的更新规则对这个隐藏状态进行变换。下图就展示了序列建模方式的特点和典型案例这些典型案例都包括三个组件初始状态、更新规则和输出规则。RNN方案中解码器把过去所有的上下文信息压缩到一个固定大小低维向量隐状态中。解码器的不同阶段都使用这个隐状态。该方案的优势是在长上下文中的线性相对于二次复杂性。但是在长上下文时RNN受限于固定大小的隐状态表达能力有限很难利用额外的条件信息。TTTTest-Time Training则把上下文压缩到模型的权重中其优势是既能在时间上保持固定大小又能大大增强表达能力。自注意力机制使用一个列表从后续文章中我们会知道这其实是KV Cache作为隐状态。所有的上下文都存储在列表中没有被压缩。列表中所有的上下文共同构成了统一的隐状态每个阶段的隐状态是列表的一项这样编码器可以将更多数据传递给解码器。因此我们可以看到自注意力机制Transformer的优势不只像RNN那样只传递一个编码器最终的隐状态而是传入所有的隐藏状态对应处理过的所有token到解码器。这样新的token就可以和过去所有上下文进行交互。当然随着上下文长度的增加使用列表的成本也会越来越高其处理时间随上下文长度急剧增长列表的内存也急剧增加。缩减单词间距我们还是搬出之前的图来进行辅助解析。自注意力机制中当某单词获取其它单词信息时其它单词和它的位置距离都是固定常数。这样两个词之间的紧密程度仅取决于它们的真实相关性而非取决于距离。或者说对绝对位置不敏感任意两个词都可以直接建模。该特点可以解决长距离依赖问题。我们具体分析下。首先CNN虽然可以借助增加卷积层数来扩大视野融合信息但是信息在过深的网络传播过程之中容易丢失导致模型性能下降。自注意力机制摒弃了 CNN 的局部假设把感知域perceptive field调整到了整个序列。RNN方案因为无法弥补长距离依赖问题会导致梯度消失和梯度爆炸问题。在处理任何一个单词时自注意力可以注意到整个句子的所有单词这样可以将序列中的任意两个位置之间的距离缩小为一个常量能在常数时间内有效地捕捉到它们之间的依赖关系直接建立联系从而消除了距离概念。因为此特点自注意力机制的信息传播损失小。下图为三个方案构建词语之间关系所需距离的对比。另外常数距离特点也让自注意力机制没有“有序假设”。让自注意力机制在处理每个位置时并非像RNN那样更容易注意到靠后的内容忽略靠前的输入。而是平等看待序列中每个单词的顺序这样能够有效得考虑到输入序列中的其他位置可以更好的将对其他单词的“理解”融入到当前处理的单词中信息融合效率高。最后常数距离特点让自注意力机制没有了递归的限制像CNN一样可以在每一层内实现并行。选择性处理信息注意力机制可以选择性地关注和处理相关信息这样即可以提纲挈领又可以有效地解决对齐问题。加权求和加权求和可以分为加权和求和两方面来看前者是对数据进行有差别的对待而后者是做数据融合综合在一起就是用提纲挈领对于不同信息量的元素给予不同的关注度的方式对数据进行加工。我们接下来从不同角度对加权求和与CNN、全连接层进行比对分析。首先注意力机制是动态产生权重。CNN或者全连接层的权重是静态权重这些权重在训练时候固定下来在推理时使用相同权重进行推理并没有建立权重和输入实体本身的关系。注意力机制是动态权重用输入的query、key通过相似度计算来得到注意力权重。注意力机制根据输入来计算出输出应该更关注哪些输入权重的产生随着输入变化这是一种自适应操作。其次从另一个角度来看注意力机制是站在某个输入对象的立场上看待上下文和它之间的关系并以此关系为权重来确定如何吸取其它对象的信息。因此注意力机制是一种相对关系建模。而这种操作大多采用全局注意力以建模更广范围的依赖关系是一种全局操作。综上所述加权求和以一种动态、相对、全局的关系更好的完成了对序列信息的处理。对齐机制将注意力应用在序列转换的源序列和目标序列之间就是对齐机制。在机器翻译中源序列中的每个单词都可能会对输出造成影响不仅仅是待翻译词之前的输入其后续的输入也可能对输出产生影响因此需要结合源序列和目标序列进行综合考虑。比如下面中译英的例子当翻译到”一个“时我们无法确定英文应该翻译成”a“还是”an“必须往后看到”苹果“才能确定因此需要在翻译时把”a or an“的操作和”苹果“进行对齐。中文我吃了一个苹果然后吃了一个香蕉。英文I ate an apple and then a banana。注意力允许依据输入序列和输出序列的不同部分进行相关度计算这样就可以决定在输出某个单词时模型将重点关注输入数据的哪些部分。从而在输入序列和输出序列进行对齐更准确地学习序列之间的关系提高模型的泛化能力和性能。下图中虚线代表key与query的相关度线条越粗表示越相关。我们可以看出来“一个”和“苹果”等词对“an”的编码更重要或更相关或更相似应该承担更多的对“an”的预测需要赋予更多的权重。因此在模型生成“an“的时候不但要从”一个“提取语义也要从”苹果“提取语义才能判断出来应该是”an“还是”a“。最终”一个“和”苹果“共同决定了对应的英文单词应该是an。同时前瞻和回顾编码器可以同时从左到右和从右到左读取输入序列并将每个时间步的隐状态拼接起来作为输出。这样做的好处是可以让编码器同时考虑输入序列中每个单词的前后上下文信息从而生成更丰富和完整的表示。3.5 优劣综上所述注意力机制确保每个解码步骤都由最相关的上下文片段提供信息为长期存在的长距离依赖问题提供了稳健的解决方案从而重新定义了序列建模的格局。而且注意力机制的提出不仅是技术上的突破也为机器学习领域开辟了新的视野更反映了人类认知的深刻影响。正如 Andrej Karpathy 所评价的“注意力是一种重大解锁是神经网络架构设计的一次飞跃。”注意力机制并非完美方案其也存在若干缺点最主要的问题就是计算速度慢和存储占用高。算力需求大。注意力机制需要计算序列中每个元素对其他每个元素的关系因此随着输入序列长度的增加计算量呈平方级增长。这在处理长序列时尤其成为问题限制了大语言模型的最大序列长度N的大小这就是在发展初期大模型往往只支持2K或4K token输入的原因。 与之对应RNN只要考虑之前的隐状态和当前输入。内存消耗大与计算复杂度类似注意力机制在处理长序列时需要存储大量的中间结果对内存的要求很高。0x04 注意力发展历史注意力机制只是一种思想可以用到很多任务上。我们接下来看看几个经典的使用注意力机制对Encoder-Decoder进行改进的案例也梳理一下历史上的重要节点。用范伟的话说我们要知道Transformer是怎么来的。当然我们也希望可以看到Transformer是怎么没的毕竟如果有新方案取代了Transformer那就说明AI领域将迎来新的历史性突破。我们首先用一个图来展示下注意力发展历史。大家可以看到 Transformer是建立在很多巨人肩膀之上的集大成者。此处参考了 看图学大模型Transformers 的前生今世(上)。4.1 RCTM论文Recurrent Continuous Translation Models 被认为是神经网络机器翻译(NMT)的开篇之作其特点如下使用编码器-解码器框架。编码器用CNN实现解码器用RNN实现。编码器将源文本转换成连续的上下文向量解码器将上下文向量转换成目标语言。解码中的每一步都用到了编码器生成的上下文向量。端到端神经网络模型。4.2 RNN 编码器-解码器论文Learning Phrase Representations using RNN Encoder–Decoder for Statistical Machine Translation这篇是Bengio 团队的成果其特点如下明确了编码器和解码器的概念且都用RNN来实现。解码的每一步都用到了编码器生成的隐向量。没有把编码器-解码器做成一个端到端的模型只是把解码器的输出概率作为特征喂给了统计机器翻译SMT模型。4.3 Sequence to Sequence Learning with Neural Networks论文“Sequence to Sequence Learning with Neural Networks”也起到了重要作用其特点如下使用端到端结构。用RNN实现编码器和解码器。将编码器生成的上下文作为解码器的初始化参数。