目录
- 一、Transformer 的整体结构
- 二、Input Encoding
- 三、Transformer Block
- 3.1 Encoder
- 3.1.1 Attention
- 3.1.2 Self-attention
- 3.1.3 Multi-head Attention
- 3.2 Decoder
- 3.2.1 Masked Multi-head Attention
- 四、Transformer 的优缺点
遇到看不明白的地方,欢迎在评论中留言呐,一起讨论,一起进步!
前提知识:注意力机制
本文参考:
【清华NLP】刘知远团队大模型公开课全网首发|带你从入门到实战
【官方双语】Transformer模型最通俗易懂的讲解,零基础也能听懂!
全网最透彻的注意力机制的通俗原理与本质【推荐】
【Transformer系列(2)】注意力机制、自注意力机制、多头注意力机制、通道注意力机制、空间注意力机制超详细讲解
之前我们已经了解了 RNN,它是一个顺序计算模型,无法并行处理。这就导致了计算机的并行资源被浪费。而 RNN 变体 GRU 或者 LSTM 仍然需要注意力机制。RNN 这样“笨”,那我们是否能不要它呢?答案是肯定的,论文 Attention is all you need (NeurIPS 2017) 给了我们答案。在这篇文章中,作者提出了一个非常强大的模型结构来进行机器翻译的任务,这个结构就是接下来要介绍的 Transformer。
一、Transformer 的整体结构
Transformer 同样是一个编码器-解码器的模型。下图中的红色框表示编码器(encoder)部分,蓝色框表示解码器(decoder)部分。
我们现在从下往上来看这个过程。首先第一层(下图红框内容)是输入层,输入层需要将文本序列切分成一个个小的单元(这个单元我们叫 token),然后通过 Embedding 转换为向量表示。
这里有两点不同于 RNN:
1、Transformer 会使用 byte pair encoding(BPE) 的方式来对文本进行切分。
2、在每个位置会加上一个 token 的位置向量,即 positional encoding,用来表示 token 在文本序列中的一个位置。
我们再来看 Transformer 的主体部分(下图红框内容),它是由多个 encoder blocks(编码器块)和多个 decoder blocks(解码器块)堆叠而成的。
在 encoder blocks 和 decoder blocks 之间,存在一些差异。然而,不同的 encoder block 之间和不同的 decoder block 之间的结构完全一致,只有参数有所不同。
最后来看模型的输出层,其实就是通过一个线性层的变换和一个 Softmax 来输出一个在词表上的概率分布。这与之前 RNN 输出层基本是一致的。在训练过程中,我们也是通过在词表这样一个维度通过计算交叉熵来计算 loss。
以上就是 Transformer 的整体结构,接下来我们逐个部分进行讲解。
二、Input Encoding
输入层使用 Byte-Pair Encoding 对输入进行切分,具体细节可以参考之前的博客 BPE (Byte-Pair Encoding) Tokenization 。
我们知道一个 token 出现在文本中的位置是非常重要的。
Transformer 提出了一个显式建模位置关系的一个方法:通过在原有的 embedding 上加上一个位置向量来让同一个单词在不同位置有不同的表示,进而让模型进行区分。
我们首先假设通过 BPE 和 embedding 得到的向量的维度为
d
d
d,而位置编码也需要一个维度为
d
d
d 向量。
Transformer 采用了一个基于三角函数的一个方法来得到对应的一个位置向量:
p
o
s
pos
pos 表示当前 token 在句子中的位置,是一个从
0
0
0 到 序列长度之间的数。
i
i
i 表示当前这个位置在 embedding 中的 index,是一个从
0
0
0 到
d
/
2
d/2
d/2 之间的数。
下图展示的是一个长度为
10
10
10 个 token,编码向量维度
d
=
64
d=64
d=64 的位置编码可视化。我们可以看到相同维度的编码(就是每个竖线)其实是一个周期的正弦或者余弦函数,而相同位置的编码(就是每个横线)对应着不同周期的正弦和余弦函数。
根据三角函数的性质我们知道,不同位置的位置编码向量之间的差别取决于它们之间的相对位置。
我们最终就是将 BPE 和 PE 按照位置相加得到的向量输入到 Transformer 主体部分中。
三、Transformer Block
3.1 Encoder
Encoder 整体是由两大块组成的,分别是 Multi-Head Attention 网络(下面橙色部分)和 Feed-Forward 网络(上面蓝色部分,本质上是一个带激活函数的两层 MLP 全连接,大家应该比较熟悉了)。
图中的 Nx 表示 N 个模块(block)可以堆叠在一起组成一个更深的神经网络,在原始论文中, Encoder 端一共堆叠了 6 个模块。
除此之外,这里附加了两个小技巧:
1、残差连接(Residual connection)(如图左侧的两个箭头)
残差连接主要用于解决深层神经网络中的梯度消失和梯度爆炸问题。它通过在网络中添加跨层的直接连接,将上一层的输出与下一层的输入相加,从而将梯度从较深的层传递到浅层,使得网络更易于训练。具体而言,残差连接可以使用以下公式表示:
y = F ( x ) + x y = F(x) + x y=F(x)+x其中, x x x 代表上一层的输入, F ( x ) F(x) F(x) 代表上一层经过一系列操作后的输出, y y y 代表当前层的输出。通过将 x x x 直接添加到 F ( x ) F(x) F(x) 上,实现了梯度的直接传递。
残差连接最早被引入到深度残差网络(ResNet)中,该网络在 2015 年的 ImageNet 比赛中取得了优秀的成绩。自此以后,残差连接成为了深度学习中的重要组件,被广泛用于各种网络结构的设计中,例如DenseNet、Highway Network等。
深入了解可以参考论文:
Deep residual learning for image recognition. He et al. CVPR 2016.
2、层归一化(Layer normalization)(见图中两处黄色部分)
Layer normalization 的主要思想是对每个神经网络层的输入进行归一化,使得其均值为 0,方差为
1。具体而言,给定一个输入向量 x x x,Layer normalization 的计算公式如下: LayerNorm ( x ) = scale ⋅ ( x − mean variance + epsilon ) + bias \text{{LayerNorm}}(x) = \text{{scale}} \cdot \left(\frac{{x - \text{{mean}}}}{{\sqrt{{\text{{variance}} + \text{{epsilon}}}}}}\right) + \text{{bias}} LayerNorm(x)=scale⋅(variance+epsilonx−mean)+bias其中,mean 和
variance 分别表示输入向量 x x x 的均值和方差,epsilon 是一个小的正数防止除以零的情况,scale 和 bias
是可学习的参数。 通过将输入向量 x x x 进行归一化,Layer normalization 可以使得每个神经网络层的输入具有类似的分布。
深入了解可以参考论文:
Layer normalization. Ba et al. arXiv 2016.
我们主要关注 Multi-Head Attention 部分,下面我们对这部分详细介绍一下。
3.1.1 Attention
我们先回顾一下前讲的注意力机制:给定一个 query 向量和一组 value 向量,注意力机制基于 query 向量对 value 向量进行一个加权平均。
而 Transformer 给定的是一个 query 向量和一组 key-value 向量对。其中,query 向量和 key 向量的维度都是 d k d_k dk,而 value 向量的维度是 d v d_v dv。
不同于之前用 query 向量和 value 向量来计算注意力分数,我们这里采用 query 向量和 key 向量的点积来计算注意力分数。
这里的输出同样是对 value 向量进行一个加权平均。
A
(
q
,
K
,
V
)
=
∑
i
e
q
⋅
K
i
∑
j
e
q
⋅
K
j
V
i
=
softmax
(
q
K
T
)
V
A(q,K,V)=\sum_i{\frac{e^{q\cdot K_i}}{\sum_j{e^{q\cdot K_j}}}V_i}=\text{softmax}(qK^T)V
A(q,K,V)=i∑∑jeq⋅Kjeq⋅KiVi=softmax(qKT)V
大家可以借助淘宝的例子来进行理解:
而多个 query 向量可以通过矩阵
Q
Q
Q 来表示:
A
(
Q
,
K
,
V
)
=
softmax
(
Q
K
T
)
V
A(Q,K,V)=\text{softmax}(QK^T)V
A(Q,K,V)=softmax(QKT)V
为了控制注意力权重的大小和梯度的稳定性,这里进一步通过 query 向量的长度
d
k
d_k
dk 进行缩放(scale):
A
(
Q
,
K
,
V
)
=
softmax
(
Q
K
T
d
k
)
V
A(Q,K,V)=\text{softmax}(\frac{QK^T}{\sqrt{d_k}})V
A(Q,K,V)=softmax(dkQKT)V
上图完整地展示了 attention 的一个过程:
- 首先 Q Q Q 和 V V V 进行一个矩阵乘法,得到对应的一个注意力分数;
- 然后通过缩放系数 1 d k \frac{1}{\sqrt{d_k}} dk1 对注意力分数进行放缩
Mask 这个部分我们将在 decoder 部分使用- 接着再通过 SoftMax 函数将注意力分数转换为一个概率分布
- 随后通过与对应的 V V V 矩阵进行一个矩阵乘法就可以对 V V V 实现加权平均,得到我们最后的输出
3.1.2 Self-attention
自注意力机制希望每个 token 能够自主地选择应该关注这句话中的哪些 token 并进行信息的整合,对应的 Q 、 K 、 V Q、K、V Q、K、V 三个矩阵其实都是通过文本的表示向量乘上一个变换矩阵得到的。
对于第一层的 Transformer Block 来说,文本的表示向量其实就是我们前面提到的词表向量和对应位置编码的一个求和。
而对于非第一层的 Transformer Block 来说,文本的表示向量其实就是前面一层的输出。
自注意力机制的关键点在于, Q 、 K 、 V Q、K、V Q、K、V 是同一个东西,或者三者同源,不是输入语句和输出语句之间的注意力机制,而是输入语句内部元素之间或者输出语句内部元素之间发生的注意力机制。
注意力机制的 Q Q Q 和 K K K 是不同来源的。 例如,在 Encoder-Decoder 模型中, K K K是 Encoder 中的元素,而 Q Q Q 是 Decoder 中的元素。
自注意力机制的 Q Q Q 和 K K K 则都是来自于同一组元素。 例如,在 Encoder-Decoder 模型中, Q Q Q 和 K K K 都是 Encoder 中的元素,相互之间做注意力汇聚。
3.1.3 Multi-head Attention
在上述单个 attention 的基础上,Transformer 为了进一步增强模型的一个表示能力,采用了多个结构相同但参数不同的注意力模块,组成了一个多头的注意力机制,其中每个注意力头的计算方式都和前面介绍的完全一致,只不过每个头都有一个自己的权重矩阵
W
i
Q
W_i^Q
WiQ、
W
i
K
W_i^K
WiK 和
W
i
V
W_i^V
WiV(分别对应下图下方的 Linear 位置)。
每个注意力头通过前面介绍的方式得到自己的输出:
h
e
a
d
i
=
A
(
Q
W
i
Q
,
K
W
i
K
,
V
W
i
V
)
head_i=A(QW_i^Q,KW_i^K,VW_i^V)
headi=A(QWiQ,KWiK,VWiV)
然后我们将这些输出在维度层面进行一个拼接,然后通过一个线性层进行整合就得到了 Multi-head Attention 的一个输出。
MultiHead
(
Q
,
K
,
V
)
=
Concat
(
h
e
a
d
1
,
.
.
.
,
h
e
a
d
h
)
W
O
\text{MultiHead}(Q,K,V)=\text{Concat}(head_1,...,head_h)W^O
MultiHead(Q,K,V)=Concat(head1,...,headh)WO
最后这个输出就会通过残差连接和正则化之后输入到后面的前馈神经网络(2-layer feed-forward network)。
3.2 Decoder
对于 Decoder 端,大体上和 Encoder 端是一致的,但是有两个简单的修改:
1、最开始并不是 Multi-head Attention,而是 Masked Multi-head Attention
掩码操作可以避免模型在预测当前位置时使用未来位置的信息。具体而言,模型在预测第
i
i
i 个位置时,将第
i
i
i 个位置及其后续位置的注意力权重设置为一个很小的值,表示这些位置的信息被遮盖。
2、Multi-head Attention 的输入
Q
Q
Q 来自 Decoder,即 Masked Multi-head Attention 的输出向量经过残差连接和正则化之后的输出,而
K
K
K 和
V
V
V 来自于 Encoder 最后一层的输出
这个部分类似于我们最开始讲的端到端模型中的注意力机制,它是为了帮助 Decoder 端每一步的生成都可以关注和整合每个 Encoder 端每个位置的信息。
和 Encoder block 一样,这样的 Decoder block 也可以进行堆叠,如上图我右方标记了“Nx”。在原论文中,Decoder block 也是一共堆叠了 6 层。
3.2.1 Masked Multi-head Attention
在 Multi-head Attention 的基础上, Masked Multi-head Attention 在注意力分数矩阵上进行了掩码操作,即将这个矩阵的左对角线的上三角部分(不包括对角线)设置为
−
∞
-∞
−∞
这样的操作能让我们在计算 SoftMax 之后
−
∞
-∞
−∞ 对应的位置会变为 0,然后通过矩阵乘法我们会发现:第
i
i
i 个输出(即 Output 的第
i
i
i 行)只考虑了前
i
i
i 个 value 向量(即 V 的前
i
i
i 行)
这样的操作就保证了 Decoder 端在文本生成的时候是顺序生成的,不会出现我们在生成第
i
i
i 个位置的时候参考了第
i
+
1
i+1
i+1 个输入位置的信息。
四、Transformer 的优缺点
优点:
- Transformer 是一个功能强大的模型,在许多自然语言处理 (NLP) 任务中已被证明是有效的。
- Transformer 模型适用于并行计算,可以在大规模数据上进行高效的训练和推理。
- Transformer 的注意力机制被证明是一种有效的建模方法,在处理不同位置之间的关系时表现出色。
- Transformer 模型的出现为最近的 NLP 进展提供了启示,如 BERT 和 GPT,这些模型基于 Transformer 的架构取得了显著的突破。
缺点:
- 模型本身对于参数非常敏感,优化过程非常困难
- 处理复杂度为 O ( n 2 ) O(n^2) O(n2),导致对于也别长的文本束手无策,通过设置 512 为最大输入长度。