全民 Transformer (一): Attention 在深度学习中是如何发挥作用的

《Attention 在深度学习中是如何发挥作用的:理解序列模型中的 Attention》

   Transformer 的出现让 Deep Learning 出现了大一统的局面。Transformer 首先在 NLP 的机器翻译上大放异彩,Attention is all you need 论文是很值得研究的,随后 Bert、DETR 的出现,Transformer的身影无处不在,目前 vis-transformer 又开始名声大噪。而 Transformer 的基础就是 Attention,本文翻译自 AI Summer 的一篇文章,方便记录和理解 Attention 是如何出现的,以及 Attention 是如何在深度学习中发挥作用的。

Key Words:Attention、Self-attention、Transformer


Beijing, 2021.01

作者:RaySue

Code:

Agile Pioneer  

  • 目录

文章目录


  我和 AI Summer 的作者情况差不多,一直从事于计算机视觉应用的相关工作。对于 Transformer和 Attention-based 方法只是略知一二,从没花时间来研究过,而 Transformer 目前已经在 ImageNet 上达到了 SOTA 的效果,所以不得不花精力研究一下 Transformer 了。

  Transformer 和 Attention 已经成功的在 NLP 的很多任务上使用了,包括阅读理解,摘要自动生成,单词补全等等。

  在大量的阅读和收集之后,我意识到理解 Attention 是如何从 NLP 以及机器翻译中出现的是非常重要的。这也是这篇文章的目的,读完此文,我保证你会对 Transformer 的前世今生有个了解。

  先来思考一个问题,什么是 Attention?读文章的时候要不断的问自己。

Memory is attention through time. ~ Alex Graves 2020 [1]

  Attention 机制自然而然从解决时间变化数据(序列)中产生。当我们正在处理“序列” 的时候,我们首先把问题以机器学习的角度公式化。Attention 则在处理序列任务中变得重要。

序列到序列学习 (seq2seq)

  不谈 Attention 和 Transformer,典型的序列到序列(Seq2Seq)工作很像下图所示的那样:

全民 Transformer (一): Attention 在深度学习中是如何发挥作用的

  序列的元素 x 1 x_1 x1​, x 2 x_2 x2​ 等等,通常被叫做 tokens,可以用来逐字表示任何变量。例如,文本表示,像素或者视频中的一帧图像。

  我们为什么需要这样的模型呢?

The goal is to transform an input sequence (source) to a new one (target).

  两个序列可以有同样的长度或任意的长度。你可能感到疑惑了,循环神经网络(RNNs)不就可以主宰这种类型的任务吗?因为我们喜欢顺序的处理序列问题。听起来显然就是最合适的做法。但是 Transformer 后面会告诉你不是的。

Encoder 和 Decoder

  编码器和解码器只不过就是对 RNN 层的堆叠,编码器部分处理所有的输入的时间步特征并产生一个压缩表示我们称之为 z z z,可以将其视为输入的压缩格式。

全民 Transformer (一): Attention 在深度学习中是如何发挥作用的

  另一方面,解码器收到上下文向量 z z z 并产生输出序列。最常见的 Seq2Seq 是应用是语言翻译。我们可以将输入的序列想成英文中的一个句子的表示然后输出法语中相同的句子。

全民 Transformer (一): Attention 在深度学习中是如何发挥作用的

  实际上,使用 LSTM 和 GRU 元素的基于 RNN 的结构的表现是很好的,但问题是只在序列长度较小(长度小于20)的时候表现才好,见下图:

全民 Transformer (一): Attention 在深度学习中是如何发挥作用的

RNN 的局限性

  编码器输出的中间表示 z z z 不能够编码输入时间步的全部信息。这也就是众所周知的瓶颈问题。这个向量 z z z 需要捕捉源句子的全部信息。

  理论上,数学的证明是可能,然而实际中,我们能够捕获到的过去信息(叫做参考窗口)是有限的。 RNN 趋向于忘记更前面的时间步的信息。

  让我们来看一个实际的例子。想象一个有 97 个单词的句子:

