目录
Transformer模型回顾
简述
Transformer的输入
单词 Embedding
位置 Embedding
Self-Attention结构
Q,K,V的计算
Self-Attention的输出
Multi-Head Attention
Encoder结构
残差模块
Feed Forward
Decoder结构
第一个 Multi-Head Attention
第二个 Multi-Head Attention
Softmax 预测输出单词
Transformer总结
Transformer由论文 Attention is All You Need 提出,论文传送门
首先介绍Transformer的整体结构下图是Transformer用于中英文翻译的整体结构。从宏观的视角来看,我们可以把模型看成是一个黑箱操作。在机器翻译中,就是输入一种语言,输出另一种语言。
拆开这个黑箱,我们可以看到它是由编码组件、解码组件和它们之间的连接组成。
编码组件部分由一堆编码器(encoder)构成(论文中是将6个编码器叠在一起——数字6没有什么神奇之处,你也可以尝试其他数字)。解码组件部分也是由相同数量(与编码器对应)的解码器(decoder)组成的。
所有的编码器在结构上都是相同的,但他们没有共享参数。每个解码器都可以分解成两个子层。
从编码器输入的句子首先会经过一个自注意力(self-attention)层,这层帮助编码器在对每个单词编码时关注输入句子的其他单词。具体稍后讲解。
自注意力层的输出会传递到前馈(feed-forward)神经网络中。每个位置的单词对应的前馈神经网络都完全一样
解码器中也有编码器的自注意力(self-attention)层和前馈(feed-forward)层。除此之外,这两个层之间还有一个注意力层,用来关注输入句子的相关部分(和seq2seq模型的注意力作用相似)。
Transformer模型使用经典的encoder-decoder架构,由encoder和decoder两部分组成。encoder和decoder都包含6个block。
Multi-Head Attention,是由多个Self-Attention组成的,可以看到Encoder block包含一个Multi-Head Attention,而decoder block包含两个Multi-Head Attention(其中一个用到masked)。Multi-Head Attention上方还包括一个Add&Norm层,Add表示残差连接(Residual Connection)用于防止网络退化,Norm表示Layer Normalization,用于对每一层的激活值进行归一化。
Transformer中单词的输入表示 x 由单词embedding和位置embedding相加得到。
单词的embedding有很多种方式可以获取,例如可以采用word2vec,glove等算法预训练得到,也可以在transformer中训练得到。
transformer 中除了单词的embedding,还需要使用位置embedding表示单词出现在句子中的位置。因为transformer不采用RNN的结构,而是使用全局信息,不能利用单词的顺序信息,而这部分信息对于NLP来说非常重要。所以Transformer中使用位置embedding保存单词在序列中的相对或绝对位置。
位置 Embedding 用 PE 表示,PE 的维度与单词 Embedding 是一样的。PE 可以通过训练得到,也可以使用某种公式计算得到。在 Transformer 中采用了后者,计算公式如下:
将单词的词 Embedding 和位置 Embedding 相加,就可以得到单词的表示向量 x,x 就是 Transformer 的输入。
因为Self-Attention时Transformer的重点,所以我们重点关注Multi-Head Attention以及Self-Attention,首先详细了解一下Self-Attention的内部逻辑。
上图是Self-Attention的结构,计算自注意力的第一步就是从每个编码器的输入向量(每个单词的词向量)中生成三个向量。也就是说对于每个单词,我们创造一个矩阵Q(查询向量),一个K(键向量),一个V(值向量)。这三个向量是通过词嵌入与三个权重矩阵后相乘创建的。
Self-Attention的输入用矩阵X进行表示,则可以使用线性变换矩阵WQ,WK,WV计算得到Q,K,V。计算如下图所示,注意X, Q, K, V的每一行都表示一个单词。
(K, V计算同上)
得到矩阵Q, K, V之后就可以计算出Self-Attention的输出了,计算的公式如下:
公式中计算矩阵Q和K每一行向量的内积,为了防止内积过大,因此除以dk的平方根。(让梯度更稳定)Q乘以K的转置后,得到的矩阵行列数都为n,n为句子单词数,这个矩阵可以表示单词之间的attention强度。下图为Q乘以K的转置,1234表示的是句子中的单词。
得到QKT之后,使用softmax计算每一个单词对于其他单词的attention系数,公式中的softmax是对矩阵的每一行进行softmax,即每一行的和都为1.
然后将每个值向量去乘以softmax分数(这是为了准备之后将它们求和)这里的直觉是希望关注语义上相关的单词,并弱化不相关的单词(例如,让它们乘以0.001这样的小数)。最后是对加权值向量求和,得到自注意力层在该位置的输出。
这样自注意力的计算就完成了。得到的向量就可以传给前馈神经网络。然而实际中,这些计算是以矩阵形式完成的,以便算得更快。
在上一步,我们已经知道怎么通过self-attention计算得到输出矩阵Z,而multi-haed attention是由多个self-attention组合形成的,下图是论文中multi-head attention的结构图:
从上图可以看到multi-head attention包含多个self-attention层,首先将输入X分别传递到h个不同的self-attention中,计算得到h个输出矩阵Z。下图是h = 8时候的情况,此时会得到8个输出矩阵Z:
得到 8 个输出矩阵Z1到Z8之后,multi-head attention将它们拼接在一起(concat),然后传入一个linear层,得到multi-head attention 最终的输出Z。
可以看到multi-head attention输出的矩阵Z与其输入的矩阵X的维度是一样的。
它在两方面提高了注意力层的性能:
在这里我们还需要提到一个编码器架构中的细节:在每个编码器中的每个子层(自注意力、前馈网络)的周围都有一个残差连接,并且都跟随着一个“层-归一化”步骤。(Add & Norm)
Add & Norm 层由 Add 和 Norm 两部分组成,其计算公式如下:
其中 X 表示 Multi-Head Attention 或者 Feed Forward 的输入,MultiHeadAttention(X) 和 FeedForward(X) 表示输出 (输出与输入 X 维度是一样的,所以可以相加)。
Add 指 X+MultiHeadAttention(X),是一种残差连接,通常用于解决多层网络训练的问题,可以让网络只关注当前差异的部分,在 ResNet 中经常用到。
Norm 指 Layer Normalization,通常用于 RNN 结构,Layer Normalization 会将每一层神经元的输入都转成均值方差都一样的,这样可以加快收敛。
Feed Forward 层比较简单,是一个两层的全连接层,第一层的激活函数为ReLu,第二层不使用激活函数,对应的公式如下:
X 是输入,Feed Forward 最终得到的输出矩阵的维度与 X 一致。
通过上面描述的 Multi-Head Attention, Feed Forward, Add & Norm 就可以构造出一个 Encoder block,Encoder block 接收输入矩阵 X(n×d),并输出一个矩阵 O(n×d)。通过多个 Encoder block 叠加就可以组成 Encoder。
第一个 Encoder block 的输入为句子单词的表示向量矩阵,后续 Encoder block 的输入是前一个 Encoder block 的输出,最后一个 Encoder block 输出的矩阵就是 编码信息矩阵 C,这一矩阵后续会用到 Decoder 中。
上图红色部分为 Transformer 的Decoder block结构,与Encoder block相似,但是存在一些区别:
Decoder block 的第一个 Multi-Head Attention 采用了 Masked 操作,因为在翻译的过程中是顺序翻译的,即翻译完第 i 个单词,才可以翻译第 i+1 个单词。
通过 Masked 操作可以防止第 i 个单词知道 i+1 个单词之后的信息。
下面以 "我有一只猫" 翻译成 "I have a cat" 为例,了解一下 Masked 操作。
下面的描述中使用了类似 Teacher Forcing 的概念(见括号坑未填...),在 Decoder 的时候,是需要根据之前的翻译,求解当前最有可能的翻译,如下图所示。首先根据输入 "
Decoder 可以在训练的过程中使用 Teacher Forcing 并且并行化训练,即将正确的单词序列 (
第一步: 是 Decoder 的输入矩阵和 Mask 矩阵,输入矩阵包含 "
第二步:接下来的操作和之前的 Self-Attention 一样,通过输入矩阵 X 计算得到 Q, K, V 矩阵。然后计算 Q 和 KT 的乘积 QKT。
第三步:在得到 QKT 之后需要进行 Softmax,计算 attention score,我们在 Softmax 之前需要使用 Mask 矩阵遮挡住每一个单词之后的信息,遮挡操作如下:
得到 Mask QKT 之后在 Mask QKT 上进行 Softmax,每一行的和都为 1。但是单词 0 在单词 1, 2, 3, 4 上的 attention score 都为 0。
第四步:使用 Mask QKT 与矩阵 V 相乘,得到输出 Z,则单词 1 的输出向量 Z1 是只包含单词 1 信息的。
第五步:通过上述步骤就可以得到一个 Mask Self-Attention 的输出矩阵 Zi,然后和 Encoder 类似,通过 Multi-Head Attention 拼接多个输出 Zi 然后计算得到第一个 Multi-Head Attention 的输出 Z,Z 与输入 X 维度一样。
Decoder block 第二个 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)。
Decoder block 最后的部分是利用 Softmax 预测下一个单词,在之前的网络层我们可以得到一个最终的输出 Z,因为 Mask 的存在,使得单词 0 的输出 Z0 只包含单词 0 的信息,如下。
Softmax 根据输出矩阵的每一行预测下一个单词:
这就是 Decoder block 的定义,与 Encoder 一样,Decoder 是由多个 Decoder block 组合而成。
Transformer 与 RNN 不同,可以比较好地并行训练。
Transformer 本身是不能利用单词的顺序信息的,因此需要在输入中添加位置 Embedding,否则 Transformer 就是一个词袋模型了。
Transformer 的重点是 Self-Attention 结构,其中用到的 Q, K, V 矩阵通过输出进行线性变换得到。
Transformer 中 Multi-Head Attention 中有多个 Self-Attention,可以捕获单词之间多种维度上的相关系数 attention score。
Reference
https://www.jianshu.com/p/9b87b945151e
https://baijiahao.baidu.com/s?id=1622064575970777188&wfr=spider&for=pc