深入理解深度学习——注意力机制(Attention Mechanism):自注意力(Self-attention)

分类目录:《深入理解深度学习》总目录

相关文章:
·注意力机制(AttentionMechanism):基础知识
·注意力机制(AttentionMechanism):注意力汇聚与Nadaraya-Watson核回归
·注意力机制(AttentionMechanism):注意力评分函数(AttentionScoringFunction)
·注意力机制(AttentionMechanism):Bahdanau注意力
·注意力机制(AttentionMechanism):多头注意力(MultiheadAttention)
·注意力机制(AttentionMechanism):自注意力(Self-attention)
·注意力机制(AttentionMechanism):位置编码(PositionalEncoding)


在深度学习中,经常使用卷积神经网络(CNN)或循环神经网络(RNN)对序列进行编码。想象一下,有了注意力机制之后,我们将词元序列输入注意力池化中,以便同一组词元同时充当查询、键和值。具体来说,每个查询都会关注所有的“键—值”对并生成一个注意力输出。由于查询、键和值来自同一组输入,因此被称为自注意力(Self-attention),也被称为内部注意力(Intra-attention)

给定一个由词元组成的输入序列 x 1 , x 2 , ⋯   , x n x_1,x_2,\cdots,x_n x1,x2,,xn,其中任意 x i ∈ R d ( 1 ≤ i ≤ n ) x_i\in R^d(1\leq i\leq n) xiRd(1in)。该序列的自注意力输出为一个长度相同的序列 y 1 , y 2 , ⋯   , y n y_1,y_2,\cdots,y_n y1,y2,,yn,其中:
y i = f ( x i , ( x 1 , x 1 ) , ( x 2 , x 2 ) , ⋯   , ( x n , x n ) ) ∈ R d y_i=f(x_i,(x_1,x_1),(x_2,x_2),\cdots,(x_n,x_n))\in R^d yi=f(xi,(x1,x1),(x2,x2),,(xn,xn))Rd

接下来比较下面几个架构,目标都是将由 n n n个词元组成的序列映射到另一个长度相等的序列,其中的每个输入词元或输出词元都由 d d d维向量表示。具体来说,将比较的是卷积神经网络、循环神经网络和自注意力这几个架构的计算复杂性、顺序操作和最大路径长度。请注意,顺序操作会妨碍并行计算,而任意的序列位置组合之间的路径越短,则能更轻松地学习序列中的远距离依赖关系。
比较卷积神经网络(填充词元被忽略)、循环神经网络和自注意力三种架构
考虑一个卷积核大小为 k k k的卷积层。由于序列长度是 n n n,输入和输出的通道数量都是 d d d,所以卷积层的计算复杂度为 O ( k n d 2 ) O(knd^2) O(knd2)。如上图所示,卷积神经网络是分层的,因此为有 O ( 1 ) O(1) O(1)个顺序操作,最大路径长度为 O ( n k ) O(\frac{n}{k}) O(kn)。例如, x 1 x_1 x1 x 5 x_5 x5处于上图中卷积核大小为3的双层卷积神经网络的感受野内,两层神经网络即可读到彼此的信息。当更新循环神经网络的隐状态时, d × d d\times d d×d权重矩阵和 d d d维隐状态的乘法计算复杂度为 O ( d 2 ) O(d^2) O(d2)。由于序列长度为 n n n,因此循环神经网络层的计算复杂度为 O ( n d 2 ) O(nd^2) O(nd2)。根据上图所示,有 O ( n ) O(n) O(n)个顺序操作无法并行化,最大路径长度也是 O ( n ) O(n) O(n)。而在自注意力中,查询、键和值都是 n × n n\times n n×n矩阵。考虑《深入理解深度学习——注意力机制(AttentionMechanism):注意力评分函数(AttentionScoringFunction)》中缩放点积注意力,其中 n × d n\times d n×d矩阵乘以 d × n d\times n d×n矩阵。之后输出的 n × n n\times n n×n矩阵乘以 n × d n\times d n×d矩阵。因此,自注意力具有 O ( n 2 d ) O(n^2d) O(n2d)计算复杂性。正如在上图中所示,每个词元都通过自注意力直接连接到任何其他词元。因此,有 O ( 1 ) O(1) O(1)个顺序操作可以并行计算,最大路径长度也是 O ( 1 ) O(1) O(1)