“On offering to help the *blind man*, the man who then *stole his car*, had not, at that precise moment, had any evil intention, quite the contrary, what he did was nothing more than obey those feelings of generosity and altruism which, as everyone knows, are the two best traits of human nature and to be found in much more hardened criminals than this one, a simple *car-thief* without any hope of advancing in his profession, exploited by the real owners of this enterprise, for it is they who take advantage of the needs of the *poor*.” ~ Jose Saramago, “Blindness.”

  上面这段英文中方便理解的加星号的单词都距离非常远!

  在大多数的场景下,中间变量 z z z 是不能够有效的压缩 97 个单词中较早出现的单词的。

  而最终导致的结果是系统会更加注意句子的后面部分的单词。然而,这不是最好的方法来解决序列任务的,和人类翻译或理解语言的方式并不兼容。

  进一步说,堆叠的 RNN 层通常会产生梯度消失的问题,如下图所示:

全民 Transformer (一): Attention 在深度学习中是如何发挥作用的

如何解决这个问题呢?Attention-base model 呼之欲出。

Attention 的出现

  Attention 的出现主要问了解决 Seq2Seq 模型的两个问题:

  1. 序列过长导致上下文变量 z z z 不能对早期时间步的特征进行有效的表示
  2. 梯度消失的问题

核心思想:上下文变量 z 应该直接访问输入序列的所有部分,而不只是最后一个部分。

  换句话说,我们需要 z z z 对输入序列的每个时间步形成一个直接的连接。

  这个想法最早来自于计算机视觉。Larochelle 和 Hinton [5]提出通过看图像的不同部分(瞥见),我们能够学到累积的形状信息并相应的对图像进行分类。

  同样的原理被应用到到序列任务上。我们同时看到了所有不同的单词然后学习“注意”到那些有助于解决手头任务的正确单词上。

  这就是所谓的 Attention 简单来说就像是记忆的概念一样,从多个沿着时间的输入中注意到有用的信息。

  以我的愚见全面的理解这个概念是重要的。为此,我们将 Attention 机制分为不同的类型来讨论。

Attention的类型:隐式 VS 显式

  我们先明确一个事情,那就是 Attention 是如何在机器翻译中使用的。

Very deep neural networks already learn a form of implicit attention [6].

  深度网络是一个非常丰富的函数近似器。不需要做任何的修改,他们就能趋向于忽略输入图像的一些部分并且聚焦于其他的部分。 例如,当我们做人体姿态估计的任务时,网络将对于人体上的像素更加敏感。许多激活单元显示出对人体部位和姿态的偏向性。

  一种观察隐式 Attention 的方式是通过看其相应于输入的偏导数。在数学中称为雅克比矩阵。实际上我们有很多的原因来强调隐式 Attention 的思想。Attention 对于人脑来说是相当的直观而且可解释。因此,我们可以显式的问网络,让网络来‘加权’对之前输入记忆的敏感度,我们接下来介绍一下显式 Attention

Attention的类型:hard VS soft(Attention-based model)

  区分 Attention base model 的另一个角度就是 hard attention 和 soft attention。在所有前面的场景下,我们提及的 Attention 是通过可微函数来进行参数化的。作为记录,我们在文献中称之为 soft attention,官方定义如下:

Soft attention means that the function varies smoothly over its domain and, as a result, it is differentiable.

  相对于 soft attention,我们有另一个概念叫做 hard attention。

  一个直观的例子:你可以想象一个机器人在一个迷宫中行走,每次必须要做出一个硬抉择来选择哪一条路要走,就像红色箭头表示的那样,如下图所示:

全民 Transformer (一): Attention 在深度学习中是如何发挥作用的

  一般来说,hard attention 意思是利用离散变量来描述的,而 soft attention 是用连续变量来描述的。换句话说,hard attention 使用随机抽样模型来代替决策方法。

  接下来的例子中,从图片的一个随机的位置开始尝试去寻找用于分类的“重要像素”。错略的说,在训练的时候,该算法让这个点必须选择一个方向走入到图像的内部。

全民 Transformer (一): Attention 在深度学习中是如何发挥作用的

  hard attention 是不可微的,我们不能使用标准的梯度下降法来解决。所以我们需要使用强化学习技术比如策略梯度和 REINFORCE 算法

  虽然如此,REINFORCE 算法和强化学习相似的方法的最大问题是方差过大,总结如下:

Hard attention 可以被看做成一个开关机制来决定是否关注一个区域,这也就意味着在整个域上会有很多的突然的改变。
  最终,假设我们已经有了所有的序列符号是可获取的,我们可以放松对 hard attention 的定义,这样的话,我们就有了一个平滑的微分函数,进而我们可以使用我们最擅长的反向传播来进行端到端的训练了。

Attention 用在 Encoder-Decoder 的例子

  在 Encoder-Decoder 使用 RNN 的例子中,假设解码器前一时刻的状态为 y i − 1 y_{i-1} yi−1​ 然后隐藏层的状态 h = h 1 , h 2 , h n h=h_1,h_2,h_n h=h1​,h2​,hn​,我们可以定义如下的公式:

e i = a t t e n t i o n n e t ( y i − 1 , h ) ∈ R n e_i=attention_{net}(y_{i-1}, h) \in R^n ei​=attentionnet​(yi−1​,h)∈Rn

  索引 i 表示预测的时间步。本质上,我们在解码器的每个隐藏层状态和所有的编码器的隐藏层状态之间定义了一个得分 score (权重)。 目的是为了在解码器的每个时间步上显式的学习应该“注意”到编码器隐藏层状态的哪些变量上。

  更具体的来说,对于编码器的每个隐藏层的状态(用 j 来表示) h 1 , h 2 , h n h_1,h_2,h_n h1​,h2​,hn​ 我们将会计算一个标量,用以表示在第 i 个解码阶段,编码器第 j 个隐藏层的权重:

e i j = a t t e n t i o n n e t ( y i − 1 , h j ) e_{ij} = attention_{net}(y_{i-1}, h_j) eij​=attentionnet​(yi−1​,hj​)

全民 Transformer (一): Attention 在深度学习中是如何发挥作用的

  仔细观察上图你会发现在前的公式中用于表示 score 的变量( e i j e_{ij} eij​)和图中的 score 变量( α i j \alpha_{ij} αij​)的符号是不一样的,实际上它们的数值也是不一样的, α i j \alpha_{ij} αij​ 是 e i j e_{ij} eij​ 经过 s o f t m a x softmax softmax 的结果,比起后者能够转换为概率分布,还可以让不同的得分对比更加的明显。

α i j = e x p ( e i j ) ∑ k = 1 T x e x p ( e i k ) \alpha_{ij} = \frac{exp(e_{ij})}{\sum^{T_x}_{k=1}exp(e_{ik})} αij​=∑k=1Tx​​exp(eik​)exp(eij​)​

最终的 Attention 层的结果如下:

z i = ∑ j = 1 T α i j h j z_i = \sum_{j=1}^{T} \alpha_{ij} h_j zi​=j=1∑T​αij​hj​

  理论上,attention 的定义为所有值的加权平均。但是这里加权方式是一个可学习的函数!

直观来说,我们可以把 $\alpha_{ij}$ 看作一个数据依赖的动态权重。因此,显然我们需要一个记忆的概念,并且想我们前面提到过的 attention 的权重存储了时间线上的记忆。

  所有前面提及的内容和我们选择如何建立 attention 模型无关!我们将稍作讨论。

