本例子是训练了一个 Transformer 模型 用于将葡萄牙语翻译成英语。这是一个高级示例,假定您具备文本生成(text generation)和 注意力机制(attention) 的知识。
Transformer 模型的核心思想是自注意力机制(self-attention)——能注意输入序列的不同位置以计算该序列的表示的能力。Transformer 创建了多层自注意力层(self-attetion layers)组成的堆栈,下文的按比缩放的点积注意力(Scaled dot product attention)和多头注意力(Multi-head attention)部分对此进行了说明。
一个 transformer 模型用自注意力层而非 RNNs 或 CNNs 来处理变长的输入。这种通用架构有一系列的优势:
它不对数据间的时间/空间关系做任何假设。这是处理一组对象(objects)的理想选择(例如,星际争霸单位(StarCraft units))。 层输出可以并行计算,而非像 RNN 这样的序列计算。 远距离项可以影响彼此的输出,而无需经过许多 RNN 步骤或卷积层(例如,参见场景记忆 Transformer(Scene Memory Transformer)) 它能学习长距离的依赖。在许多序列任务中,这是一项挑战。 该架构的缺点是:
对于时间序列,一个单位时间的输出是从整个历史记录计算的,而非仅从输入和当前的隐含状态计算得到。这可能效率较低。 如果输入确实有时间/空间的关系,像文本,则必须加入一些位置编码,否则模型将有效地看到一堆单词。 在此 notebook 中训练完模型后,您将能输入葡萄牙语句子,得到其英文翻译。
startTokenized string is [7915, 1248, 7946, 7194, 13, 2799, 7877]The original string: Transformer is awesome.7915 ----> T1248 ----> ran7946 ----> s7194 ----> former13 ----> is2799 ----> awesome7877 ----> .(1, 50, 512)
Transformer 使用的注意力函数有三个输入:Q(请求(query))、K(主键(key))、V(数值(value))
多头注意力由四部分组成:
线性层并分拆成多头。按比缩放的点积注意力。多头及联。最后一层线性层。每个多头注意力块有三个输入:Q(请求)、K(主键)、V(数值)。这些输入经过线性(Dense)层,并分拆成多头。
Q、K、和 V 被拆分到了多个头,而非单个的注意力头,因为多头允许模型共同注意来自不同表示空间的不同位置的信息。在分拆后,每个头部的维度减少,因此总的计算成本与有着全部维度的单个注意力头相同。
Output:TensorShape([64, 50, 512])
Transformer 模型与标准的具有注意力机制的序列到序列模型(sequence to sequence with attention model),遵循相同的一般模式。
输入语句经过 N 个编码器层,为序列中的每个词/标记生成一个输出。 解码器关注编码器的输出以及它自身的输入(自注意力)来预测下一个词。 编码器层(Encoder layer) 每个编码器层包括以下子层:
多头注意力(有填充遮挡) 点式前馈网络(Point wise feed forward networks)。 每个子层在其周围有一个残差连接,然后进行层归一化。残差连接有助于避免深度网络中的梯度消失问题。
每个子层的输出是 LayerNorm(x + Sublayer(x))。归一化是在 d_model(最后一个)维度完成的。Transformer 中有 N 个编码器层。
Output:TensorShape([64, 43, 512])
解码器层(Decoder layer) 每个解码器层包括以下子层:
遮挡的多头注意力(前瞻遮挡和填充遮挡) 多头注意力(用填充遮挡)。V(数值)和 K(主键)接收编码器输出作为输入。Q(请求)接收遮挡的多头注意力子层的输出。 点式前馈网络 每个子层在其周围有一个残差连接,然后进行层归一化。每个子层的输出是 LayerNorm(x + Sublayer(x))。归一化是在 d_model(最后一个)维度完成的。
Transformer 中共有 N 个解码器层。
当 Q 接收到解码器的第一个注意力块的输出,并且 K 接收到编码器的输出时,注意力权重表示根据编码器的输出赋予解码器输入的重要性。换一种说法,解码器通过查看编码器输出和对其自身输出的自注意力,预测下一个词。参看按比缩放的点积注意力部分的演示。
Output:TensorShape([64, 50, 512])
Output:(64, 62, 512)(TensorShape([64, 26, 512]), TensorShape([64, 8, 26, 62]))
创建 Transformer
Transformer 包括编码器,解码器和最后的线性层。解码器的输出是线性层的输入,返回线性层的输出。
优化器(Optimizer)根据论文中的公式,将 Adam 优化器与自定义的学习速率调度程序(scheduler)配合使用。
Output:Text(0.5, 0, 'Train Step')
损失函数与指标(Loss and metrics)由于目标序列是填充(padded)过的,因此在计算损失函数时,应用填充遮挡非常重要。
训练与检查点(Training and checkpointing)
目标(target)被分成了 tar_inp 和 tar_real。tar_inp 作为输入传递到解码器。tar_real 是位移了 1 的同一个输入:在 tar_inp 中的每个位置,tar_real 包含了应该被预测到的下一个标记(token)。
例如,sentence = "SOS A lion in the jungle is sleeping EOS"
tar_inp = "SOS A lion in the jungle is sleeping"
tar_real = "A lion in the jungle is sleeping EOS"
Transformer 是一个自回归(auto-regressive)模型:它一次作一个部分的预测,然后使用到目前为止的自身的输出来决定下一步要做什么。
在训练过程中,本示例使用了 teacher-forcing 的方法(就像文本生成教程中一样)。无论模型在当前时间步骤下预测出什么,teacher-forcing 方法都会将真实的输出传递到下一个时间步骤上。
当 transformer 预测每个词时,自注意力(self-attention)功能使它能够查看输入序列中前面的单词,从而更好地预测下一个单词。
为了防止模型在期望的输出上达到峰值,模型使用了前瞻遮挡(look-ahead mask)。
葡萄牙语作为输入语言,英语为目标语言
Output:
评估(Evaluate) 以下步骤用于评估:
实践翻译:
输出:Input: este é um problema que temos que resolver.Predicted translation: so this is a problem that we have to solve ...c . to fix .Real translation: this is a problem we have to solve .Input: os meus vizinhos ouviram sobre esta ideia.Predicted translation: my neighbors heard about this idea of an idea .Real translation: and my neighboring homes heard about this idea .Input: vou então muito rapidamente partilhar convosco algumas histórias de algumas coisas mágicas que aconteceram.Predicted translation: so i 'm going to spend a few of you could share with you a few really magic stories that happen .Real translation: so i 'll just share with you some stories very quickly of some magical things that have happened .