注意力机制
开始我们先想一个问题:假设我要找工作,我怎么才能知道我在一个公司可能拿到多少工资呢?
将全公司所有人的工资进行平均?这显然不合理吧。
一个合理的想法是找到这个公司和我相同或类似岗位且与我教育经历、工作经验相似的人的工资做平均,这样的到平均显然就更接我可能拿到的工资。
其中:已知公司每个员工岗位经历等以及对应工资分别是Key和Value(K_i, V_i)
而我就是Query(Q),最后想要得到的工资就是求的Value
注意力机制的目的就是找到一个函数F[Q, (K_i, V_i)]通过Query找到相似的Key, 并根据与每个Key的相似度赋予不同的权重Weight, 通过这个权重Weight与对应Value求出目标Query的价值Value。
这个寻找Query相似的Key的 限制条件(相似度判别方法) 就是注意力。
Attention机制:神经网络接收的输入是很多大小不一的向量,并且不同向量向量之间有一定的关系,但是实际训练的时候无法充分发挥这些输入之间的关系而导致模型训练结果效果极差。注意力机制迫使模型在解码时学会将注意力集中在输入序列的特定部分,而不是仅仅依赖于decoder的输入。
定义:从大量输入信息里面选择小部分的有用信息来重点处理,并忽略其他信息,这种能力就叫做注意力(Attention)
计算:
- 输入Query、Key、Value;
- 根据Query和Key计算两者之间的相关性/相似性(常见方法点乘、余弦相似度,一般用点乘),得到注意力得分;
- 对注意力得分进行缩放scale(除以维度的根号),再softmax归一化,再得到权重系数;
- 根据权重系数对Value值进行加权求和,得到Attention Value(此时的V是具有一些注意力信息的,更重要的信息更关注,不重要的信息被忽视了);
f
(
q
,
(
k
1
,
v
1
)
,
…
,
(
k
m
,
v
m
)
)
=
∑
i
=
1
m
α
(
q
,
k
i
)
v
i
∈
R
v
f\left(\mathbf{q},\left(\mathbf{k}_{1}, \mathbf{v}_{1}\right), \ldots,\left(\mathbf{k}_{m}, \mathbf{v}_{m}\right)\right)=\sum_{i=1}^{m} \alpha\left(\mathbf{q}, \mathbf{k}_{i}\right) \mathbf{v}_{i} \in \mathbb{R}^{v}
f(q,(k1,v1),…,(km,vm))=i=1∑mα(q,ki)vi∈Rv
α
(
q
,
k
i
)
=
softmax
(
a
(
q
,
k
i
)
)
=
exp
(
a
(
q
,
k
i
)
)
∑
j
=
1
m
exp
(
a
(
q
,
k
j
)
)
∈
R
.
\alpha\left(\mathbf{q}, \mathbf{k}_{i}\right)=\operatorname{softmax}\left(a\left(\mathbf{q}, \mathbf{k}_{i}\right)\right)=\frac{\exp \left(a\left(\mathbf{q}, \mathbf{k}_{i}\right)\right)}{\sum_{j=1}^{m} \exp \left(a\left(\mathbf{q}, \mathbf{k}_{j}\right)\right)} \in \mathbb{R} .
α(q,ki)=softmax(a(q,ki))=∑j=1mexp(a(q,kj))exp(a(q,ki))∈R.
正如上图所示,选择不同的注意力评分函数a
会导致不同的注意力汇聚操作。
一些需要注意的点:
- 为什么softmax前要缩放?为什么是除以维度的根号?
- 缩放是因为softmax归一化是有问题的,当缩放前的某个元素非常大的时候,softmax会把大部分的概率分给这个大的元素,这就会产生一个类似one-hot的向量,softmax反向传播会导致梯度消失。所以在softmax前缩放,缓解这种问题。
- 除以维度的根号因为我们希望输入softmax的数据是均值为0,方差为1。
- 一般K和V是相同的,或者是存在一定的联系的。
- 新的向量Attention Value表示了Key 和Value(Key 一般和Value相同),而且Attention Value还暗含了Q的信息。总结下:通过查询遍历Key找出Key里面的关键点,然后再和Value组合成一个新的向量去表示Key。
- 为什么不能用Key和Key自乘得到相似度,而要新建一个Q?
- 如果Key自乘得到相似度,这个时候得到的其实是一个对称矩阵,相当于把Key投影到同一个空间中,泛化能力弱。
自注意力机制
从上面注意力机制可以看出,其中的Key和Query没有本质区别,只是一个是已知的、一个是未知的。自注意力机制就是Query、Key、Value全部来自已知的X序列中,通过类似做完形填空的方式自主学习找到每个X_i与其他X_k(k ≠ i)之间的关系。
Attention和Self-Attention的区别:
- Attention中K和V往往是同源的(也可以不同源),而Q没有任何要求,所以attention其实是一个很宽泛的概念,没有规定Q、K、V是怎么来的,只要满足QKV相乘计算相似度这种流程的都是注意力机制(所以才有通道注意力机制、空间注意力机制);
- Self-Attention属于Attention,要求QKV必须同源,依然代表X,本质上可以看作是相等的,只是对同一个词向量X乘上了参数矩阵,作了空间上的变换;
计算:
- 通过共享参数W_Q、W_K、W_V 和X运算得到Q、K、V;
- 接下来和注意力机制一模一样;
Z本质上还是X向量,只不过包含了一些新的信息:包含X中每个向量和所有向量之间的相似度,让x1/x2…去关注更重要的词向量
位置编码
位置编码
为什么需要位置编码?
self-attention是并行就意味着它是可以同时计算每个位置和其他位置的相关性的,也就是说词与词之间是不存在顺序关系的。所以如果打乱一句话,那么这句话里的词向量依然不变,即无位置关系。
总结:self-attention不像RNN那样有先后顺序,可以找到每个序列的位置,self-attention只是负责计算每个位置和其他位置的相关性。为了解决这个问题,就提出了位置编码。
怎么做位置编码?
- 对词向量进行编码生成embedding x1(shape1);
- 生成相应的位置编码 positional emcoding t1(shape1),如上t1包含x1和x2,x1和x3的位置关系;
- 两者相加add(embedding +positional emcoding),生成最终的输入特征 Embedding with time signal(shape1);
位置编码的生成方式
1、正余弦生成
P
E
(
p
o
s
,
2
i
)
=
sin
(
p
o
s
/
1000
0
2
i
/
d
)
P
E
(
p
o
s
,
2
i
+
1
)
=
cos
(
p
o
s
/
1000
0
2
i
/
d
)
\begin{array}{c} P E_{(p o s, 2 i)}=\sin \left(p o s / 10000^{2 i / d}\right) \\ P E_{(p o s, 2 i+1)}=\cos \left(p o s / 10000^{2 i / d}\right) \end{array}
PE(pos,2i)=sin(pos/100002i/d)PE(pos,2i+1)=cos(pos/100002i/d)
借助上面的公式,我们可以得到一个特定位置的
d
m
o
d
e
l
d_{model}
dmodel 维的位置向量,并且借助三角函数的性质
{
sin
(
α
+
β
)
=
sin
α
cos
β
+
cos
α
sin
β
cos
(
α
+
β
)
=
cos
α
cos
β
−
sin
α
sin
β
\left\{\begin{array}{l} \sin (\alpha+\beta)=\sin \alpha \cos \beta+\cos \alpha \sin \beta \\ \cos (\alpha+\beta)=\cos \alpha \cos \beta-\sin \alpha \sin \beta \end{array}\right.
{sin(α+β)=sinαcosβ+cosαsinβcos(α+β)=cosαcosβ−sinαsinβ
我们可以得到:
{
P
E
(
pos
+
k
,
2
i
)
=
P
E
(
pos
,
2
i
)
×
P
E
(
k
,
2
i
+
1
)
+
P
E
(
pos
,
2
i
+
1
)
×
P
E
(
k
,
2
i
)
P
E
(
pos
+
k
,
2
i
+
1
)
=
P
E
(
pos
,
2
i
+
1
)
×
P
E
(
k
,
2
i
+
1
)
−
P
E
(
pos
,
2
i
)
×
P
E
(
k
,
2
i
)
\left\{\begin{array}{l} P E(\text { pos }+k, 2 i)=P E(\text { pos }, 2 i) \times P E(k, 2 i+1)+P E(\text { pos }, 2 i+1) \times P E(k, 2 i) \\ P E(\text { pos }+k, 2 i+1)=P E(\text { pos }, 2 i+1) \times P E(k, 2 i+1)-P E(\text { pos }, 2 i) \times P E(k, 2 i) \end{array}\right.
{PE( pos +k,2i)=PE( pos ,2i)×PE(k,2i+1)+PE( pos ,2i+1)×PE(k,2i)PE( pos +k,2i+1)=PE( pos ,2i+1)×PE(k,2i+1)−PE( pos ,2i)×PE(k,2i)
可以看出,对于
p
o
s
+
k
pos+k
pos+k位置的向量某一维
2
i
2i
2i或
2
i
+
1
2i+1
2i+1而言,可以表示为
p
o
s
pos
pos位置与
k
k
k位置的位置向量的
2
i
2i
2i与
2
i
+
1
2i+1
2i+1维的线性组合,这样的线性组合意味着位置向量中蕴含着相对位置信息。
前面我们知道位置编码其实就是让t1知道x1和x2,x1和x3的位置关系。从公式角度理解为什么?
sin(pos+k) = sin(pos)*cos(k) + cos(pos)*sin(k)
cos(pos+k) = cos(pos)*cos(k) - sin(pos)*sin(k)
这个公式告诉我们:位置
p
o
s
+
k
pos + k
pos+k 是 位置
p
o
s
pos
pos 和 位置
k
k
k 的线性组合
即当我知道 位置
p
o
s
+
k
pos+k
pos+k 那内部就会暗含 位置
p
o
s
pos
pos 和 位置
k
k
k 的信息
所以,此时即使打乱了词的位置关系,位置编码也会发生改变 这就解决了transformer的问题
2、自学习生成
这种方式比较简单,就直接随机初始化和x1一样shape的随机变量,然后训练网络的时候自动学习即可。
多头注意力机制
Multi-Head Self-Attention得到的新的词向量可以比Self-Attention得到的词向量有进一步提升。
什么是多头?(一般是使用8头)
理论做法:
- 输入X;
- 对应8个single head,对应8组W_Q、W_K、W_V再分别进行self-attention,得到Z_0 - Z_7;
- 再把Z_0 - Z_7拼接concat起来;
- 再做一次线性变换(降维)得到 Z;
源码:
- 输入X;
- 根据W_Q、W_K、W_V,生成Q、K、V;
- 再把Q拆分成q_1 - q_7,K拆分成k_1 - k_7,V拆分成v_1 - v_7;
- head_0 - head_7分别在qkv_1 - qkv_7上做自注意力机制
- 再把z_0 - z_7拼接concat起来;
- 再做一次线性变换(降维)得到 Z;
为什么多头?有什么作用?
机器学习的本质:
y
=
σ
(
w
x
+
b
)
y=σ(wx+b)
y=σ(wx+b),其实就是在做非线性变换。把数据x(它是不合理的),通过非线性变换,变成数据y(合理)。
非线性变换的本质:空间变换,改变空间上的位置坐标。
self-attention本质,通过非线性变换,把原始数据空间上的X点位置映射到新空间上的点Z上。
muti-head self-attention:把输入数据X,再把X通过非线性变换,映射到8个不同的子空间上,然后通过这8个不同的子空间去找最终的新空间上的点Z。这样可以捕捉更加丰富的特征信息,效果更好。
简单来说就是可以通过更多不同的维度观察Query与Key之间的联系,更好的计算Q与K的权重。
- 注意力机制 & 自注意力模型
- 【Transformer 相关理论深入理解】注意力机制、自注意力机制、多头注意力机制、位置编码
- 自注意力机制(Self-Attention)
- 详解自注意力机制中的位置编码(第一部分
- Transformer模型详解(图解最完整版)
- 【Transformer专题】一、Attention is All You Need(Transformer入门)
- Embedding层的作用
- EMBEDDING层作用
- 注意力机制
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)