深度学习:自注意力机制(Self-attention)详解
自注意力机制(Self-attention)详解
自注意力机制(Self-attention)是一种用于神经网络中的机制,能够动态地捕捉序列中不同位置元素之间的依赖关系,并根据这些依赖关系生成新的序列表示。它特别适用于处理序列数据(如文本、时间序列、语音信号等),目前在自然语言处理、语音识别和计算机视觉等领域被广泛应用。
自注意力机制之所以被称为“自注意力”,是因为它在单一序列中通过计算序列元素之间的相互依赖关系来生成新的特征表示。这与传统的注意力机制(如用于机器翻译中,编码器与解码器之间的注意力机制)有所不同,后者通常涉及两个序列之间的交互。
自注意力机制的核心工作原理
自注意力机制可以分为以下几个步骤:
1. 查询、键、值向量的生成
对于序列中的每个输入向量(例如在文本处理中,一个词的嵌入表示),我们将其通过三个不同的权重矩阵 ( W q W^q Wq ), ( W k W^k Wk ) 和 ( W v W^v Wv ) 线性映射为查询向量(Query vector, ( q ))、键向量(Key vector, ( k ))和值向量(Value vector, ( v ))。这些向量可以描述为:
- 查询向量 ( $q_i = W^q x_i $)
- 键向量 ( $k_i = W^k x_i $)
- 值向量 ( v i = W v x i v_i = W^v x_i vi=Wvxi )
其中,( x i x_i xi ) 是输入序列的第 ( $i $) 个元素的嵌入表示。这三种向量分别用于不同的操作:
- 查询向量 ( q i q_i qi ) 用于与其他输入元素的键向量进行匹配,以确定该元素应该“关注”序列中的哪些部分。
- 键向量 ( k i k_i ki ) 用于与查询向量进行匹配,生成注意力得分。
- 值向量 ($ v_i$ ) 通过加权求和生成新的输出表示。
2. 注意力得分的计算
为了确定序列中每个元素之间的相关性,自注意力机制通过点积运算计算每个查询向量 ( $q_i $) 与所有其他元素的键向量 ( k j k_j kj ) 的相似度。相似度的计算方式为:
[
α
i
,
j
=
q
i
⋅
k
j
\alpha_{i,j} = q_i \cdot k_j
αi,j=qi⋅kj
]
即查询向量 ( $q_i $) 和键向量 ( k j k_j kj ) 的点积。这个点积结果 ($ \alpha_{i,j}$ ) 表示序列中的第 ($ i KaTeX parse error: Can't use function '\)' in math mode at position 1: \̲)̲ 个元素对第 \( j$ ) 个元素的关注程度(即相关性)。
3. 归一化:softmax
得到的点积得分 ( α i , j \alpha_{i,j} αi,j ) 并不是直接用于生成输出向量的,而是需要通过softmax函数进行归一化处理,以将它们转换为有效的概率分布:
[
α
^
i
,
j
=
exp
(
α
i
,
j
)
∑
j
=
1
n
exp
(
α
i
,
j
)
\hat{\alpha}_{i,j} = \frac{\exp(\alpha_{i,j})}{\sum_{j=1}^n \exp(\alpha_{i,j})}
α^i,j=∑j=1nexp(αi,j)exp(αi,j)
]
通过 softmax 函数,每个 ( α i , j \alpha_{i,j} αi,j ) 被转换成 ( $\hat{\alpha}_{i,j} $),表示第 ( $i $) 个元素对第 ( j j j ) 个元素的相对关注权重。这样,所有元素的关注权重和为 1。
4. 输出的加权求和
归一化后的注意力权重 ( α ^ i , j \hat{\alpha}_{i,j} α^i,j ) 决定了每个输入元素对输出的贡献大小。具体地,输出向量 ( b i b_i bi ) 是对所有值向量 ( v j v_j vj ) 进行加权求和:
[
b
i
=
∑
j
=
1
n
α
^
i
,
j
v
j
b_i = \sum_{j=1}^{n} \hat{\alpha}_{i,j} v_j
bi=∑j=1nα^i,jvj
]
这意味着,第 ($ i$ ) 个元素的输出向量 ($ b_i$ ) 是所有输入元素的值向量 ( $v_j $) 通过对应的注意力权重 ( $\hat{\alpha}_{i,j} $) 加权后得到的。因此,输出向量不仅包含了第 ( i i i ) 个元素本身的信息,还包含了其他相关元素的信息。
5. 缩放点积注意力
在计算点积时,如果查询向量和键向量的维度较大,点积的值可能会变得很大,这会导致 softmax 输出接近 0 或 1,使得梯度消失或过于集中。为了解决这个问题,Transformer 引入了缩放因子 ( 1 d k \frac{1}{\sqrt{d_k}} dk1 ) 来对点积进行缩放,公式变为:
[
α
i
,
j
=
q
i
⋅
k
j
d
k
\alpha_{i,j} = \frac{q_i \cdot k_j}{\sqrt{d_k}}
αi,j=dkqi⋅kj
]
其中 ( d_k ) 是键向量的维度。缩放因子的引入有助于防止在模型训练过程中出现梯度问题。
6. 多头注意力(Multi-head Attention)
在实际应用中,Transformer 引入了多头注意力机制。多头注意力的核心思想是通过多个不同的查询、键和值的线性变换来生成多组并行的注意力操作,进而捕捉序列中不同位置之间的多样化关系。具体过程如下:
- 将输入向量通过不同的权重矩阵 ( $W^q, W^k, W^v $) 线性变换为多组查询、键和值向量。
- 对每组查询、键和值向量分别计算自注意力输出。
- 将所有头部的输出连接起来,再通过一个线性层进行投影,得到最终的输出。
公式表示为:
[
MultiHead
(
Q
,
K
,
V
)
=
Concat
(
head
1
,
…
,
head
h
)
W
O
\text{MultiHead}(Q, K, V) = \text{Concat}(\text{head}_1, \dots, \text{head}_h)W^O
MultiHead(Q,K,V)=Concat(head1,…,headh)WO
]
其中,( head i = Attention ( Q W i Q , K W i K , V W i V ) \text{head}_i = \text{Attention}(QW_i^Q, KW_i^K, VW_i^V) headi=Attention(QWiQ,KWiK,VWiV) ),( $W_i^Q, W_i^K, W_i^V, W^O $) 是线性变换的权重矩阵。
多头注意力机制的优势在于它能够从不同的“视角”来捕捉输入序列中元素之间的不同关联,从而提高模型的表达能力。
自注意力的优势
- 并行化计算:与循环神经网络(RNN)不同,自注意力机制不依赖于顺序传递的隐藏状态,因此可以进行并行计算,极大提高了计算效率。
- 捕捉长距离依赖关系:自注意力机制能够轻松捕捉序列中任意位置元素之间的依赖关系,不管这些元素距离多远,这使得它特别适用于处理长序列。
- 灵活性强:自注意力机制能够动态地调整各个元素之间的关注权重,根据不同的上下文情况学习不同的依赖关系。
自注意力的局限性
- 计算复杂度高:由于自注意力需要计算每个元素与其他所有元素之间的依赖关系,因此其计算复杂度为 ($ O(n^2) $),当序列长度较长时,这会导致计算开销非常大。
- 无法显式捕捉位置信息:自注意力机制本身并不考虑输入序列的位置信息,因此需要引入**位置编码(Positional Encoding)**来为序列中的每个元素附加位置信息。
总结
自注意力机制通过查询、键和值向量的转换,能够有效捕捉序列中元素之间的依赖关系。它通过点积计算出元素之间的相似度,然后通过 softmax 归一化生成注意力权重,最终对值向量加权求和生成输出表示。自注意力机制在 Transformer 模型中得到了广泛应用,并通过多头注意力进一步增强了模型对序列关系的捕捉能力。