如果你对这篇文章感兴趣,可以点击「【访客必读 - 指引页】一文囊括主页内所有高质量博客」,查看完整博客分类与对应链接。
在 Transformer 之前,序列翻译任务(或者说与序列、时序相关的任务)通常采用 RNN、CNN 结构,其中 RNN 的缺点在于:(1)使用计算的先后次序,来表征序列中的先后信息,因此只能串行计算(2)长序列早期的信息可能会丢失;CNN 的缺点在于:捕捉相邻信息依赖卷积的窗口,因此对于长序列的信息可能需要很多层卷积。
基于上述问题,Transformer 应运而生,提出新结构,用于实现(1)更好地并行化(2)更好地建模长序列。
首先是单层直接做 Attention,输入 Q(query)、K(keys)、V(values),具体思想是将 Q 与 K 两两做相似度比较,再将相似度作为与 V 的权重系数,具体计算方式如下:
Attention
(
Q
,
K
,
V
)
=
softmax
(
Q
K
T
d
k
)
V
\text { Attention }(Q, K, V)=\operatorname{softmax}\left(\frac{Q K^T}{\sqrt{d_k}}\right) V
Attention (Q,K,V)=softmax(dkQKT)V
其中
d
k
d_{k}
dk 是 Q、K、V 向量维度。此处除以
d
k
\sqrt{d_k}
dk 的原因在于,当向量较长时,softmax 很容易将每个元素的结果往 0 或 1 推,而当所有结果分布在 0、1 区域时,softmax 函数的梯度将变得很小,即出现梯度消失现象。
由于上述的 Attention 操作是对全局做的,但实际在预测中, t − 1 t-1 t−1 时刻是无法看到 t t t 时刻信息的,因此对 t − 1 t-1 t−1 时刻之后的结果,乘以一个很大的负数,即通过 softmax 后变为 0,V 中对应位置的权重系数变为 0。
在上述的单层 Attention 中,我们可以发现没有多少可以调整的参数,因此借鉴 CNN 的思想,采用 Multi-Head Attention 的方式,将 Q、K、V 映射到多个子空间中,分别进行 Attention 操作后再拼接起来,具体结构如下所示:
实际上就是两层 MLP,计算过程如下:
FFN
(
x
)
=
max
(
0
,
x
W
1
+
b
1
)
W
2
+
b
2
\operatorname{FFN}(x)=\max \left(0, x W_1+b_1\right) W_2+b_2
FFN(x)=max(0,xW1+b1)W2+b2
在 RNN 中,通过计算的先后次序,来表征序列中的先后信息;而在 Transformer 中,Attention 只是两两算相似度,其本身没有时序信息,因此在其模型结构中,主要通过对每一个位置的向量,加上一个表示当前位置信息的向量,即一个记录时序信息的 Positional Encoding,以此达到加入时序的作用,其具体做法如下:
P
E
(
p
o
s
,
2
i
)
=
sin
(
p
o
s
/
1000
0
2
i
/
d
model
)
P
E
(
p
o
s
,
2
i
+
1
)
=
cos
(
p
o
s
/
1000
0
2
i
/
d
model
)
其中
P
E
(
p
o
s
,
2
i
)
PE_{(pos,2i)}
PE(pos,2i) 表示
p
o
s
pos
pos 位置对应向量的第
2
i
2i
2i 维度数值。