Attention 作为一个可训练的权重对于机器翻译的意义

  最直观的方式来理解 Attention 在 NLP 任务当中的作用是考虑单词的软对齐。拿机器翻译来说,软对齐的结果如下图所示:

  在机器翻译中,我们能够使用热力图来可视化训练网络的 Attention的分布情况,注意 scores 是动态计算的。

全民 Transformer (一): Attention 在深度学习中是如何发挥作用的

  仔细观察上图你会发现热力图中会有一些非对角线的元素被激活了。在标记的红色的区域中,模型学习到了在翻译中交换了单词的顺序。这个任务不一定是一对一翻译的也可能是一对多的,意味着输出一个单词可能需要多个单词共同作用(每个单词有不同的重要性)。

如何计算 Attention

  在我们前面的 encoder-decoder 的例子中,我们把 attention 记为 a t t e n t i o n n e t ( y i − 1 , h j ) attention_{net}(y_{i-1}, h_j) attentionnet​(yi−1​,hj​),表示输入解码层前一时刻的输出 y i − 1 y_{i-1} yi−1​ 和编码器隐藏层的所有输出 h = h 1 , h 2 , h n h=h_1,h_2,h_n h=h1​,h2​,hn​。事实上我们需要一个得分来描述两个状态的关系,并捕获如何将他们“对齐”。

  利用一个小的神经网络来计算 Attention 是一个最突出的方法,这些年有很多不同的想法来计算 attention 的得分。最简单的一种方法就是直接对 y i y_i yi​ 和 h h h 做点积来计算 attention。进一步思考,我们引入了一个可训练的矩阵 y i W a h y_i W_ah yi​Wa​h,其中 W a W_a Wa​ 是一个中间的可训练的矩阵。再进一步,我们也能引入一个激活函数混进来,这样的做法就更类似于神经网络了 v a T t a n h ( W a [ h ; y i − 1 ] ) v^T_atanh(W_a[h;y_{i-1}]) vaT​tanh(Wa​[h;yi−1​]) 这个是 Bahdanau 等人提出来的。

  在确定的场景下,对齐只是受隐藏状态的位置所影响,所以我们可以简单的使用 softmax 函数来量化对齐结果。

  最后一个值得提及的是 Graves A. 在文章 Neural Turing Machines 中提出的把 attention 的计算作为一个余弦相似度的度量 c o s i n e [ y i , h ] cosine[y_i, h] cosine[yi​,h]。

  下表中 s t s_t st​ 表示解码器的预测值,不同的 W W W 表示可训练的矩阵,把不同的 Attention 的计算方式汇总得到的表格如下:

全民 Transformer (一): Attention 在深度学习中是如何发挥作用的

  经受住时间考验的计算 Attention 的方式是 Bahdanau 提出的最后一种方法,他们将 Attention 参数化的任务用一个小的全连接网络来实现。显然,我们可以对其进行扩展得到更多的层。

  实际上,意味着 Attention 现在是一个可以通过标准的反向传播算法来训练的权重集合。

  Bahdanau 等人完美的阐述如下:

"直觉上,是在解码器端执行了 Attention 机制。解码器决定原始句子中哪些部分应该被注意。通过让解码器拥有 Attention 机制,我们减轻了编码器需要将源句子中的所有信息编码到一个固定长度向量的负担。通过这个新的方法,信息可以分布在整个注释序列中,可以被相应的解码器有选择的检索。"

  最后需要考虑的就是计算复杂度的问题了,虽然效果变好了,但是计算复杂度却增加了,我们需要多训练一个有 O ( T 2 ) O(T^2) O(T2) 权重的神经网络(其中 T 是输入和输出序列的总长度)。所以平方的复杂度还是不容忽视的。所以我们可以以一定的窗口来进行局部的Attention,这里插一句,貌似 SE layer 和 ECA-Net 就是这样的全局和局部的 Attention 关系,后者更轻量化而且效果更好。

