目录

  • 矩阵维度分析
  • 训练阶段
  • 预测阶段
  • Multihead Attention解析
  • 训练阶段
  • Encoder Multihead Attention
  • Masked Multihead Attention
  • Encoder-Decoder Multihead Attention
  • 预测阶段
  • Encoder Multihead Attention
  • Masked Multihead Attention
  • Encoder-Decoder Multihead Attention



解读Transformer就离不开下面这张图:


rnn输入维度 transformer输入输出维度_神经网络

不同于之前的基于rnn的seq2seq模型,Transfomer完全摒弃了循环神经网络的结构:

  1. encoder层: {多头自注意力 + 前馈网络} rnn输入维度 transformer输入输出维度_数据_02
  2. decoder层: {Masked 多头自注意力 + encoder-decoder多头自注意力 + 前馈网络} rnn输入维度 transformer输入输出维度_数据_02

下面我们介绍Transformer模型中的矩阵维度变化情况:

矩阵维度分析

对于一个batch的数据,encoder端的输入大小为:(batch_size, sr_len);decoder端的输入大小为:(batch_size, tar_len)。不妨假设 encoder layer 及 decoder layer 都只有一层,下面是训练阶段的矩阵维度变化:

训练阶段

训练阶段 Encoder

input_size

Layer

output_size

Layer_parameter_size

Note

batch_size

Input Embedding

batch_size sr_len

sr_vocab_size

Embedding层的参数即可设为可学习的,也可设为固定参数

batch_size sr_len

Postion Embedding

batch_size sr_len

1 sr_len

固定参数

batch_size sr_len

MultiHead Attention

batch_size sr_len

