基于Encoder-Decoder架构,最初用于翻译任务。
左边是encoder,右边是decoder。
或达到解码最大token数为结束标志。单词的 Embedding 有很多种方式可以获取,例如可以采用 Word2Vec、Glove 等算法预训练得到,也可以在 Transformer 中训练得到。
Transformer 中除了单词的 Embedding,还需要使用位置 Embedding 表示单词出现在句子中的位置。因为 Transformer 不采用 RNN 的结构,而是使用全局信息,不能利用单词的顺序信息,而这部分信息对于 NLP 来说非常重要。所以 Transformer 中使用位置 Embedding 保存单词在序列中的相对或绝对位置。
(如果不用位置编码的话,就跟词袋模型差不多了)
位置 Embedding 用 PE表示,PE 的维度与单词 Embedding 是一样的。PE 可以通过训练得到,也可以使用某种公式计算得到。在 Transformer 中采用了后者,计算公式如下:
其中,pos 表示单词在句子中的位置,d 表示 PE的维度 (与词 Embedding 一样),2i 表示偶数的维度,2i+1 表示奇数维度 (即 2i≤d, 2i+1≤d)。使用这种公式计算 PE 有以下的好处:
将单词的词 Embedding 和位置 Embedding 相加,就可以得到单词的表示向量 x,x 就是 Transformer 的输入。
Add 表示残差连接 (Residual Connection) 用于防止网络退化,Norm 表示 Layer Normalization,用于对每一层的激活值进行归一化。
Add操作出自ResNet:
Norm指 Layer Normalization,通常用于 RNN 结构,Layer Normalization 会将每一层神经元的输入都转成均值方差都一样的,这样可以加快收敛。
Q-query
K-key
V-value
self-attention中的QKV都是对输入进行线性转换后得到的(XQKV都是每一行代表一个token):
decoder中的K和V则是用 Encoder 的编码信息矩阵 C 计算的。
根据 Encoder 的输出 C计算得到 K, V,根据上一个 Decoder block 的输出 Z 计算 Q (如果是第一个 Decoder block 则使用输入矩阵 X 进行计算),后续的计算方法与encoder述的一致。
这样做的好处是在 Decoder 的时候,每一位单词都可以利用到 Encoder 所有单词的信息 (这些信息无需 Mask)。
得到QKV后计算输出:
公式中计算矩阵 Q和 K 每一行向量的内积,为了防止内积过大,因此除以
d
k
d_k
dk 的平方根。Q 乘以 K 的转置后,得到的矩阵行列数都为 n,n 为句子单词数,这个矩阵可以表示单词之间的 attention 强度。下图为 Q 乘以 K 的转置,1234 表示的是句子中的单词。
得到 QK
T
^T
T 之后,使用 Softmax 计算每一个单词对于其他单词的 attention 系数,公式中的 Softmax 是对矩阵的每一行进行 Softmax,即每一行的和都变为 1。
得到 Softmax 矩阵之后可以和 V相乘,得到最终的输出 Z。
上图中 Softmax 矩阵的第 1 行表示单词 1 与其他所有单词的 attention 系数,最终单词 1 的输出
Z
1
Z_1
Z1 等于所有单词 i 的值
V
i
V_i
Vi 根据 attention 系数的比例加在一起得到,如下图所示:
另一种诠释方式是将每个词的向量拆出来看:每个词的词向量都是所有词向量value的加权求和,权重则是由Q和K点乘得到的
将多个(8个)attention机制的结果concat在一起,以增加attention机制本身的鲁棒性:
可以看到 Multi-Head Attention 输出的矩阵 Z与其输入的矩阵 X 的维度是一样的。
线性转换→ReLU→线性转换:
Feed Forward 最终得到的输出矩阵的维度与 X 一致。
Decoder预测时输入的内容和输出的对象(使用teacher forcing1思想):
事实上每次的输入都是完整的输出标签,通过mask实现每次模型只看到当前timestep之前的输出:
下面用 0 1 2 3 4 5 分别表示
我认为这个mask之所以要这么搞,是因为整个神经网络模型需要进行矩阵运算,用这样矩阵形式的mask方便进行整个的矩阵运算。
首先进行和之前的self-attention一样的操作,线性转换得到QKV,然后计算QK
T
^T
T:
(KV是通过encoder得到的C计算的,Q是通过decoder上一层输出得到的)
在得到 QKT 之后需要进行 Softmax,计算 attention score,我们在 Softmax 之前需要使用 Mask矩阵遮挡住每一个单词之后的信息,也就是直接把每个timestep对应单词之后的元素值置0:
得到 Mask QK T ^T T 之后进行 Softmax,每一行的和都为 1
使用 Mask QKT 与矩阵 V相乘,得到输出 Z,则单词 1 的输出向量
Z
1
Z_1
Z1 是只包含单词 1 信息的。
得到一个 Mask Self-Attention 的输出矩阵 Zi,然后和 Encoder 类似,通过 Multi-Head Attention 拼接多个输出 Zi 然后计算得到第一个 Multi-Head Attention 的输出 Z,Z与输入 X 维度一样。
整个预测过程在训练时可以同步(直接让每个位置都拟合真实值),但在测试时是autoregressive的,意思是每一步都用encoder的表征+上一步的输出来预测这一步的单词。
Decoder block 最后的部分是利用 Softmax 预测下一个单词,在之前的网络层我们可以得到一个最终的输出 Z,因为 Mask 的存在,使得单词 0 的输出
Z
0
Z_0
Z0 只包含单词 0 的信息,如下:
Softmax 根据输出矩阵的每一行预测下一个单词
相比RNN,Transformer能够比较好地并行训练。
Transformer 中 Multi-Head Attention 中有多个 Self-Attention,可以捕获单词之间多种维度上的相关系数 attention score。
我看的是What is Teacher Forcing for Recurrent Neural Networks?
总之意思就是用真实值而非上一timestep的输出值作为下一timestep的输入,效果会更好。(RNN中就直接切换上一cell的输出值/上一cell位置的真实标签,在Transformer中则通过mask实现) ↩︎