全局 VS 局部 Attention

  目前为止我们假设 Attention 都是通过整个输入序列来计算得到的(全局 Attention)。尽管这种做法是简单的,但是带来的计算复杂度是较高的并且有些时候是不必要的。因此,有些论文中提出局部 Attention 可以作为一种解决方案。

  • 在局部的 Attention 中,我们只考虑输入输入符号的一个子集。

  实际上,有些时候对比较长的序列来说,局部 Attention 更好,它可以被看作为 hard attention 因为我们需要先做一个硬抉择来排除一些输入单元。下图通过对比全连接层和一维的卷积层,我们可以类比 全局 和 局部 Attention。

全民 Transformer (一): Attention 在深度学习中是如何发挥作用的

Attention 上的不同颜色表示这些权重在推理的时候是时常改变的,不同的数据计算的结果不同,权重就不一样,而不是像训练时候的卷积或全连接那样是根据梯度下降来缓慢更新变换的。

Self-attention:Transformer结构的重要元素

  我们也对相同的序列定义了 Attention,叫做 self-attention。我们现在通过权重得分来寻找序列上元素之间的联系,而不再是寻找 输入-输出 序列之间的联系/对齐了,如下图所示:

全民 Transformer (一): Attention 在深度学习中是如何发挥作用的

  我个人喜欢将 self-attention 看作一个图。实际上,它可以被看作为一个(k个顶点的)无向加权的图。无向表示这个矩阵是对称的。

  数学上我们有: s e l f − a t t e n t i o n n e t ( x , x ) self {-} attention_{net}(x, x) self−attentionnet​(x,x)。self-attention 可以被以任何提及的训练方式来计算。最终的目标是在转换到另一个序列之前对该序列创建一个有意义的表示。

Attention 的优势

  能够有效地解决两方面问题:

  • 瓶颈问题
  • 梯度消失问题

从概念上讲,Attention 的做法类似于卷积神经网络的跳跃连接。

  另一方面就是它的可解释性,通过观察 Attention 的权重分布,我们能够洞察模型的行为,也能够理解模型的局限。

Attention 超越语言翻译

  序列无处不在,transformers 除了在机器翻译中非常有用,也被认为是一个通用的NLP 模型,在文本生成,聊天机器人,文本分类等任务上也是很有效的。比如谷歌的 BERT 或 OpenAI 的 GPT-3。

  但是 Attention 也超越了 NLP。我们也看到注意力机制在图像分类模型中被使用了,通过看一张图片的不同位置来解决一个具体的分类问题。实际上,时间 Attention 模型最近已经超越了 SOTA 的ImageNet 模型。我们也发现其在医疗,推荐系统,甚至图神经网络上有所应用。

  一句话,Attention 不只是 transformers 并且 transformers 也不只是 NLP 方法,时间证明一切。

结论

  Seq2Seq 以RNN或其相关变体作为基础模块的编解码系统能够有效的处理序列长度小于20的序列问题,一旦输入序列过长就会导致上下文变量 z 无法对输入序列早期时间步的特征进行有效的编码。

  为了解决这个问题,Attention 被提出,在 Seq2Seq 的解码阶段的第 i 个时间步的隐藏层状态需要与输入序列的所有的 j 个时间步的隐藏层状态做一个动态的加权平均,其中的计算过程就是Attention 层。

  从 Attention 的计算复杂度的考量,将 Attention 分为 全局Attention 和 局部Attention,类似于 SE layer 和 ECA-Net。

  Attention 是一个通用的机制来介绍记忆的概念。记忆是根据时间线存储在 Attention 的权重中的,它会显式的告诉我们哪些模型更注意那些地方。最后我们清楚了各个 Attention 的区别,并且给出了一些有名的计算 Attention 的方式。

参考

https://theaisummer.com/attention/#attention-beyond-language-translation

https://blog.csdn.net/racesu/article/details/109596367?spm=1001.2014.3001.5501

上一篇:bert-for-tf2源码解读10------权重参数对应的结构图


下一篇:用深度学习(CNN RNN Attention)解决大规模文本分类问题