总而言之,卷积神经网络和自注意力都拥有并行计算的优势,而且自注意力的最大路径长度最短。但是因为其计算复杂度是关于序列长度的二次方,所以在很长的序列中计算会非常慢。

自注意力的实例

假设有如下例句:

A dog ate the food because it was hungry.
一只狗吃了食物,因为它很饿。

例句中的代词it(它)可以指代dog(狗)或者food(食物)。当读这段文字的时候,我们自然而然地认为it指代的是dog,而不是food。但是当计算机模型在面对这两种选择时,就需要自注意力机制来解决这个问题。还是以上句为例,我们的模型首先需要计算出单词A的特征值,其次计算dog的特征值,然后计算ate的特征值,以此类推。当计算每个词的特征值时,模型都需要遍历每个词与句子中其他词的关系。模型可以通过词与词之间的关系来更好地理解当前词的意思。比如,当计算it的特征值时,模型会将it与句子中的其他词一一关联,以便更好地理解它的意思。如下图所示,it的特征值由它本身与句子中其他词的关系计算所得。通过关系连线,模型可以明确知道原句中it所指代的是dog而不是food,这是因为it与dog的关系更紧密,关系连线相较于其他词也更粗。

自注意力示例
为简单起见,我们假设输入句(原句)为“I am good.(我很好。)”。首先,我们将每个词转化为其对应的词嵌入向量。需要注意的是,嵌入只是词的特征向量,这个特征向量也是需要通过训练获得的。单词I的词嵌入向量可以用 x 1 x_1 x1来表示,相应地,am为 x 2 x_2 x2,good为 x 3 x_3 x3。这样一来,原句“I am good”就可以用一个矩阵 X X X(输入矩阵或嵌入矩阵)来表示了,其形状为 3 × 512 3\times 512 3×512。其中3为单词的个数,512为单个词嵌入的维度。

现在通过矩阵 X X X,我们再创建三个新的矩阵:查询(Query)矩阵 Q Q Q、键(Key)矩阵 K K K,以及值(Value)矩阵 V V V。接下来,我们将继续了解在自注意力机制中如何使用这三个矩阵。为了创建查询矩阵 Q Q Q、键矩阵 K K K和值矩阵 V V V,我们需要先创建另外三个权重矩阵,分别为 W q W^q Wq W k W^k Wk W v W^v Wv。用矩阵 X X X分别乘以矩阵 W q W^q Wq W k W^k Wk W v W^v Wv,就可以依次创建出查询矩阵 Q Q Q、键矩阵 K K K和值矩阵 V V V。值得注意的是,权重矩阵 W q W^q Wq W k W^k Wk W v W^v Wv的初始值完全是随机的,但最优值则需要通过训练获得。我们取得的权值越优,通过计算所得的查询矩阵、键矩阵和值矩阵也会越精确。如下图所示,将输入矩阵 X X X分别乘以 W q W^q Wq W k W^k Wk W v W^v Wv后,我们就可以得出对应的查询矩阵 Q Q Q、键矩阵 K K K和值矩阵 V V V
创建查询矩阵、键矩阵和值矩阵
根据上图,我们可以总结出以下三点:

  • 三个矩阵的第一行 Q 1 , : Q_{1, :} Q1,: K 1 , : K_{1, :} K1,: V 1 , : V_{1, :} V1,:分别代表单词“I”的查询向量、键向量和值向量。
  • 三个矩阵的第二行 Q 2 , : Q_{2, :} Q2,: K 2 , : K_{2, :} K2,: V 2 , : V_{2, :} V2,:分别代表单词“am”的查询向量、键向量和值向量。
  • 三个矩阵的第三行 Q 3 , : Q_{3, :} Q3,: K 3 , : K_{3, :} K3,: V 3 , : V_{3, :} V3,:分别代表单词“good”的查询向量、键向量和值向量。

因为每个向量的维度均为64,所以对应的矩阵维度为 [ 句子长度 × 64 ] [\text{句子长度}\times64] [句子长度×64]。因为我们的句子长度为3,所以代入后可得维度为 [ 3 × 64 ] [3×64] [3×64]

目前,我们学习了如何计算查询矩阵 Q Q Q、键矩阵 K K K和值矩阵 V V V,并知道它们是基于输入矩阵 X X X计算而来的。要计算一个词的特征值,自注意力机制会使该词与给定句子中的所有词联系起来。还是以“I am good.”这句话为例。为了计算单词“I”的特征值,我们将单词I与句子中的所有单词一一关联,如下图所示。
自注意力的示例
了解一个词与句子中所有词的相关程度有助于更精确地计算特征值。自注意力机制利用查询矩阵 Q Q Q、键矩阵 K K K和值矩阵 V V V将一个词与句子中的所有词联系起来,其一共包括4个步骤:

  1. 自注意力机制首先要计算查询矩阵 Q Q Q与键矩阵 K T K^T KT的点积。首先,来看 Q K T QK^T QKT矩阵的第一行,这一行计算的是查询向量 Q 1 , : Q_{1, :} Q1,:(I)与所有的键向量 K 1 , : K_{1, :} K1,:(I)、 K 2 , : K_{2, :} K2,:(am)和 K 3 , : K_{3, :} K3,:(good)的点积。通过计算两个向量的点积可以知道它们之间的相似度。因此,通过计算查询向量 Q 1 , : Q_{1, :} Q1,:和键向量 K 1 , : K_{1, :} K1,: K 2 , : K_{2, :} K2,: K 3 , : K_{3, :} K3,:的点积,可以了解单词“I”与句子中的所有单词的相似度。我们了解到,“I”这个词与自己的关系比与“am”和“good”这两个词的关系更紧密,因为点积值 Q 1 , : K 1 , : Q_{1, :}K_{1, :} Q1,:K1,:大于 Q 1 , : K 2 , : Q_{1, :}K_{2, :} Q1,:K2,: Q 1 , : K 3 , : Q_{1, :}K_{3, :} Q1,:K3,:。现在来看[插图]矩阵的第二行。现在需要计算查询向量 Q 2 , : Q_{2, :} Q2,:(am)与所有的键向量 K 1 , : K_{1, :} K1,:(I)、 K 2 , : K_{2, :} K2,:(am)和 K 3 , : K_{3, :} K3,:(good)的点积。这样一来,我们就可以知道“am”与句中所有词的相似度。通过查看 Q K T QK^T QKT矩阵的第二行可以知道,单词“am”与自己的关系最为密切,因为点积值最大。同理,来看 Q K T QK^T QKT矩阵的第三行。计算查询向量 Q 3 , : Q_{3, :} Q3,:(good)与所有键向量 K 1 , : K_{1, :} K1,:(I)、 K 2 , : K_{2, :} K2,:(am)和 K 3 , : K_{3, :} K3,:(good)的点积。从结果可知,“good”与自己的关系更密切,因为点积值 Q 3 , : K 3 , : Q_{3, :}K_{3, :} Q3,:K3,:大于 Q 3 , : K 1 , : Q_{3, :}K_{1, :} Q3,:K1,: Q 3 , : K 2 , : Q_{3, :}K_{2, :} Q3,:K2,:。综上所述,计算查询矩阵 Q Q Q与键矩阵 K T K^T KT的点积,从而得到相似度分数。这有助于我们了解句子中每个词与所有其他词的相似度。
    自注意力机制的第一步
  2. Q K T QK^T QKT矩阵除以键向量维度的平方根。这样做的目的主要是获得稳定的梯度。我们用 d k d_k dk来表示键向量维度。然后,将 Q K T QK^T QKT除以 d k \sqrt{d_k} dk 。在上面的例子中,键向量维度是64,即平方根为8。将第上一步中算出的 Q K T QK^T QKT除以8。
    除以键向量维度的平方根
  3. 目前所得的相似度分数尚未被归一化,我们需要使用Softmax函数对其进行归一化处理。如下图所示,应用Softmax函数将使数值分布在0到1的范围内,且每一行的所有数之和等于1。我们将下图中的矩阵称为分数矩阵。通过这些分数,我们可以了解句子中的每个词与所有词的相关程度。以下图的分数矩阵的第一行为例,它告诉我们,“I”这个词与它本身的相关程度是90%,与“am”这个词的相关程度是7%,与“good”这个词的相关程度是3%。
    分数矩阵
  4. 至此,我们计算了查询矩阵与键矩阵的点积,得到了分数,然后用Softmax函数将分数归一化。自注意力机制的最后一步是计算注意力矩阵 Z Z Z。注意力矩阵包含句子中每个单词的注意力值。它可以通过将分数矩阵 Softmax ( Q K T d k ) \text{Softmax}(\frac{QK^T}{\sqrt{d_k}}) Softmax(dk QKT)乘以值矩阵 V V V得出,如下图所示。由下图可以看出,注意力矩阵 Z = [ Z 1 , Z 2 . Z 3 ] T Z=[Z_1, Z_2. Z_3]^T Z=[Z1,Z2.Z3]T就是值向量与分数加权之后求和所得到的结果。让我们逐行理解这个计算过程。首先,第一行 Z 1 , : Z_{1, :} Z1,:对应“I”这个词的自注意力值,它通过 Z 1 , : = 0.90 × V 1 , : + 0.07 × V 2 , : + 0.03 × V 3 , : Z_{1, :}=0.90\times V_{1, :} +0.07\times V_{2, :} +0.03\times V_{3, :} Z1,:=0.90×V1,:+0.07×V2,:+0.03×V3,:的方法计算所得。单词“I”的自注意力值 Z 1 Z_1 Z1是分数加权的值向量之和。所以, Z 1 Z_1 Z1的值将包含90%的值向量 V 1 , : V_{1, :} V1,:(I)、7%的值向量 V 2 , : V_{2, :} V2,:(am),以及3%的值向量 V 3 , : V_{3, :} V3,:(good)。
    计算注意力矩阵

