NLP中的Attention机制
一 Attention机制
1 Why Attention
- 计算能力的限制:当要记住很多“信息“,模型就要变得更复杂,计算能力是瓶颈。
- 优化算法的限制:RNN中的长距离依赖问题,信息“记忆”能力并不高。
2 Attention理解
Attention机制的实质其实就是一个寻址(addressing)的过程,如上图所示:给定一个和任务相关的查询Query向量 q,通过计算与Key的注意力分布并附加在Value上,从而得到Attention Value,这个过程实际上是Attention机制缓解神经网络模型复杂度的体现:不需要将所有的N个输入信息都输入到神经网络进行计算,只需要从X中选择一些和任务相关的信息输入给神经网络。
更好的理解1:在Youtube上搜索某些视频
- Query:要查询的视频
- Key:数据库中与候选视频相关的一组键(视频标题,说明等)
- Value:数据库中的候选视频
更好的理解2:
- Query:搜索词
- Key:句子中的所有词(包括query,去和query匹配搜寻相关度,故q*k可以决定在句子每个单词上投入多少注意力)
- Value:句子中每个词自身的价值value,将求得的注意力得分与v相乘得到最终每个单词的得分。、
更好的理解3:
图书管(source)里有很多书(value),为了方便查找,我们给书做了编号(key)。当我们想要了解漫威(query)的时候,我们就可以看看那些动漫、电影、甚至二战相关的书籍。
为了提高效率,并不是所有的书都会仔细看,针对漫威来说,动漫,电影相关的会看的仔细一些(权重高),但是二战的就只需要简单扫一下即可(权重低)。当我们全部看完后就对漫威有一个全面的了解了。
二 Attention分类
1 soft Attention
(1)普通模式 (Key=Value=X)
计算步骤:
-
信息输入:用 X = [ x 1 , ⋅ ⋅ ⋅ , x N ] X=[x_1, · · · ,x_N ] X=[x1,⋅⋅⋅,xN]表示N个输入信息;
-
注意力分布计算:
由于
α i = softmax ( s ( k e y i , q ) ) = softmax ( s ( X i , q ) ) \alpha_{i}=\operatorname{softmax}\left(s\left(k e y_{i}, q\right)\right)=\operatorname{softmax}\left(s\left(X_{i}, q\right)\right) αi=softmax(s(keyi,q))=softmax(s(Xi,q))
将 α i \alpha_i αi称之为注意力分布(概率分布), s ( X i , q ) s(X_i,q) s(Xi,q)为注意力打分机制,有几种打分机制: -
信息加权平均:注意力分布 α i \alpha_i αi表示在给定查询 q q q时,输入信息向量 X X X中第 i i i个信息与查询 q q q的相关程度。采用“软性”信息选择机制给出查询所得的结果,就是用加权平均的方式对输入信息进行汇总,得到Attention值:
att ( X , q ) = ∑ i = 1 N α i x i \operatorname{att}(X,q)=\sum_{i=1}^{N} \alpha_{i} x_{i} att(X,q)=i=1∑Nαixi
(2)键值对模式 (Key!=Value)
计算步骤:
-
信息输入:用键值对(key-value pair)来表示输入信息,那么N个输入信息就可以表示为 ( K , V ) = [ ( k 1 , v 1 ) , ( k 2 , v 2 ) , . . . , ( k N , v N ) ] (K,V)= [(k_1,v_1),(k_2,v_2),...,(k_N,v_N)] (K,V)=[(k1,v1),(k2,v2),...,(kN,vN)],其中"Key"用来计算注意分布 α i \alpha_i αi,"Value"用来计算聚合信息。
-
注意力分布计算:
α i = softmax ( s ( k e y i , q ) ) \alpha_{i}=\operatorname{softmax}\left(s\left(k e y_{i}, q\right)\right) αi=softmax(s(keyi,q))
-
信息加权平均:
相比普通模式,注意力函数变为:
att ( ( K , V ) , q ) = ∑ i = 1 N α i v i \operatorname{att}((K,V), q)=\sum_{i=1}^{N} \alpha_{i} v_{i} att((K,V),q)=i=1∑Nαivi
注意:在NLP中,Key和Value常常都是同一个,即Key = Value。
2 hard Attention
区别:
-
软性注意力,其选择的信息是所有输入信息在注意力分布下的期望。
-
硬性注意力,只关注到某一个位置上的信息
硬性注意力有两种实现方式:
- 选取最高概率的输入信息
- 通过在注意力分布式上随机采样的方式实现。
hard Attention缺点:
基于最大采样或随机采样的方式来选择信息。因此最终的损失函数与注意力分布之间的函数关系不可导,因此无法使用在反向传播算法进行训练。为了使用反向传播算法,一般使用soft Attention来代替hard Attention。
3 self-Attention
问题:CNN或RNN不能处理序列之间的长距离依赖关系
当使用神经网络来处理一个变长的向量序列时,我们通常可以使用CNN或RNN进行编码来得到一个相同长度的输出向量序列,如图所示:
从上图可以看出,无论CNN或RNN其实都是对变长序列的一种“局部编码”:CNN显然是基于N-gram的局部编码;而对于RNN,由于梯度消失等问题也只能建立短距离依赖。
解决方法:
- 增加网络的层数,通过一个深层网络来获取远距离的信息交互。
- 使用全连接网络。
计算步骤:
输入序列:
X
=
[
x
1
,
⋅
⋅
⋅
,
x
N
]
X=[x_1, · · · ,x_N ]
X=[x1,⋅⋅⋅,xN]
输出序列:
H
=
[
h
1
,
⋅
⋅
⋅
,
h
N
]
H=[h_1, · · · ,h_N ]
H=[h1,⋅⋅⋅,hN]
-
信息输入:用 X = [ x 1 , ⋅ ⋅ ⋅ , x N ] X=[x_1, · · · ,x_N ] X=[x1,⋅⋅⋅,xN]表示N 个输入信息;通过线性变换得到
(1)查询向量序列: Q = W Q X Q=W_QX Q=WQX
(2)键向量序列: K = W K X K=W_KX K=WKX
(3)值向量序列: V = W V X V=W_VX V=WVX
其中 W Q , W K , W V W_Q,W_K,W_V WQ,WK,WV,分别为可学习的参数矩阵。上面的公式可以看出,self-Attention中的Q是对自身(self)输入的变换,而在传统的Attention中,Q来自于外部。
-
计算输出向量 h i h_i hi:
h i = att ( ( K , V ) , q i ) = ∑ j = 1 N α i j v j = ∑ j = 1 N softmax ( s ( k j , q i ) ) v j \begin{aligned} \mathbf{h}_{i} &=\operatorname{att}\left((K, V), \mathbf{q}_{i}\right) \\ &=\sum_{j=1}^{N} \alpha_{i j} \mathbf{v}_{j} \\ &=\sum_{j=1}^{N} \operatorname{softmax}\left(s\left(\mathbf{k}_{j}, \mathbf{q}_{i}\right)\right) \mathbf{v}_{j} \end{aligned} hi=att((K,V),qi)=j=1∑Nαijvj=j=1∑Nsoftmax(s(kj,qi))vj
其中 i , j ∈ [ 1 , N ] i, j ∈ [1, N] i,j∈[1,N]为输出和输入向量序列的位置,连接权重 α i j \alpha_{ij} αij由注意力机制动态生成。自注意力模型中,通常使用缩放点积来作为注意力打分函数,输出向量序列可以写为:
H = V softmax ( K T Q d k ) H=V \operatorname{softmax}\left(\frac{K^TQ}{\sqrt{d_k}}\right) H=Vsoftmax(dkKTQ)
拆解:
为每个向量计算自注意力得分,分数决定当我们在某个位置对单词进行编码时,要在输入句子的其他部分上投入多少注意力: s c o r e = q ⋅ k score=q\cdot k score=q⋅k
为了梯度的稳定,对计算的分数进行 Scale,即除以 d k \sqrt{d_k} dk ,原因是如果点乘结果过大,使得经过softmax之后的梯度很小,不利于反向传播
对score施以softmax激活函数,归一化,即 s o f t m a x ( q ⋅ k d k ) softmax(\frac{q\cdot k}{\sqrt{d_k}}) softmax(dkq⋅k);
softmax乘Value值 v v v,得到加权的每个输入向量的评分 v ⋅ s o f t m a x ( q ⋅ k d k ) v \cdot softmax(\frac{q\cdot k}{\sqrt{d_k}}) v⋅softmax(dkq⋅k) ;
相加之后得到最终的输出结果: z = ∑ v ⋅ s o f t m a x ( q ⋅ k d k ) z= \sum v \cdot softmax(\frac{q\cdot k}{\sqrt{d_k}}) z=∑v⋅softmax(dkq⋅k) 。
使用矩阵形式表示:
4 multi-head attention
结构如下:
利用多个查询
Q
=
[
q
1
,
⋅
⋅
⋅
,
q
M
]
Q = [q_1, · · · , q_M]
Q=[q1,⋅⋅⋅,qM],来平行地计算从输入信息中选取多个信息。每个注意力关注输入信息的不同部分,然后再进行拼接:
att
(
(
K
,
V
)
,
Q
)
=
att
(
(
K
,
V
)
,
q
1
)
⊕
⋯
⊕
att
(
(
K
,
V
)
,
q
M
)
\operatorname{att}((K, V), Q)=\operatorname{att}\left((K, V), \mathbf{q}_{1}\right) \oplus \cdots \oplus \operatorname{att}\left((K, V), \mathbf{q}_{M}\right)
att((K,V),Q)=att((K,V),q1)⊕⋯⊕att((K,V),qM)
“多头”注意力的机制通过两种方式提高attention layer的性能:
- 它扩展了模型专注于不同位置的能力。
- 它为attention layer提供了多个“表示子空间”。
我们重复8次相似的操作,得到8个 Z i Z_i Zi矩阵:
前馈层不期望有八个矩阵–它期望一个矩阵(每个单词一个向量)。因此,我们需要一种将这八个压缩为单个矩阵的方法,即合并矩阵并乘以一个线性 W 0 W_0 W0,得到最终的 Z Z Z:
在示例句中对单词“ it”进行编码时,不同的注意头所关注的位置: