前言
Transformer是由论文《Attention is All You Need》提出的,论文链接如下:
这篇论文提出了一种新的神经网络架构:Transformer,仅仅依赖于注意力机制就可处理序列数据,从而摒弃了 RNN 或 CNN 。这个新的网络结构,刷爆了各大翻译任务,同时创造了多项新的记录,目前大热的 Bert 就是基于 Transformer 构建的。
在本文中,我们从零来详细解读什么是Transformer模型。
1. Transformer 整体结构
首先介绍 Transformer 的整体结构
Transformer在做一个什么事情?
由上图可知,它是一个“输入—处理—输出”的过程,输入“我 爱 你”会输出一个“I LOVE YOU”,相当于机器翻译的过程。那我们继续细化 Transformer:
由上图可知,当我输入一个文本的时候,该文本数据会先经过一个叫Encoders的模块,对该文本进行编码,然后将编码后的数据再传入一个叫Decoders的模块进行解码,解码后就得到了翻译后的文本,对应的我们称Encoders为编码器,Decoders为解码器。所以,Transformer由encoders(编码器)和decoders(解码器)构成;,是一个编码-解码的结构;类似于seq2seq;让我们继续来细化 Transformer:
由上图我们看到,Encoders由6个相同的小Encoder组成,Decoders由6个相同的小Decoder组成。在编码部分,每一个的小编码器的输入是前一个小编码器的输出,而每一个小解码器的输入不光是它的前一个解码器的输出,还包括了整个编码部分的输出。,6个Encoder/Decoder结构完全相同,但是Encoder和Decoder结构是不同的。
注意了:6个Encoder/Decoder的结构相同但是参数不同;(也就是说,训练的时候,不是训练一个然后copy5个,而是6个都在训练);其次,6个是可以变化的,相当于是个N。
那每一个小编码器里边又是什么呢?
我们放大一个encoder,发现里边的结构是一个自注意力机制加上一个前馈神经网络。如下图:
原论文中的的图如下:
2. Encoder详细介绍
可以把单个的encoder分为三个部分:输入部分,注意力机制和前馈神经网络;如下图:
2.1 输入部分
输入部分分为两个小部分:embedding和位置嵌入;
Embedding: Embedding 是一个将离散变量转为连续向量表示的一个方式。在神经网络中,embedding 是非常有用的,因为它不光可以减少离散变量的空间维数,同时还可以有意义的表示该变量。
位置Embedding: 以下图RNN为例,对于所有的时间步,都共享一套参数
而Transformer是并行的,所有单词是可以一起处理的,不像RNN,输入完“我”,等处理完“我”,再输入“爱”;这样做增快了速度,但忽略了单词间先后关系;所以需要位置编码。
位置 Embedding 用 PE表示,PE 的维度与单词 Embedding 是一样的。PE 可以通过训练得到,也可以使用某种公式计算得到。在 Transformer 中采用了后者,计算公式如下:
其中,pos 表示单词在句子中的位置,d 表示 PE的维度 (与词 Embedding 一样),2i 表示偶数的维度,2i+1 表示奇数维度 (即 2i≤d, 2i+1≤d)。在偶数位置使用sin,在奇数位置使用cos;如下图:
例如“爱”这个字,在512个维度编码中,偶数位是sin,奇数位是cos,得到位置编码之后,将位置编码512维度和词(字)向量的512维度相加,得到最终的512维度作为最终的输入。
为什么位置嵌入有用?或有什么好处
借助上述公式,我们可以得到一个特定位置的维的位置向量,并且借助三角函数的性质:
我们可以得到:
可以看出,对于pos+k位置的位置向量某一维2i或2i+1而言,可以表示为,pos位置与k位置的位置向量的2i与2i+1维的线性组合,这样的线性组合意味着位置向量中蕴含了相对位置信息。
但是这种相对位置信息会在注意力机制那里消失。
2.2 self-attention自注意力机制
注意力机制是transformer的核心操作。
首先介绍下最基本的注意力机制:
人类在看一张图片时,有比较关注的部分和不怎么关注的部分,红色越深代表很受关注。计算公式如下:
从公式中,可以关注Q,K,V三个矩阵,从公式角度来看,拿上面的图片举例子:
把区域分为4个区域,婴儿和左上、左下、右上、右下分别点乘得到某个值,得到的值看哪个比较大,大的就更关注,再和V相乘,得到加权和。
在Transformer中如何运用
Self-Attention是 Transformer 的重点,所以我们重点关注 Multi-Head Attention 以及 Self-Attention,首先我们详细了解一下 Self-Attention 的内部逻辑。
2.2.1 Self-attention结构
上图是 Self-Attention 的结构,在计算的时候需要用到矩阵Q(查询),K(键值),V(值) 。在实际中,Self-Attention 接收的是输入或者上一个 Encoder block 的输出。而Q,K,V正是通过 Self-Attention 的输入进行线性变换得到的。
2.2.2 Q,K,V的计算
如上图所示,和相乘,就得到Q的值,以此类推K,V
得到矩阵 Q, K, V之后就可以计算出 Self-Attention 的输出了,计算的公式如下:
是Q,K矩阵的列数,即向量维度
公式中计算矩阵Q和K每一行向量的内积,为了防止内积过大,因此除以的平方根。Q乘以K的转置后,得到的矩阵行列数都为 n,n 为句子单词数,这个矩阵可以表示单词之间的 attention 强度。下图为Q乘以,1234 表示的是句子中的单词
得到之后,使用 Softmax 计算每一个单词对于其他单词的 attention 系数,公式中的 Softmax 是对矩阵的每一行进行 Softmax,即每一行的和都变为 1
得到 Softmax 矩阵之后可以和V相乘,得到最终的输出Z
上图中 Softmax 矩阵的第 1 行表示单词 1 与其他所有单词的 attention 系数,最终单词 1 的输出等于所有单词的值根据 attention 系数的比例加在一起得到,如下图所示:
2.2.3 Multi-head Attention
Multi-Head Attention 是由多个 Self-Attention 组合形成的,论文中Multi-Head Attention结构图如下:
从上图可以看到 Multi-Head Attention 包含多个 Self-Attention 层,首先将输入X分别传递到 h 个不同的 Self-Attention 中,计算得到 h 个输出矩阵Z。下图是 h=8 时候的情况,此时会得到 8 个输出矩阵Z。
得到8个输出矩阵到之后,Multi-Head Attention 将它们Concat在一起,然后传入一个Linear层,得到 Multi-Head Attention 最终的输出:
可以看到 Multi-Head Attention 输出的矩阵Z与其输入的矩阵X的维度是一样的。
2.3 前馈神经网络
Feed Forward 层比较简单,是一个两层的全连接层,第一层的激活函数为 Relu,第二层不使用激活函数,对应的公式如下:
2.4 Add&Normalize
Add & Norm 层由 Add 和 Norm 两部分组成,其计算公式如下:
其中 X表示 Multi-Head Attention 或者 Feed Forward 的输入,MultiHeadAttention(X) 和 FeedForward(X) 表示输出 (输出与输入 X 维度是一样的,所以可以相加)。
Add指 X+MultiHeadAttention(X),是一种残差连接,通常用于解决多层网络训练的问题,可以让网络只关注当前差异的部分,在 ResNet 中经常用到:
上图代表残差,X作为输入,经过两层网络,这两层网络统一为一个函数F(X),如果没有残差网络,直接F(X)输出就可以了,有了残差网络后,把X和F(X)对位相加,得到真正的输出。
残差的作用:
根据后向传播的链式法则:
确保了梯度不会为0,缓解了梯度消失的出现。
3. Decoder详细介绍
Decoder的结构图如下:
上图红色部分为 Transformer 的 Decoder block 结构,与 Encoder block 相似,但是存在一些区别:
- 包含两个 Multi-Head Attention 层。
- 第一个 Multi-Head Attention 层采用了Masked 操作。
- 第二个 Multi-Head Attention 层的K, V矩阵使用 Encoder 的编码信息矩阵C进行计算,而Q使用上一个 Decoder block 的输出计算。
- 最后有一个 Softmax 层计算下一个翻译单词的概率。
3.1 Masked Multi-Head Attention
为什么采用Mask操作?
在翻译的过程中是顺序翻译的,即翻译完第 i 个单词,才可以翻译第 i+1 个单词。通过 Masked 操作可以防止第 i 个单词知道 i+1 个单词之后的信息。下面以 "我有一只猫" 翻译成 "I have a cat" 为例,了解一下 Masked 操作。
在 Decoder 的时候,是需要根据之前的翻译,求解当前最有可能的翻译,如下图所示。首先根据输入 "Begin" 预测出第一个单词为 "I",然后根据输入 "Begin I" 预测下一个单词 "have"。
Decoder 可以在训练的过程中使用 Teacher Forcing 并且并行化训练,即将正确的单词序列 (Begin I have a cat) 和对应输出 (I have a cat end) 传递到 Decoder。那么在预测第 i 个输出时,就要将第 i+1 之后的单词掩盖住,注意 Mask 操作是在 Self-Attention 的 Softmax 之前使用的,下面用 0 1 2 3 4 5 分别表示 "Begin I have a cat end"
第一步:是 Decoder 的输入矩阵和 Mask矩阵,输入矩阵包含 "Begin I have a cat" (0, 1, 2, 3, 4) 五个单词的表示向量,Mask 是一个 5×5 的矩阵。在 Mask 可以发现单词 0 只能使用单词 0 的信息,而单词 1 可以使用单词 0, 1 的信息,即只能使用之前的信息。
第二步: 接下来的操作和之前的 Self-Attention 一样,通过输入矩阵X计算得到Q,K,V矩阵。然后计算Q和的乘积。
第三步: 在得到之后需要进行 Softmax,计算 attention score,我们在 Softmax 之前需要使用Mask矩阵遮挡住每一个单词之后的信息,遮挡操作如下:
得到Mask 之后在Mask 上进行Softmax,每一行的和都为 1。但是单词 0 在单词 1, 2, 3, 4 上的 attention score 都为 0。
第四步: 使用 Mask 与矩阵 V相乘,得到输出Z,则单词 1 的输出向量 是只包含单词 1 信息的。
第五步: 通过上述步骤就可以得到一个 Mask Self-Attention 的输出矩阵,然后和 Encoder 类似,通过 Multi-Head Attention 拼接多个输出,然后计算得到第一个 Multi-Head Attention 的输出Z,Z与输入X维度一样。
3.2 第二个Multi-Head Attention
其中 Self-Attention 的 K, V矩阵不是使用 上一个 Decoder block 的输出计算的,而是使用 Encoder 的编码信息矩阵 C 计算的。
根据 Encoder 的输出C计算得到K,V,根据上一个 Decoder block 的输出 Z计算 Q (如果是第一个 Decoder block 则使用输入矩阵 X进行计算),后续的计算方法与之前描述的一致。
这样做的好处是在 Decoder 的时候,每一位单词都可以利用到 Encoder 所有单词的信息 (这些信息无需 Mask)。
4. 总结
- Transformer 本身是不能利用单词的顺序信息的,因此需要在输入中添加位置 Embedding,否则 Transformer 就是一个词袋模型了。
- Transformer 的重点是 Self-Attention 结构,其中用到的 Q, K, V矩阵通过输出进行线性变换得到。
- Transformer 中 Multi-Head Attention 中有多个 Self-Attention,可以捕获单词之间多种维度上的相关系数 attention score。
参考: