Transformer/Attention
Self-Attention
本文主要关注attention部分,Attention is all you need 原文包括的positional encoding,layer normalization,和decoder未展开分析,有时间补上~
这三个attention block都是multi-head attention的形式,输入都是query Q 、key K 、value V 三个元素,只是 Q 、 K 、 V 的取值不同。
理解
以如下句子作为输入:
I like Natural Language Processing , a lot !
根据 Attention is all you need这篇文章,encoder需通过Scaled Dot-Product Attention mechanism(通过 query 和 key 的相似度来确定 value 的权重分布的方法)对每个单词都产生输出向量。下面以第一个单词"I"为例:
- query是token "I"的输入词向量表示;
- keys是其余所有token的输入词向量表示,也包含"I";
[like; Natural; Language; Processing; ,; a; lot; !]+[I]
- query和keys逐个做点乘,可以得到九个最初的scores(相似度);
- 将点乘结果乘以一个常数 1 d k \frac{1}{\sqrt{d_k}} dk1,(该缩放因子可以防止结果过大,使得结果经过softmax计算后落入饱和区间)后进行softmax,得到的结果即是每个词对于当前位置的词的相关性大小;
- 将输入的九个词向量表示以相关性为权重,求加权和后得到针对单词"I"的输出词向量表示z。
- 其余单词处理过程同理。
补充:计算query和某个key的score(相似度)常用方法有:
- 点乘: s ( q , k ) = q T k s(q, k)=q^Tk s(q,k)=qTk
- 矩阵相乘: s ( q , k ) = q T k s(q, k)=q^Tk s(q,k)=qTk
- cosine相似度: s ( q , k ) = q T k ∣ ∣ q ∣ ∣ ⋅ ∣ ∣ k ∣ ∣ s(q, k)=\frac{q^Tk}{||q||\cdot||k||} s(q,k)=∣∣q∣∣⋅∣∣k∣∣qTk
- concatenate(串联): s ( q , k ) = W [ q ; k ] s(q, k)=W[q; k] s(q,k)=W[q;k]
- MLP(多层感知机):引入MLP来拟合出一个相似度, s ( q , k ) = h T t a n h ( W [ q ; k ] + b ) s(q, k)=h^Ttanh(W [q; k]+b) s(q,k)=hTtanh(W[q;k]+b),其中h是模型参数
图示
如何获得Q, K, V并计算?
实际应用时,为提高计算速度,用embedding X与随机初始化的矩阵相乘,计算出Q,K,V矩阵,把矩阵Q, K相乘并乘以缩放因子后做softmax操作,最后乘上V矩阵。这种通过 query 和 key 的相似性程度来确定 value 的权重分布的方法被称为Scaled Dot-Product Attention mechanism。
Multi-Headed Attention
考虑到方差大的问题,将Node-level Attention延伸到Multihead Attention来解决这个问题。将不同head的结果concatenate到一起,能够使模型更容易考虑到输入数据的不同方面:
一次性初始化多组Q,K,V矩阵,然后对于生成的多个特征矩阵Z进行concatenate(串联)得到一个大矩阵,然后用一个随机初始化矩阵与该矩阵相乘,得到最终矩阵。
h
e
a
d
i
=
A
t
t
e
n
t
i
o
n
(
Q
W
i
Q
,
K
W
i
K
,
V
W
i
V
)
,
head_i=Attention(QW_i^Q, KW_i^K, VW_i^V),
headi=Attention(QWiQ,KWiK,VWiV),
W
i
Q
,
W
i
Q
,
W
i
Q
∈
R
d
m
o
d
e
l
∗
d
k
W_i^{Q}, W_i^Q, W_i^Q \in R^{d_{model}*d_k}
WiQ,WiQ,WiQ∈Rdmodel∗dk
M
u
l
t
i
H
e
a
d
(
Q
,
K
,
V
)
=
C
o
n
c
a
t
(
h
e
a
d
1
,
h
e
a
d
2
,
.
.
.
,
h
e
a
d
h
)
,
MultiHead(Q, K, V)=Concat(head_1, head_2, ..., head_h),
MultiHead(Q,K,V)=Concat(head1,head2,...,headh),
其中
d
k
=
d
m
o
d
e
l
h
d_k=\frac{d_{model}}{h}
dk=hdmodel
Mask
mask 表示掩码,它对某些值进行掩盖,使其在参数更新时不产生效果。Transformer 模型里面涉及两种 mask,分别是 padding mask 和 sequence mask。
其中,padding mask 在所有的 scaled dot-product attention 里面都需要用到,而 sequence mask 只有在 decoder 的 self-attention 里面用到。
Padding Mask
由于每个批次输入序列长度是不一样的,我们要对输入序列进行对齐,在较短的序列后面填充 0;但是如果输入的序列太长,就直接截取较短序列的内容,把多余的直接舍弃。因为这些填充的位置,其实是没什么意义的,所以我们的attention机制不应该把注意力放在这些位置上,所以我们需要进行一些处理。具体的做法是,把这些位置的值加上一个非常大的负数(负无穷),这样再经过 softmax,这些位置的概率就会接近0。
padding mask 实际上是一个张量,每个值都是一个boolean,值为 false 的地方就是我们要进行处理的地方。
Sequence Mask
sequence mask 是为了使得 decoder 不能看见未来的信息。也就是对于一个序列,在 time_step 为 t 的时刻,在当前time_step解码输出只能依赖当前时刻之前的输出,所以使用 Mask 将后面的掩盖。
具体做法是:产生一个上三角矩阵,上三角的值全为0。把这个矩阵作用在每一个序列上,就可以达到我们的目的。
对于 decoder 的 self-attention,里面使用到的 scaled dot-product attention,同时需要padding mask 和 sequence mask 作为 attn_mask,具体实现就是两个mask相加作为attn_mask。其他情况,attn_mask 一律等于 padding mask。
输出层
当decoder层全部执行完毕后,只需要在结尾再添加一个全连接层(linear)和softmax层就能把得到的向量映射为我们需要的词,假如我们的词典是1w个词,那最终softmax会输入1w个词的概率,概率值最大的对应的词就是我们最终的结果。
一般其作用为在给定context vector c和所有已预测的词
{
y
1
,
.
.
.
,
y
t
−
1
}
\{y1,...,yt−1\}
{y1,...,yt−1}去预测
y
t
y_t
yt,故t时刻翻译的结果y为以下的联合概率分布:
p
(
y
∣
c
)
=
∏
t
=
1
T
p
(
y
t
∣
c
,
{
y
1
,
y
2
,
.
.
.
,
y
t
−
1
}
)
p(y|c)=\prod_{t=1}^T p(y_t|c, \{y_1, y_2, ..., y_{t-1}\})
p(y∣c)=t=1∏Tp(yt∣c,{y1,y2,...,yt−1})
联系上文Self-Attention计算相关性部分,另外,通过神经网络来表示模型,可以大幅减少模型的参数:
u
(
c
)
j
=
{
C
⋅
t
a
n
h
(
q
(
c
)
T
k
j
d
k
)
∀
t
′
<
t
−
∞
o
t
h
e
r
w
i
s
e
.
u_{(c)j}=\left\{ \begin{array}{rcl} C \cdot tanh(\frac{q_{(c)}^Tk_j}{\sqrt{d_k}}) & & {\forall t^{'}<t}\\ {- \infty} & & {otherwise.} \end{array} \right.
u(c)j={C⋅tanh(dkq(c)Tkj)−∞∀t′<totherwise.
p
(
y
i
∣
c
)
=
p
(
y
t
=
i
∣
c
,
y
1
:
t
−
1
)
=
e
u
(
c
)
i
∑
j
e
u
(
c
)
j
p(y_i|c)=p(y_t=i|c, y_{1:t-1})=\frac{e^{u_{(c)i}}}{\sum_j e^{u_{(c)}j}}
p(yi∣c)=p(yt=i∣c,y1:t−1)=∑jeu(c)jeu(c)i
参考
图解Transformer(完整版)
Transformer模型详解
Attention 机制
家乐的深度学习笔记「5」 - 多层感知机
点积 vs. MLP:推荐模型到底用哪个更好?