位置ii的预测只能依赖于小于i的这个位置(列)

我们还修改了解码器堆栈中的自注意力子层,以防止位置关注后续位置。这种掩蔽,加上输出嵌入被这个位置偏移的事实,确保了位置 ii 的预测只能依赖于小于 i 的该位置的已知输出。

作者注:每个 tgt 词(行)被允许看到的位置(列)显示在注意掩码下方。在训练期间,单词被屏蔽以专注于后续单词。

防范措施

请注意,函数可以描述为将查询和一组键值对映射到输出,其中查询、键、值和输出都是向量。输出计算为值的加权和,其中分配给每个值的权重由查询与相应键的兼容性函数计算。我们称我们的特别关注为“Scaled Dot-Product attention”。输入由维度为 dk 的查询和键以及维度为 dv 的值组成。我们用所有键计算查询的点积,将每个点积除以 √dk,然后应用 softmax 函数来获得值的权重。

在实际应用中,我们同时计算一组查询的注意力函数,并将它们打包成一个矩阵 QQ。键和值也一起打包成矩阵 KK 和 VV。我们计算输出的矩阵是:

两个最常用的注意功能是加法注意(引用)和点积(乘法)注意。点积注意力与我们的算法相同,只是比例因子是 1/√dk。附加注意使用具有单个隐藏层的前馈网络计算兼容性函数。尽管两者在理论上的复杂性相似,但点积注意力在实践中更快且更节省空间,因为它可以使用高度优化的矩阵乘法代码来实现。

虽然这两种机制对于小 dk 值的表现相似,但对于没有缩放(参​​考)的大 dk 值,加法注意力优于点积注意力。我们怀疑对于较大的dk值,点积的幅度变大,将softmax函数推到其梯度最小的区域(为了说明点积为什么变大,假设qq和kk的分量是均值 0 0、 方差为 11 的独立随机变量。那么它们的点积 qk=∑dki=1qiki,均值为 00,方差为 dk)。

为了抵消这种影响,我们将点积缩放为 1/√dk。

多头注意力使模型能够共同关注来自不同位置的不同代表性子空间的信息。在单个注意力头的情况下,平均会抑制这一点。

其中投影是参数矩阵

在这项工作中,我们使用 h=8h=8 个并行注意力层或头。对于这些层中的每一层没有关联解码输出,我们使用:

由于每个头的维数减少,总计算成本类似于全维单头注意力。

注意力在我们的模型中的应用

Transformers 以三种不同的方式使用多头注意力:

1. 在“encoder-decoder attention”层中,query来自之前的decoder层,记忆keys和values来自encoder的输出。这使得解码器中的每个位置都能够关注输入序列中的所有位置。这模仿了序列到序列模型中典型的编码器-解码器注意机制,如 (ref) 所示。

2. 编码器包含一个自注意力层。在自注意力层中,所有键、值和查询都来自同一个地方,在这种情况下,是编码器中前一层的输出。编码器中的每个位置都可以参与编码器上一层的所有位置。

3. 同样,解码器中的自注意力层允许解码器中的每个位置参与解码器中的所有位置,直到并包括该位置。我们需要阻止解码器中的剩余信息流以保持自动递减功能。我们通过屏蔽(设置为 -∞)与 softmax 输入中的非法连接对应的所有值,在缩放的点积注意力中做到这一点。

位置导向的前馈网络

除了注意力子层,我们的编码器和解码器中的每一层都包含一个完全连接的前馈网络,该网络分别且相同地应用于每个位置。这包括两个线性变换,中间有一个 ReLU 激活。

尽管不同位置的线性变换是相同的,但它们在层与层之间使用不同的参数。另一种描述方式是内核大小为1的两个卷积。输入和输出的维度为dmodel=512,内层的维度为dff=2048。

嵌入和 Softmax

与其他序列转导模型类似,我们使用学习的嵌入将输入标记和输出标记转换为维度 dmodel 的向量。我们还使用通常的学习线性变换和 softmax 函数将解码器输出转换为预测的下一个令牌概率。在我们的模型中,我们在两个嵌入层和 pre-softmax 线性变换之间共享相同的权重矩阵,类似于 (ref)。在嵌入层中,我们将这些权重乘以 √dmodel。

位置代码

由于我们的模型不包含递归和卷积,为了让模型能够利用序列的顺序,我们必须注入一些关于序列中标记的相对或绝对位置的信息。为此,我们在编码器和解码器堆栈底部的输入嵌入中添加“位置编码”。位置编码和embedding的维度dmodel一样,所以两者可以相加。位置编码有很多选择没有关联解码输出,包括学习的和固定的(引用)。

在这项工作中,我们使用不同频率的正弦和余弦函数。

其中 pos 是位置,i 是维度。也就是说,位置编码的每一维对应一个正弦波。波长形成从 2π 到 100002π 的几何级数。我们选择这个函数是因为我们假设它可以让模型轻松学习通过相对位置参与,因为对于任何固定的偏移量 k,PEpos+k 可以表示为 PEpos 的线性函数。

此外,我们将 dropout 应用于编码器和解码器堆栈中嵌入和位置编码的总和。对于基本模型,我们使用 Pdrop=0.1 的比率。

下面的位置编码将根据位置添加一个正弦波。波的频率和偏移在每个维度上都是不同的。

我们还尝试使用学习的位置嵌入 (cite),发现这两个版本产生了几乎相同的结果。我们选择了正弦版本,因为它可以让模型推断出比训练期间遇到的长度更长的序列。

完整模型

在这里,我们定义了一个接受超参数并生成完整模型的函数。

训练

本节描述了我们模型的训练机制。

作者注:我们停下来做个简短的插曲,介绍一些训练标准编码器-解码器模型所需的工具。首先,我们定义一个批处理对象,其中包含用于训练以及构建掩码的 src 和目标语句。

批量和块

作者注:接下来我们创建一个通用的训练和评分函数来跟踪损失。我们传递了一个通用的损失计算函数,它也处理参数更新。

训练循环

训练数据和批次

我们在标准的 WMT 2014 英语-德语数据集上进行训练,该数据集由大约 450 万个句子对组成。句子是使用字节对编码的,具有大约 37,000 个标记的共享源-目标词汇表。对于英语-法语,我们使用了更大的 WMT 2014 英语-法语数据集,该数据集由 3600 万个句子组成,并将标记拆分为 32,000 个单词的词汇表。

句子对按近似的序列长度批处理在一起。每个训练批次包含一组句子对,其中包含大约 25,000 个源标记和 25,000 个目标标记。

作者注:我们将使用 Torch 文本进行批处理。这将在下面详细讨论。在这里,我们在 torchtext 函数中创建批次,以确保我们的批次大小填充到不超过阈值的最大批次大小(如果我们有 8 个 GPU,则为 25000)。

硬件和时间线

我们在具有 8 个 NVIDIA P100 GPU 的机器上训练我们的模型。对于我们的基本模型,使用本文中描述的超参数,每个训练步骤大约需要 0.4 秒。总的来说,我们对基础模型进行了 100,000 步或 12 小时的训练。对于我们的大型模型,步幅为 1.0 秒。大型模型的训练时间为 300,000 步(3.5 天)。

优化器

我们使用了 Adam 优化器(参考),β1=0.9, β2=0.98, =10^-9。我们根据公式在训练期间改变学习率。

图片[1]-位置ii的预测只能依赖于小于i的这个位置(列)-老王博客

这相当于线性增加第一个 warmupsteps warmupsteps 训练步骤的学习率,并按其后步骤的平方根倒数按比例减少。我们使用warmupsteps=4000。

注意:这部分非常重要。需要训练具有此设置的模型。

该模型在不同模型大小和优化超参数下的曲线示例。

正常化

标签平滑

在训练期间,我们使用值为 ls=0.1ls=0.1 的标签平滑(参考)。随着模型学习更多的不确定性,这会伤害混乱,但会提高准确性和 BLEU 分数。

作者注:我们使用 KL div loss 来实现标签平滑。我们不是使用单热目标分布,而是创建一个确信正确单词的分布,而其余的平滑质量分布在整个词汇表中。

在这里,我们可以看到一个基于置信度如何将质量分配给单词的示例。

如果模型对给定的选择非常有信心,标签平滑实际上会开始惩罚模型。

一个例子

我们可以先尝试一个简单的复制任务。给定来自小词汇表的一组随机输入符号,目标是生成相同的符号。

综合数据

损失计算

贪心解码

为简单起见,此代码使用贪婪解码来预测翻译。

一个真实的例子

作者注:现在我们考虑一个使用 IWSLT 的德语-英语翻译任务的真实示例。这个任务比论文中考虑的 WMT 任务要小得多,但它说明了整个系统。我们还展示了如何使用多 GPU 处理使其真正快速。

数据加载

作者注:我们将使用 torchtext 和 spacy 加载数据集以进行标记化。

