赞
踩
原论文地址:Attention Is All You Need
近年来,Transformer在CV领域很火,Transformer是2017年Google在Computation and Language上发表的,当时主要是针对自然语言处理领域提出的。
在《Attention Is All You Need]》中作者提出了Self-Attention的概念,然后在此基础上提出Multi-Head Attention,所以本文对Self-Attention以及Multi-Head Attention 等理论进行讲解。
为了便于理解,假设输入的序列长度为2,输入就两个节点 x 1 , x 2 x_1, x_2 x1,x2,然后通过Input Embedding也就是图中的 f ( x ) f(x) f(x) 将输入映射到 a 1 , a 2 a_1, a_2 a1,a2 。紧接着分别将 a 1 , a 2 a_1, a_2 a1,a2 分别通过三个变换矩阵 W q , W k , W v W_q, W_k, W_v Wq,Wk,Wv(这三个参数是可训练的,是共享的)得到对应的 q i , k i , v i q^i, k^i, v^i qi,ki,vi(这里在源码中是直接使用全连接层实现的,这里为了方便理解,忽略偏置参数 b)。
其中
后续 q 和 k 匹配的过程可以理解成计算两者的相关性,相关性越大对应 v(value) 的权重也就越大。
同理我们可以得到
(
k
1
k
2
)
\binom{k^1}{k^2}
(k2k1) 和
(
v
1
v
2
)
\binom{v^1}{v^2}
(v2v1),那么求得的
(
q
1
q
2
)
\binom{q^1}{q^2}
(q2q1)就是原论文中的
Q
Q
Q ,
(
k
1
k
2
)
\binom{k^1}{k^2}
(k2k1) 就是
K
K
K,
(
v
1
v
2
)
\binom{v^1}{v^2}
(v2v1) 就是
V
V
V。
接着先拿 q 1 q^1 q1 和每个 k k k 进行match,点乘操作,接着除以 d \sqrt{d} d 得到对应的权重 α,其中 d 代表向量 k i k^i ki 的维度。在本示例中等于2。
接着对每一行即
(
α
1
,
1
,
α
1
,
2
)
(\alpha_{1, 1}, \alpha_{1, 2})
(α1,1,α1,2) 和
(
α
2
,
1
,
α
2
,
2
)
(\alpha_{2, 1}, \alpha_{2, 2})
(α2,1,α2,2) 分别进行softmax处理得到
(
α
^
1
,
1
,
α
^
1
,
2
)
(\hat\alpha_{1, 1}, \hat\alpha_{1, 2})
(α^1,1,α^1,2) 和
(
α
^
2
,
1
,
α
^
2
,
2
)
(\hat\alpha_{2, 1}, \hat\alpha_{2, 2})
(α^2,1,α^2,2),这里的
α
^
\hat{\alpha}
α^ 相当于计算得到针对每个 v 的权重。
到这儿,我们就完成了 A t t e n t i o n ( Q , K , V ) {\rm Attention}(Q, K, V) Attention(Q,K,V) 公式中 s o f t m a x ( Q K T d k ) {\rm softmax}(\frac{QK^T}{\sqrt{d_k}}) softmax(dk QKT) 部分。
上面已经计算得到
α
^
\hat\alpha
α^,即针对每个 v 的权重,接着进行加权得到最终结果:
统一写成矩阵乘法形式:
到这,Self-Attention 的内容就讲完了。总结下来就是论文中的一个公式:
接下来是 Multi-Head Attention(多头注意力)模块,实际使用中基本使用的还是Multi-Head Attention模块。原论文中说使用多头注意力机制能够联合来自不同head部分学习到的信息:
其实只要懂了Self-Attention模块Multi-Head Attention模块就非常简单了。
比如下图中假设h = 2,然后
q
1
q^1
q1 拆分成
q
1
,
1
q^{1,1}
q1,1 和
q
1
,
2
q^{1,2}
q1,2 ,那么
q
1
,
1
q^{1,1}
q1,1 就属于head1,
q
1
,
2
q^{1,2}
q1,2 属于head2。
看到这里,可能会有疑问,论文中不是写的通过
W
i
Q
,
W
i
K
,
W
i
V
W^Q_i, W^K_i, W^V_i
WiQ,WiK,WiV 映射得到每个 head 的
Q
i
,
K
i
,
V
i
Q_i, K_i, V_i
Qi,Ki,Vi 吗?
二者其实是等价的,因为都是线性运算,把
W
W
W 设置为原来的h倍大小即可。即通过将
W
i
Q
,
W
i
K
,
W
i
V
W^Q_i, W^K_i, W^V_i
WiQ,WiK,WiV 设置成对应值来实现均分,比如下图中的
Q
Q
Q 通过
W
1
Q
W^Q_1
W1Q 就能得到均分后的
Q
1
Q_1
Q1。
接着将每个head得到的结果进行concat拼接,比如下图中 b 1 , 1 b_{1,1} b1,1( h e a d 1 head_1 head1 得到的 b 1 b_1 b1)和 b 1 , 2 b_{1,2} b1,2( h e a d 2 head_2 head2 得到的 b 1 b_1 b1)拼接在一起, b 2 , 1 b_{2,1} b2,1 ( h e a d 1 head_1 head1 得到的 b 2 b_2 b2) 和 b 2 , 2 b_{2,2} b2,2(head_2$ 得到的 b 2 b_2 b2) 拼接在一起。
接着将拼接后的结果通过
W
O
W^O
WO(可学习的参数)进行融合,如下图所示,融合后得到最终的结果
b
1
,
b
2
b_1, b_2
b1,b2。
到这儿,Multi-Head Attention 的内容就讲完了。总结下来就是论文中的两个公式:
原论文章节 3.2.2 中有说两者的计算量其实是差不多。
可以简单的尝试一下,这个Attention就是实现Multi-head Attention的方法,其中包括上面讲的所有步骤。
注:FLOPs 为每秒浮点运算次数,也就是所用的时间。
通过实验发现:
上述所讲的 Self-Attention 和 Multi-Head Attention 模块,在计算中是没有考虑到位置信息的。假设在Self-Attention模块中,输入
a
1
,
a
2
,
a
3
a_1, a_2, a_3
a1,a2,a3 得到
b
1
,
b
2
,
b
3
b_1, b_2, b_3
b1,b2,b3 。对于
a
1
a_1
a1而言,
a
2
a_2
a2 和
a
3
a_3
a3 离它都是一样近的而且没有先后顺序。
因此,为了引入位置信息,在原论文中引入了位置编码 positional encodings。
如下图所示,位置编码是直接加在输入的
a
=
{
a
1
,
.
.
.
,
a
n
}
a=\{a_1,...,a_n\}
a={a1,...,an} 中的,即
p
e
=
{
p
e
1
,
.
.
.
,
p
e
n
}
pe=\{pe_1,...,pe_n\}
pe={pe1,...,pen} 和
a
=
{
a
1
,
.
.
.
,
a
n
}
a=\{a_1,...,a_n\}
a={a1,...,an} 拥有相同的维度大小。
关于位置编码在原论文中有提出两种方案,
mask是Transformer中很重要的一个概念,mask操作的目的有两个:
让padding (不够长的补0) 部分不参与attention操作。(每个句子的序列长度不同)
在生成当前词语的概率分布时,让模型不会注意到这个词后面的部分,避免利用未来信息。
在自注意力机制中,每个位置都会与所有其他位置进行交互,因此为了避免模型在预测时利用未来信息,需要将未来位置的信息掩盖掉。在编码器中,需要将输入序列中不够长的部分进行mask,而在解码器中,还需要将当前位置之后的位置进行掩盖,以避免模型利用未来信息。掩盖的方式可以是将对应位置的注意力权重设置为0,或者将对应位置的输入向量设置为一个特殊的掩码向量。
这个很好理解,下面就是一个mask矩阵,这个mask矩阵表示的是这个句子只有两个单词,句子后两个词是padding的内容,所以全都是0(假设序列长度为4)。我们在进行attention时不应该将这里考虑进attention,当给mask矩阵为0的对应位置替换一个负很大的值后,相应attention的结果就会趋近为0。
这个稍微复杂一点,我们先看看对应的mask矩阵(下三角矩阵),与得到的权重矩阵
α
\alpha
α 点乘,进而可以屏蔽掉未来的位置。
【1】https://blog.csdn.net/qq_37541097/article/details/117691873
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。