让我们回过头去看之前的例句:“A dog ate the food because it was hungry.”。在这里,“it”这个词表示“dog”。我们将按照前面的步骤来计算“it”这个词的自注意力值。假设计算过程为: Z it = 0.00 × V A + 0.98 × V dog + 0.00 × V ate + 0.00 × V the + 0.02 × V food + ⋯ + 0.00 × V hungry Z_{\text{it}}=0.00\times V_{\text{A}} + 0.98\times V_{\text{dog}} + 0.00\times V_{\text{ate}} + 0.00\times V_{\text{the}} + 0.02\times V_{\text{food}} + \cdots + 0.00\times V_{\text{hungry}} Zit=0.00×VA+0.98×Vdog+0.00×Vate+0.00×Vthe+0.02×Vfood++0.00×Vhungry,我们可以看出,单次“it”的自注意力值包含98%的值向量 V dog V_{\text{dog}} Vdog,而只包含2%的值向量 V food V_{\text{food}} Vfood。这有助于模型理解“it”这个词实际上指的是“dog”而不是“food”。这也再次说明,通过自注意力机制,我们可以了解一个词与句子中所有词的相关程度。

综上所述,注意力矩阵[插图]由句子中所有单词的自注意力值组成,它的计算公式如下:
Z = Softmax ( Q K T d k ) V Z=\text{Softmax}(\frac{QK^T}{\sqrt{d_k}})V Z=Softmax(dk QKT)V

现将自注意力机制的计算步骤总结如下:

  1. 计算查询矩阵与键矩阵的点积 Q K T QK^T QKT,求得相似值,称为相似度分数
  2. Q K T QK^T QKT除以键向量维度的平方根 d k \sqrt{d_k} dk
  3. 用Softmax函数对分数进行归一化处理,得到分数矩阵 Softmax ( Q K T d k ) \text{Softmax}(\frac{QK^T}{\sqrt{d_k}}) Softmax(dk QKT)
  4. 通过将分数矩阵与值矩阵 V V V相乘,计算出注意力矩阵 Z Z Z

自注意力机制计算步骤

自注意力机制也被称为缩放点积注意力机制,这是因为其计算过程是先求查询矩阵与键矩阵的点积,再用 d k \sqrt{d_k} dk 对结果进行缩放。

参考文献:
[1] Lecun Y, Bengio Y, Hinton G. Deep learning[J]. Nature, 2015
[2] Aston Zhang, Zack C. Lipton, Mu Li, Alex J. Smola. Dive Into Deep Learning[J]. arXiv preprint arXiv:2106.11342, 2021.
[3] Sudharsan Ravichandiran. BERT基础教程:Transformer大模型实战[M]. 人民邮电出版社, 2023

猜你喜欢

转载自blog.csdn.net/hy592070616/article/details/131135690