批量大小对速度有很大影响。我们希望有非常均匀的批次,并且填充绝对最小。为此,我们必须对默认的 torchtext 批处理进行一些改进。这段代码修补了他们的默认批处理,以确保我们搜索足够的句子来找到一个紧凑的批处理。

迭代器

多CPU训练

作者注:最终要真正针对快速训练,我们将使用多个 GPU。这段代码实现了多 GPU 词的生成。它不是特定于变形金刚的,所以我不会详细介绍。这个想法是在训练时将单词生成分成块,在许多不同的 GPU 上并行处理。为此,我们使用 pytorch 并行原语。

复制 – 跨不同 GPU 拆分模块。scatter – 将批次拆分到不同的 GPU 上。parallel_apply – 将模块应用于不同 GPU 上的批次。收集 – 将分散的数据拉回 GPU。nn.DataParallel – 一个特殊的模块包装器,在评估之前调用它们

现在我们创建我们的模型、标准、优化器、数据迭代器和并行化。

现在我们训练模型。我会稍微玩一下热身步骤,但其他所有内容都使用默认参数。在具有 4 个 Tesla V100 的 AWS p3.8xlarge 上,它以每秒约 27,000 个令牌的速度运行,批量大小为 12,000。

培训系统

作者注:一旦训练,我们就可以对模型进行解码以产生一组翻译。这里我们只需要翻译验证集中的第一句话。这个数据集相当小,所以通过贪心搜索的翻译相当准确。

附加组件:BPE、搜索、平均

作者注:所以这主要涵盖了变压器模型本身。我们没有明确涵盖四个领域。我们还在 OpenNMT-py 中实现了所有这些附加功能。

1. BPE/单词。我们可以先使用库将数据预处理为子词单元。请参阅 Rico Sennrich 的 subword-nmt 实现。这些模型会将训练数据转换成这样的东西。

Die Protokoll datei kann heimlich per E-Mail oder FTP an einen bestimmte n Empfnger gesendet werden。

2. 共享嵌入。当使用共享词汇 BPE 时,我们可以在源/目标/生成器之间共享相同的权重向量。详见(引文)。要将其添加到模型中,只需执行此操作。

3. Beam search:这里有点太复杂了。请参阅 OpenNMT-py 中的 pytorch 实现。

4. 模型平均:本文对最后 k 个检查点进行平均以生成集成效果。如果我们有一堆模型,我们可以在事后做。

结果

在 WMT 2014 英德任务中,大型 Transformer 模型(表 2 中的 Transformer (big))比先前报告的最佳模型(包括集成)优于 2.0 BLEU 或更多,建立了一个新的-最先进的模型。高级 BLEU 分数 28.4。该模型的配置列于表 3 的最后一行。在 8 个 P100 GPU 上训练耗时 3.5 天。甚至我们的基础模型也优于所有先前发布的模型和集成,其训练成本只是任何竞争模型的一小部分。

在 WMT 2014 英法翻译任务上,我们的大型模型取得了 41.0 的 BLEU 分数,超过了之前发布的所有单体模型,而训练成本不到之前 state-of- 的 1/4最先进的模型。辍学率 Pdrop=0.1 而不是 0.3 用于为英语到法语训练的 Transformer(大型)模型。

我们在这里编写的代码是基本模型的一个版本。这是该系统的完全训练版本(示例模型)。

通过上一节中的附加扩展,OpenNMT-py 在 EN-DE WMT 上最多复制 26.9。在这里,我已将这些参数加载到我们的重新实现中。

注意可视化

即使使用贪婪解码,翻译也非常好。我们可以进一步可视化这一点,看看每一层注意力会发生什么。

综上所述

作者注:我希望这段代码对未来的研究有用。如果您有任何疑问,请与我们联系。如果您发现此代码有帮助,还请查看我们的其他 OpenNMT 工具。

雷锋字幕组是由AI爱好者组成的翻译团队。汇聚五五名以上的志愿者,分享最新的海外人工智能资讯,交流人工智能技术领域的行业转型和技术创新见解。

团队成员包括大数据专家、算法工程师、图像处理工程师、产品经理、产品运营商、IT顾问、在校师生;志愿者来自IBM、AVL、Adobe、阿里、百度、北京大学、清华大学、香港大学、中科院、南卡罗来纳大学、早稻田大学等国内知名高校和科研院所和国外。

如果你也是爱分享的AI爱好者。欢迎加入雷锋字幕组,学习新知识,分享成长。

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论