{embed_size hidden_size} 3 + {hidden_size

可学习参数

batch_size sr_len

AddNorm1

batch_size sr_len

None

batch_size sr_len

Feed Forward

batch_size sr_len

{hidden_size filter_size} + {filter_size

可学习参数

batch_size sr_len

AddNorm2

batch_size sr_len

None

训练阶段 Decoder

input_size

Layer

output_size

Layer_parameter_size

Note

batch_size

Output Embedding

batch_size tar_len

tar_vocab_size

Embedding层的参数即可设为可学习的,也可设为固定参数

batch_size tar_len

Postion Embedding

batch_size tar_len

1 tar_len

固定参数

batch_size tar_len

Masked MultiHead Attention

batch_size tar_len

{embed_size hidden_size} 3 + {hidden_size

可学习参数

batch_size tar_len

AddNorm1

batch_size tar_len

None

batch_size tar_len

Encoder-Decoder MultiHead Attention

batch_size tar_len

{hidden_size hidden_size}

可学习参数

batch_size tar_len

AddNorm2

batch_size tar_len

None

batch_size tar_len

Feed Forward

batch_size tar_len

{hidden_size filter_size} + {filter_size

可学习参数

batch_size tar_len

AddNorm3

batch_size tar_len

None

注意到,为了保持encoder及decoder的层可以堆叠,需要保证每个层的输入和输出的维度一致,因此,需要保证 embed_size = hidden_size


预测阶段

预测阶段的 encoder 与训练阶段是相同的,只是 batch_size = 1;而 decoder 部分由于每个 step 只能看到当前位置之前的信息,因此每次输入的 tar_len 也等于 1。

预测阶段 Decoder

input_size

Layer

output_size

1

Output Embedding

1 1

1 1

Postion Embedding

1 1

1 $\times$1

Masked MultiHead Attention

1 1

1 1

AddNorm1

1 1

1 1

Encoder-Decoder MultiHead Attention

1 1

1 1

AddNorm2

1 1

1 1

Feed Forward

1 1

1 1

AddNorm3

1 1


Multihead Attention解析

训练阶段

Encoder Multihead Attention

rnn输入维度 transformer输入输出维度_rnn输入维度_106

  1. Input: Encoder Multihead Attention 输入的 query, key, value 是相同的,都是经过了word embedding和pos embedding之后的 source sentence,其维度为 rnn输入维度 transformer输入输出维度_数据_107 。由于有 num_heads 个头需要并行计算,首先 query, key, value 分别经过一个线性变换,再将数据 split 给 num_heads 个头分别做注意力查询,即:
    rnn输入维度 transformer输入输出维度_神经网络_108

由于query, key, value 是相同的,因此有 sr_len_q = sr_len_k = sr_len_v

  1. DotProductAttention: num_heads 个头的计算是并行的,即:
    rnn输入维度 transformer输入输出维度_深度学习_109

Encoder Multihead Attention 中在计算 softmax 之前对 key 进行了 mask,目的是消除 padding 的影响。事实上 padding 不仅对 key 有影响,对 query 也有影响,但在实际代码中 mask 仅针对 key,而没有针对 query。其实最原始代码是既有 key mask,也有query mask的,但后来作者将 query mask 删去了,因为在最后计算 loss 的时候对 padding 位置的 loss 进行mask,也可达到相同的效果。

假设 batch_size = num_heads = 1,sr_len_q = sr_len_k = 6,source sentence 的最后两个位置是padding,那么Encoder Multihead Attention 中的 mask 为:
rnn输入维度 transformer输入输出维度_神经网络_110
即只对 key 的 padding 位置进行了 mask

  1. Output: 需要将上面输出的 num_heads 个头的结果堆叠之后,再做一个线性变换:
    rnn输入维度 transformer输入输出维度_深度学习_111

Masked Multihead Attention

与 Encoder Multihead Attention 类似,Masked Multihead Attention 输入的 query, key, value 也是相同的,都是经过了word embedding和pos embedding之后的 target sentence。包括后面的计算流程也基本一致。

主要的区别在于:由于在 inference 时,每个 step 位置只能看到它之前的 steps 的信息,而看不到它之后的 steps的信息。因此 Masked Multihead Attention 中的 mask 除了要消除 key 信息里 padding 的影响,还需要消除当前 step 后面的所有 step 的信息:

假设 batch_size = num_heads = 1,tar_len_q = tar_len_k = 5,target sentence 的最后两个位置是 padding,那么Masked Multihead Attention 中的 mask 为:
rnn输入维度 transformer输入输出维度_神经网络_112
注意到上述 mask 并不是一个单纯的下三角矩阵,因为最后两个位置都是padding,因此无论如何都要被 mask 掉


Encoder-Decoder Multihead Attention

  1. Input: Encoder-Decoder Multihead Attention 输入的 query 来自于 target sentence,其维度为 rnn输入维度 transformer输入输出维度_rnn输入维度_113 ;而 key 和 value 则来自于 encoder layer 的输出,其维度为 rnn输入维度 transformer输入输出维度_数据_107 。同样是先做线性变换,再 split 成 num_heads 个头:
    rnn输入维度 transformer输入输出维度_rnn输入维度_115

这里 sr_len_q rnn输入维度 transformer输入输出维度_神经网络_116

  1. DotProductAttention: num_heads 个头的计算依然可以并行:
    rnn输入维度 transformer输入输出维度_神经网络_117

假设 batch_size = num_heads = 1,这里sr_len_q可以不等于sr_len_k,不妨假设 sr_len_q = 5,sr_len_k = 6,因为 mask 只针对key,因此这里只需要关注 source sentence 中的padding, 假设 source sentence 的最后两个位置是padding,那么Masked Multihead Attention 中的 mask 为:
rnn输入维度 transformer输入输出维度_循环神经网络_118

  1. Output: 需要将上面输出的 num_heads 个头的结果堆叠之后,再做一个线性变换:
    rnn输入维度 transformer输入输出维度_神经网络_119

预测阶段

Encoder Multihead Attention

与训练阶段的 Encoder Multihead Attention 完全相同

Masked Multihead Attention

虽然在训练阶段,Masked Multihead Attention 会将当前 step 之后的 steps 信息都 mask 掉,但是由于训练时整个 target sentence 都是已知的,因此还是可以做并行运算的。

但是在预测阶段,初始的 query, key, value 都只是一个 “<bos>” 起始符号,之后每预测出一个 token,这个 token 直接作为下一个 step 输入的 query,而将这个 token 拼在现有的 key 和 value 之后,就是下一个 step 输入的 key 和 value。也就是说,预测阶段每个 step 输入的 query 是上一 step 输出的token,而 key, value 是之前所有 steps 输出的token

至于 mask 的部分,由于输入中不再含有未来 steps 的信息,因此不再需要用 mask 来消除这部分信息。而对于 key mask,由于 Masked Multihead Attention 的 key 是 target sentence,而在预测完成前 target sentence 的长度是未知的,因此针对 key 的 mask 也是不需要的也就是说,Masked Multihead Attention 是不需要 mask 的

下面是预测阶段 Masked Multihead Attention 的流程:

  1. Input: key, value 是到当前 step 为止的所有 steps 的信息,大小为 1 rnn输入维度 transformer输入输出维度_rnn输入维度_120 cur_tar_len rnn输入维度 transformer输入输出维度_rnn输入维度_120 hidden_size;而 query 是上一 step 的输出 token,大小为 1 rnn输入维度 transformer输入输出维度_rnn输入维度_120 1 rnn输入维度 transformer输入输出维度_rnn输入维度_120 hidden_size:
    rnn输入维度 transformer输入输出维度_深度学习_124
  2. DotProductAttention: num_heads 个头的计算依然可以并行:
    rnn输入维度 transformer输入输出维度_rnn输入维度_125
  3. Output: 需要将上面输出的 num_heads 个头的结果堆叠之后,再做一个线性变换:
    rnn输入维度 transformer输入输出维度_循环神经网络_126

Encoder-Decoder Multihead Attention

预测阶段 Encoder-Decoder Multihead Attention 输入的 query 是上一层 Masked Multihead Attention 的输出,大小为 1rnn输入维度 transformer输入输出维度_神经网络_127 1 rnn输入维度 transformer输入输出维度_神经网络_127 hidden_size。而输入的 key 和 value 则是 encoder layer 的输出,大小为:1 rnn输入维度 transformer输入输出维度_神经网络_127 sr_len rnn输入维度 transformer输入输出维度_神经网络_127

  1. Input:
    rnn输入维度 transformer输入输出维度_神经网络_131
  2. DotProductAttention: num_heads 个头的计算并行:
    rnn输入维度 transformer输入输出维度_深度学习_132

假设 num_heads = 1,sr_len_k = 6,因为 mask 只针对key,因此这里只需要关注 source sentence 中的padding, 假设 source sentence 的最后两个位置是padding,那么Masked Multihead Attention 中的 mask 为:
rnn输入维度 transformer输入输出维度_深度学习_133

  1. Output: 需要将上面输出的 num_heads 个头的结果堆叠之后,再做一个线性变换:
    rnn输入维度 transformer输入输出维度_数据_134

由于最后的 Feed Forward 层不改变矩阵大小,至此可以总结一下预测阶段的 Decoder layer,输入是上一 step 输出的 token,大小为 1 rnn输入维度 transformer输入输出维度_rnn输入维度_135 1 rnn输入维度 transformer输入输出维度_rnn输入维度_135 hidden_size,经过两种MultiHead + Feed Forward 后,大小依然为 1 rnn输入维度 transformer输入输出维度_rnn输入维度_135 1 rnn输入维度 transformer输入输出维度_rnn输入维度_135