序列到序列模型中的注意力机制
Bahdanau 注意力机制(加性注意力)
在RNN中,我们通过隐藏状态 ( h 1 , h 2 , h 3 ) (h_1, h_2, h_3 ) (h1,h2,h3) 进行计算。每个隐藏状态 ( h i ) ( h_i ) (hi) 被一个权重 ( α t , i ) ( \alpha_{t,i} ) (αt,i) 加权,权重通过一个评分函数(score function)来分配,赋予更相似的词更大的权重。生成的新变量“上下文向量” ( c i ) ( c_i ) (ci) 用于计算解码器的隐藏状态 ( S t ) ( S_t ) (St)。
隐藏状态
计算公式:
- 评分函数:
s c o r e ( s t , h i ) = V α T ⋅ tanh ( W α [ s t ; h i ] ) score(s_t, h_i) = V_{\alpha}^T \cdot \tanh(W_{\alpha}[s_t; h_i]) score(st,hi)=VαT⋅tanh(Wα[st;hi])
在Bahdanau注意力机制中,使用tanh作为激活函数的原因主要是因为它提供了一个有界的输出,将加性评分函数的输出限制在-1到1之间。这种有界的输出有助于模型的数值稳定性,尤其是在早期的深度学习模型中,梯度爆炸和梯度消失是常见的问题。tanh激活函数的这一特性有助于缓解这些问题。此外,tanh函数是一个非线性激活函数,它可以增加模型的表达能力,允许网络学习到更加复杂的特征组合。 - 权重计算:
α t , i = a l i g n ( y t , x i ) = exp ( s c o r e ( s t − 1 , h i ) ) ∑ i ′ = 1 n exp ( s c o r e ( s t − 1 , h i ′ ) ) \alpha_{t,i}=align(y_t,x_i) = \frac{\exp(score(s_{t-1}, h_i))}{\sum_{i'=1}^{n} \exp(score(s_{t-1}, h_i'))} αt,i=align(yt,xi)=∑i′=1nexp(score(st−1,hi′))exp(score(st−1,hi)) - 上下文向量:
c i = ∑ i = 1 T α t , i ⋅ h i c_i = \sum_{i=1}^{T} \alpha_{t,i} \cdot h_i ci=i=1∑Tαt,i⋅hi
Bahdanau, Cho 和 Bengio (2014) 首次在神经机器翻译中使用了注意力机制,而 Luong, Pham 和 Manning (2015) 则进一步探索了不同的注意力机制及其在神经机器翻译中的影响。
尽管如此,tanh函数在注意力机制中的应用也有一些局限性。例如,它的输出范围虽然有界,但可能导致梯度消失问题,尤其是在深层网络中。这也是为什么在后续的研究中,其他的注意力机制,如缩放点积注意力(Scaled Dot-Product Attention),开始使用不同的激活函数或者没有激活函数,直接对查询和键的点积进行操作
Luong 注意力机制(缩放点积注意力)
Luong, Pham 和 Manning (2015) 没有使用双向编码器,因此他们简化了编码器的隐藏状态,只保留编码器和解码器顶层的隐藏状态。
全局注意力机制
Luong 版本的注意力机制最早使用的是全局注意力机制,即对整个句子中的所有隐藏状态进行加权求和。
局部注意力机制
改进后的局部注意力机制,只对一个窗口内的隐藏状态进行加权求和,该窗口由经验参数 ( D ) 控制。上下文向量是窗口内隐藏状态的加权平均值。
计算公式
-
评分函数(缩放点积注意力):
在Luong的注意力机制中,一个关键的创新是引入了缩放点积注意力。这种评分函数通过计算解码器隐藏状态 ( s_t ) 与编码器隐藏状态 ( h_i ) 之间的点积,并对其进行缩放,来衡量它们之间的相似性:
s c o r e ( s t , h i ) = s t ⋅ h i d k score(s_t, h_i) = \frac{s_t \cdot h_i}{\sqrt{d_k}} score(st,hi)=dkst⋅hi
其中, ( s t ) ( s_t ) (st) 是解码器在时间步 t 的隐藏状态, ( h i ) ( h_i ) (hi) 是编码器在时间步 i 的隐藏状态, ( d k ) ( d_k ) (dk) 是键的维度的平方根。这种缩放操作有助于防止点积结果过大,从而避免在训练过程中出现梯度消失的问题。 -
注意力权重:
使用 softmax 函数将评分转换为概率分布,即注意力权重:
α t , i = exp ( s c o r e ( s t , h i ) ) ∑ j = 1 n exp ( s c o r e ( s t , h j ) ) \alpha_{t, i} = \frac{\exp(score(s_t, h_i))}{\sum_{j=1}^{n} \exp(score(s_t, h_j))} αt,i=∑j=1nexp(score(st,hj))exp(score(st,hi))
其中, ( α t , i ) ( \alpha_{t, i} ) (αt,i) 表示在时间步 t 对编码器第 i 个隐藏状态的注意力权重。 -
上下文向量:
最后,上下文向量 ( c t ) ( c_t ) (ct) 是通过将编码器的隐藏状态与其对应的注意力权重相乘并求和得到的:
c t = ∑ i = 1 n α t , i h i c_t = \sum_{i=1}^{n} \alpha_{t, i} h_i ct=i=1∑nαt,ihi
这个上下文向量捕捉了输入序列中与当前解码步骤最相关的信息,并用于指导解码器生成下一个输出。属于全局注意力,同时可以对比一下局部注意力:局部注意力的上下文向量 ( c t ) ( c_t ) (ct) 计算如下:
c t = ∑ i = p t − D p t + D α t , i h i c_t = \sum_{i=p_t-D}^{p_t+D} \alpha_{t, i} h_i ct=i=pt−D∑pt+Dαt,ihi
其中 ( p t ) ( p_t ) (pt) 是由模型预测的对齐位置, ( D ) ( D ) (D) 是窗口大小,通常是一个预先设定的参数。注意力权重 ( α t , i ) ( \alpha_{t, i} ) (αt,i) 可能会通过一个高斯分布来加权,使得靠近 ( p t ) ( p_t ) (pt) 的隐藏状态有更高的权重。通过这种方式,Luong注意力机制允许模型在生成翻译的每一步时,都能够动态地关注输入序列中最相关的部分,从而提高了翻译的准确性和流畅性。
自注意力机制(Self-Attention)
自注意力机制通过比较查询(Query)、键(Key)和值(Value)之间的相似性来计算注意力分数。Vaswani 等人 (2017) 提出了这个机制,并应用在了Transformer架构中。
在实际应用中,查询可以理解为用户输入的内容,键是潜在的匹配项,而值是对应的输出内容。为了找到最佳匹配,查询需要计算与键的相似性。
注意力计算公式:
-
注意力得分:
Attention ( Q , K , V ) = softmax ( Q K T d k ) V \text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V Attention(Q,K,V)=softmax(dkQKT)V
其中, ( Q ) ( Q ) (Q)、 ( K ) ( K ) (K) 和 ( V ) ( V ) (V) 分别是查询、键和值矩阵, ( d k ) ( d_k ) (dk) 是键的维度。 -
计算查询(Q)和键(K)向量矩阵之间的相似度公式:
Similarity ( Q , K ) = Q K T scaling \text{Similarity }(Q, K) = \frac{QK^T}{\text{scaling}} Similarity (Q,K)=scalingQKT
位置编码(Positional Encoding)
与LSTM按顺序逐步输入嵌入不同,Transformer一次性处理所有的词嵌入。这提高了速度,但也失去了关于词序的信息。因此,位置编码帮助Transformer为每个词嵌入引入唯一的位置信息。
位置编码使用正弦和余弦函数定义,公式如下:
P E ( p o s , 2 i ) = sin ( p o s 1000 0 2 i / d m o d e l ) PE(pos, 2i) = \sin\left(\frac{pos}{10000^{2i/d_{model}}}\right) PE(pos,2i)=sin(100002i/dmodelpos)
P E ( p o s , 2 i + 1 ) = cos ( p o s 1000 0 2 i / d m o d e l ) PE(pos, 2i+1) = \cos\left(\frac{pos}{10000^{2i/d_{model}}}\right) PE(pos,2i+1)=cos(100002i/dmodelpos)
其中 ( p o s ) ( pos ) (pos) 是词在序列中的位置, ( i ) ( i ) (i) 是维度索引。
多头注意力机制(Multi-Head Attention)
多头注意力机制通过将查询、键和值进行多次线性变换,并分别计算注意力,从而获得不同的注意力分布。接下来,这些注意力结果被拼接并投影,最终得到多头注意力的输出。
计算流程:
- 将查询、键和值分别映射到多个不同的子空间:
Q i = W i Q ⋅ Q , K i = W i K ⋅ K , V i = W i V ⋅ V Q_i = W_i^Q \cdot Q,\ K_i = W_i^K \cdot K,\ V_i = W_i^V \cdot V Qi=WiQ⋅Q, Ki=WiK⋅K, Vi=WiV⋅V - 分别计算每个头的注意力:
Attention i = softmax ( Q i K i T d k ) V i \text{Attention}_i = \text{softmax}\left(\frac{Q_i K_i^T}{\sqrt{d_k}}\right)V_i Attentioni=softmax(dkQiKiT)Vi - 将所有头的结果拼接起来:
MultiHead ( Q , K , V ) = W O ⋅ Concat ( Attention 1 , Attention 2 , … , Attention h ) \text{MultiHead}(Q, K, V) = W^O \cdot \text{Concat}(\text{Attention}_1, \text{Attention}_2, \dots, \text{Attention}_h) MultiHead(Q,K,V)=WO⋅Concat(Attention1,Attention2,…,Attentionh)
Transformer架构
Transformer架构不使用循环神经网络或卷积神经网络,而是基于完全的注意力机制。其基本结构包括一个编码器和一个解码器。
编码器
编码器由6层相同的子层堆叠而成。每个子层包括一个多头自注意力机制和一个前馈神经网络,此外每层还使用残差连接和层归一化。
编码器的输出作为解码器的输入,从中提取句子的更高级信息。
计算公式:
每个子层的输出为:
LayerNorm ( x + Sublayer ( x ) ) \text{LayerNorm}(x + \text{Sublayer}(x)) LayerNorm(x+Sublayer(x))
其中, S u b l a y e r ( x ) Sublayer(x) Sublayer(x) 是子层本身的输出。
解码器
与编码器不同,解码器增加了一个“掩码多头注意力机制”(Masked Multi-Head Attention)。生成句子时,当前状态不能知道下一个词,因此对注意力矩阵应用掩码,防止模型看到未来的词。掩码通过将未来词的位置值设置为负无穷大(-inf)来实现,从而在softmax归一化时将其权重降到接近零。
总结
注意力机制的发展经历了几个关键阶段,每个阶段都有其独特的贡献。Bahdanau注意力机制是最早出现的,它首次在神经机器翻译中引入,允许模型根据输入序列中的每个词分配不同的重要性权重。这一机制极大地改善了长序列的翻译效果。随后,Luong注意力机制对其进行了简化和优化,引入了局部注意力的概念,通过只关注部分输入使计算更加高效。
之后,自注意力机制的出现进一步突破了局限,它不再局限于序列中的局部依赖,而是通过计算序列中所有词之间的关系,增强了模型对整体语义的理解能力。这个机制为后来的Transformer架构奠定了基础。特别是多头注意力机制的引入,使得模型能够从多个不同的角度去理解词与词之间的关系,大幅提升了模型的表达能力。与传统的循环神经网络相比,Transformer 通过完全基于注意力的机制,显著加快了训练速度并且提升了在自然语言处理任务中的表现。
每一个阶段的进步都为深度学习模型的性能提升奠定了基础,尤其在处理长序列、复杂关系和多维度信息时,注意力机制展现了强大的灵活性和高效性。
如果有帮助到你,能点个赞嘛!!谢谢!!!
目前在整理内容,尝试做自己的博客网站,敬请期待。