总体架构输入EncoderDecoder 模型须知模型参数输入与输出注意Encoder输入Input EmbeddingPositional Encoding输入整合AttentionSelf-AttentionMulti-head Attentionaddnorm线性层Feed ForwardaddnormEncoder block总结Decoder输入Output EmbeddingPositional Encoding输入整合Masked AttentionMasked Multi-Head AttentionMulti-Head Attention线性层结果输出LinearSoftmaxLoss预测参考文档
模型分为Encoder和Decoder两个部分,下图为模型的架构图:
下面,以翻译为例,介绍Transformer的工作过程:
通过Input Embedding和Positional Encoding,将句子表示为编码,记为
对
将Encoder输出的编码信息矩阵
batch_size
批量大小
src_len
Encoder端句子的最大长度
tgt_len
Decoder端句子的最大长度
d_model
词的Embedding Size
d_k (d_q)
矩阵Q、K的列数
d_v
矩阵V的列数
d_ff
Feed Forward的隐藏层个数
src_vocab_size
源端单词个数
tgt_vocab_size
目标端单词个数
1enc_input dec_input dec_output
2['我 是 中国人 P', 'S i am chinese P', 'i am chinese P E'],
3['我 有 一只 猫' , 'S i have a cat', 'i have a cat E']
enc_input
encoder input
dec_input
decoder input
dec_output
decoder output,相当于y_true
对于变量符号,为了方便起见,有重名的情况。比如在Encoder和Decoder中,Attention都有可能使用
使用word2vec,对
因此,Positional Encoding结果的shape为[batch_size, src_len, d_model]。
记Positional Encoding的结果为
shape为[batch_size, src_len, d_model]。
Encoder的Multi-Head Attention由多个Self-Attention组成,Self-Attention接收的是输入(单词的表示向量x组成的矩阵X)或者上一个Encoder block的输出,下面将对Self-Attention进行介绍。
序列
整体计算流程如下:
简而言之,已知
得到
最终结果生成过程:
其中,
需要注意的是,在上述Self-Attention的计算过程中,通常基于mini-batch来进行计算,也就是一次计算多个句子。而一个mini-batch是由多个不等长的句子组成的,我们需要按照mini-batch中最大的句长对剩余的句子进行补齐,比如使用P作为填充字符,这个过程叫做padding。
对
多个Self-Attention的组合,即定义多组
Multi-Head Attention架构图如下:
首先将输入
然后,将8 个输出矩阵
可以看到 Multi-Head Attention 输出的矩阵
残差连接。
对
其过程如下图所示,其中,
两层的线性变换,第一层使用ReLU作为激活函数,第二层不使用激活函数。对应公式如下:
线性变换后,再经过残差连接和Layer Norm处理,得到最终的输出,且维度与输入
对线性变化的结果进行残差连接。
对
通过上面描述的 Multi-Head Attention,、Feed Forward、 Add & Norm 操作可以构造出一个 Encoder block。Encoder block 接收输入矩阵
第一个 Encoder block 的输入为句子单词的表示向量矩阵,后续 Encoder block 的输入是前一个 Encoder block 的输出,最后一个 Encoder block 输出的矩阵就是编码信息矩阵
该结构的主要功能点如下:
包含两个Multi-Head Attention
最后的softmax层计算预测概率
目标序列的前序序列,后续简称dec input。
对dec_input进行word2vec词向量编码,后续简称
同Encoder的Positional Encoding,后续简称
shape为[batch_size, tgt_len, d_model]。
对
Masked Multi-Head Attention整体流程图如下:
mask过程如下,在final mask中,数值为1的将被替换为-inf:
使用final mask矩阵,对scaled scores矩阵进行mask:
基于masked scores进行softmax计算,可以将-inf变为0,得到的矩阵即为每个词之间的权重:
最后,对权重矩阵再进行scale,然后与
将输出结果做残差连接及Layer Normlization后,输入到下一步的Multi-Head Attention。
将该步的结果记为
Encoder的输出结果(矩阵
该步
最后一行蓝色部分未进行padding mask,但是对最后一列必须进行padding mask。
Feed Forward、add、norm与前文类似,不再赘述。
最后输出的结果,其shape为[batch_size, tgt_len, d_model],与最初的输入
将Decoder的输出,通过Linear操作映射为[batch_size, tgt_len, tgt_vocab_size]的矩阵。
通过Softmax计算出概率,然后
使用交叉熵损失函数计算loss。
dec_input的第一个字符为S,然后逐字预测,将概率最大的词加入到dec_input,如果该词是E,则结束。
xxxxxxxxxx
171def greedy_decoder(model, enc_input, start_symbol):
2 # 根据enc_input获取enc_outputs
3 enc_outputs, enc_self_attns = model.encoder(enc_input)
4 dec_input = torch.zeros(1, 0).type_as(enc_input.data)
5 terminal = False
6 next_symbol = start_symbol
7 while not terminal:
8 # 将上一步预测的最大概率的词,作为dec_input
9 dec_input=torch.cat([dec_input,torch.tensor([[next_symbol]],dtype=enc_input.dtype)],-1)
10 dec_outputs, _, _ = model.decoder(dec_input, enc_input, enc_outputs)
11 projected = model.projection(dec_outputs)
12 prob = projected.squeeze(0).max(dim=-1, keepdim=False)[1]
13 next_word = prob.data[-1]
14 next_symbol = next_word
15 if next_symbol == word2idx["E"]:
16 terminal = True
17 return dec_input