分类目录:《深入理解深度学习》总目录
相关文章:
·注意力机制(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)
xi∈Rd(1≤i≤n)。该序列的自注意力输出为一个长度相同的序列
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个步骤:
- 自注意力机制首先要计算查询矩阵
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的点积,从而得到相似度分数。这有助于我们了解句子中每个词与所有其他词的相似度。
- 将
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。
- 目前所得的相似度分数尚未被归一化,我们需要使用Softmax函数对其进行归一化处理。如下图所示,应用Softmax函数将使数值分布在0到1的范围内,且每一行的所有数之和等于1。我们将下图中的矩阵称为分数矩阵。通过这些分数,我们可以了解句子中的每个词与所有词的相关程度。以下图的分数矩阵的第一行为例,它告诉我们,“I”这个词与它本身的相关程度是90%,与“am”这个词的相关程度是7%,与“good”这个词的相关程度是3%。
- 至此,我们计算了查询矩阵与键矩阵的点积,得到了分数,然后用Softmax函数将分数归一化。自注意力机制的最后一步是计算注意力矩阵
Z
Z
Z。注意力矩阵包含句子中每个单词的注意力值。它可以通过将分数矩阵
Softmax
(
Q
K
T
d
k
)
\text{Softmax}(\frac{QK^T}{\sqrt{d_k}})
Softmax(dkQKT)乘以值矩阵
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(dkQKT)V
现将自注意力机制的计算步骤总结如下:
- 计算查询矩阵与键矩阵的点积 Q K T QK^T QKT,求得相似值,称为相似度分数
- 将 Q K T QK^T QKT除以键向量维度的平方根 d k \sqrt{d_k} dk
- 用Softmax函数对分数进行归一化处理,得到分数矩阵 Softmax ( Q K T d k ) \text{Softmax}(\frac{QK^T}{\sqrt{d_k}}) Softmax(dkQKT)
- 通过将分数矩阵与值矩阵 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