初识Transformer之Attention is all you need

文章目录

  • 前言
  • 一、初识ransformer
    • 从宏观视角看自注意力机制
    • 从微观视角看自注意力机制
    • 什么是查询向量、键向量和值向量向量?
    • 通过矩阵运算实现自注意力机制
    • 使用位置编码表示序列的顺序
    • 残差模块
    • 解码组件
    • 最终的线性变换和Softmax层
    • 训练部分总结
  • 二、Attention is all you need 翻译
    • 1 简介
    • 2 背景
    • 3 模型架构
      • 3.1 编码器和解码器堆栈
      • 3.2 Attention
        • 3.2.1 缩放的点积attention
        • 3.2.2 Multi-Head Attention
        • 3.2.3 Applications of Attention in our Model
      • 3.3 基于位置的前馈网络
      • 3.4 嵌入和Softmax
      • 3.5 位置编码
    • 4 为什么选择Self-Attention
    • 5 训练
      • 5.1 训练数据和批次
      • 5.2 硬件和时间


前言

本篇是自己开始认识Transformer写的第一篇学习笔记


一、初识ransformer

李宏毅老师讲的transformer非常好,让Attention is all you need 秒懂Transformer

Transformer由论文《Attention is All You Need》提出Transformer 是 Google 团队在 2017 年提出的一种 NLP 经典模型,现在比较火热的 Bert 也是基于 Transformer。Transformer 模型核心是 Self-Attention 机制,不采用RNN顺序结构,使得模型可以并行化训练,而且能够拥有全局信息,CNN的核心模块是conv。

1.transformer在分类上的应用:VIT,An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale
初识Transformer之Attention is all you need_第1张图片
把图像分成固定大小的patchs,把patchs看成words送入transformer的encoder,中间没有任何卷积操作,增加一个class token来预测分类类别。

2.transformer在检测上的应用DETR:End-to-End Object Detection with Transformers
初识Transformer之Attention is all you need_第2张图片
先用CNN提取特征,然后把最后特征图的每个点看成word,这样特征图就变成了a sequence words,而检测的输出恰好是a set objects,所以transformer正好适合这个任务。

3.transformer在分割上的应用SETR:Rethinking Semantic Segmentation from a Sequence-to-Sequence Perspective with Transformers
初识Transformer之Attention is all you need_第3张图片
用ViT作为的图像的encoder,然后加一个CNN的decoder来完成语义图的预测。
参考:如何看待transformer在CV上的应用

在《Attention is All You Need》中,经过Transformer模块,输入一种语言,输出另一种语言完成机器翻译任务。
初识Transformer之Attention is all you need_第4张图片
Transformer板块是由编码组件、解码组件和它们之间的连接组成。
初识Transformer之Attention is all you need_第5张图片
编码组件部分由一堆编码器(encoder)构成(论文中是将6个编码器叠在一起——数字6没有什么神奇之处,你也可以尝试其他数字)。解码组件部分也是由相同数量(与编码器对应)的解码器(decoder)组成的。
初识Transformer之Attention is all you need_第6张图片
所有的编码器在结构上都是相同的,但它们没有共享参数。每个解码器都可以分解成两个子层。
初识Transformer之Attention is all you need_第7张图片
从编码器输入的句子首先会经过一个自注意力(self-attention)层,这层帮助编码器在对每个单词编码时关注输入句子的其他单词。自注意力层的输出会传递到前馈(feed-forward)神经网络中。每个位置的单词对应的前馈神经网络都完全一样。
解码器中也有编码器的自注意力(self-attention)层和前馈(feed-forward)层。除此之外,这两个层之间还有一个注意力层,用来关注输入句子的相关部分(和seq2seq模型的注意力作用相似)。
初识Transformer之Attention is all you need_第8张图片
我们已经了解了模型的主要部分,接下来我们看一下各种向量或张量(译注:张量概念是矢量概念的推广,可以简单理解矢量是一阶张量、矩阵是二阶张量。)是怎样在模型的不同部分中,将输入转化为输出的。
像大部分NLP应用一样,我们首先将每个输入单词通过词嵌入算法转换为词向量。
在这里插入图片描述
每个单词都被嵌入为512维的向量,我们用这些简单的方框来表示这些向量。

词嵌入过程只发生在最底层的编码器中。所有的编码器都有一个相同的特点,即它们接收一个向量列表,列表中的每个向量大小为512维。在底层(最开始)编码器中它就是词向量,但是在其他编码器中,它就是下一层编码器的输出(也是一个向量列表)。向量列表大小是我们可以设置的超参数——一般是我们训练集中最长句子的长度。

将输入序列进行词嵌入之后,每个单词都会流经编码器中的两个子层。
初识Transformer之Attention is all you need_第9张图片
接下来我们看看Transformer的一个核心特性,在这里输入序列中每个位置的单词都有自己独特的路径流入编码器。在自注意力层中,这些路径之间存在依赖关系。而前馈(feed-forward)层没有这些依赖关系。因此在前馈(feed-forward)层时可以并行执行各种路径。
然后我们将以一个更短的句子为例,看看编码器的每个子层中发生了什么。

如上述已经提到的,一个编码器接收向量列表作为输入,接着将向量列表中的向量传递到自注意力层进行处理,然后传递到前馈神经网络层中,将输出结果传递到下一个编码器中。
初识Transformer之Attention is all you need_第10张图片
输入序列的每个单词都经过自编码过程。然后,他们各自通过前向传播神经网络——完全相同的网络,而每个向量都分别通过它。

从宏观视角看自注意力机制

例如,下列句子是我们想要翻译的输入句子:
The animal didn’t cross the street because it was too tired

这个“it”在这个句子是指什么呢?它指的是street还是这个animal呢?这对于人类来说是一个简单的问题,但是对于算法则不是。

当模型处理这个单词“it”的时候,自注意力机制会允许“it”与“animal”建立联系。

随着模型处理输入序列的每个单词,自注意力会关注整个输入序列的所有单词,帮助模型对本单词更好地进行编码。如果你熟悉RNN(循环神经网络),回忆一下它是如何维持隐藏层的。RNN会将它已经处理过的前面的所有单词/向量的表示与它正在处理的当前单词/向量结合起来。而自注意力机制会将所有相关单词的理解融入到我们正在处理的单词中。

初识Transformer之Attention is all you need_第11张图片
当我们在编码器#5(栈中最上层编码器)中编码“it”这个单词的时,注意力机制的部分会去关注“The Animal”,将它的表示的一部分编入“it”的编码中。

从微观视角看自注意力机制

首先我们了解一下如何使用向量来计算自注意力,然后来看它是怎样用矩阵来实现。

计算自注意力的第一步就是从每个编码器的输入向量(每个单词的词向量)中生成三个向量。也就是说对于每个单词,我们创造一个查询向量、一个键向量和一个值向量。这三个向量是通过词嵌入与三个权重矩阵后相乘创建的。

可以发现这些新向量在维度上比词嵌入向量更低。他们的维度是64,而词嵌入和编码器的输入/输出向量的维度是512. 但实际上不强求维度更小,这只是一种基于架构上的选择,它可以使多头注意力(multiheaded attention)的大部分计算保持不变。
初识Transformer之Attention is all you need_第12张图片
X1与WQ权重矩阵相乘得到q1, 就是与这个单词相关的查询向量。最终使得输入序列的每个单词的创建一个查询向量、一个键向量和一个值向量。

什么是查询向量、键向量和值向量向量?

它们都是有助于计算和理解注意力机制的抽象概念。请继续阅读下文的内容,你就会知道每个向量在计算注意力机制中到底扮演什么样的角色。

计算自注意力的第二步是计算得分。假设我们在为这个例子中的第一个词“Thinking”计算自注意力向量,我们需要拿输入句子中的每个单词对“Thinking”打分。这些分数决定了在编码单词“Thinking”的过程中有多重视句子的其它部分。

这些分数是通过打分单词(所有输入句子的单词)的键向量与“Thinking”的查询向量相点积来计算的。所以如果我们是处理位置最靠前的词的自注意力的话,第一个分数是q1和k1的点积,第二个分数是q1和k2的点积。
初识Transformer之Attention is all you need_第13张图片
第三步和第四步是将分数除以8(8是论文中使用的键向量的维数64的平方根,这会让梯度更稳定。这里也可以使用其它值,8只是默认值),然后通过softmax传递结果。softmax的作用是使所有单词的分数归一化,得到的分数都是正值且和为1。
初识Transformer之Attention is all you need_第14张图片
这个softmax分数决定了每个单词对编码当下位置(“Thinking”)的贡献。显然,已经在这个位置上的单词将获得最高的softmax分数,但有时关注另一个与当前单词相关的单词也会有帮助。

第五步是将每个值向量乘以softmax分数(这是为了准备之后将它们求和)。这里的直觉是希望关注语义上相关的单词,并弱化不相关的单词(例如,让它们乘以0.001这样的小数)。

第六步是对加权值向量求和(译注:自注意力的另一种解释就是在编码某个单词时,就是将所有单词的表示(值向量)进行加权求和,而权重是通过该词的表示(键向量)与被编码词表示(查询向量)的点积并通过softmax得到。),然后即得到自注意力层在该位置的输出(在我们的例子中是对于第一个单词)。
初识Transformer之Attention is all you need_第15张图片
这样自自注意力的计算就完成了。得到的向量就可以传给前馈神经网络。然而实际中,这些计算是以矩阵形式完成的,以便算得更快。那我们接下来就看看如何用矩阵实现的。

通过矩阵运算实现自注意力机制

第一步是计算查询矩阵、键矩阵和值矩阵。为此,我们将将输入句子的词嵌入装进矩阵X中,将其乘以我们训练的权重矩阵(WQ,WK,WV)。
初识Transformer之Attention is all you need_第16张图片
x矩阵中的每一行对应于输入句子中的一个单词。我们再次看到词嵌入向量 (512,或图中的4个格子)和q/k/v向量(64,或图中的3个格子)的大小差异。

最后,由于我们处理的是矩阵,我们可以将步骤2到步骤6合并为一个公式来计算自注意力层的输出。

初识Transformer之Attention is all you need_第17张图片
自注意力的矩阵运算形式

通过增加一种叫做“多头”注意力(“multi-headed” attention)的机制,论文进一步完善了自注意力层,并在两方面提高了注意力层的性能:

1.它扩展了模型专注于不同位置的能力。在上面的例子中,虽然每个编码都在z1中有或多或少的体现,但是它可能被实际的单词本身所支配。如果我们翻译一个句子,比如“The animal didn’t cross the street because it was too tired”,我们会想知道“it”指的是哪个词,这时模型的“多头”注意机制会起到作用。

2.它给出了注意力层的多个“表示子空间”(representation subspaces)。接下来我们将看到,对于“多头”注意机制,我们有多个查询/键/值权重矩阵集(Transformer使用八个注意力头,因此我们对于每个编码器/解码器有八个矩阵集合)。这些集合中的每一个都是随机初始化的,在训练之后,每个集合都被用来将输入词嵌入(或来自较低编码器/解码器的向量)投影到不同的表示子空间中。
初识Transformer之Attention is all you need_第18张图片
在“多头”注意机制下,我们为每个头保持独立的查询/键/值权重矩阵,从而产生不同的查询/键/值矩阵。和之前一样,我们拿X乘以WQ/WK/WV矩阵来产生查询/键/值矩阵。

如果我们做与上述相同的自注意力计算,只需八次不同的权重矩阵运算,我们就会得到八个不同的Z矩阵。
初识Transformer之Attention is all you need_第19张图片
这给我们带来了一点挑战。前馈层不需要8个矩阵,它只需要一个矩阵(由每一个单词的表示向量组成)。所以我们需要一种方法把这八个矩阵压缩成一个矩阵。那该怎么做?其实可以直接把这些矩阵拼接在一起,然后用一个附加的权重矩阵WO与它们相乘。
初识Transformer之Attention is all you need_第20张图片
这几乎就是多头自注意力的全部。这确实有好多矩阵,我们试着把它们集中在一个图片中,这样可以一眼看清。
初识Transformer之Attention is all you need_第21张图片
既然我们已经摸到了注意力机制的这么多“头”,那么让我们重温之前的例子,看看我们在例句中编码“it”一词时,不同的注意力“头”集中在哪里
初识Transformer之Attention is all you need_第22张图片
当我们编码“it”一词时,一个注意力头集中在“animal”上,而另一个则集中在“tired”上,从某种意义上说,模型对“it”一词的表达在某种程度上是“animal”和“tired”的代表。

然而,如果我们把所有的attention都加到图示里,事情就更难解释了:
初识Transformer之Attention is all you need_第23张图片

使用位置编码表示序列的顺序

到目前为止,我们对模型的描述缺少了一种理解输入单词顺序的方法。

为了解决这个问题,Transformer为每个输入的词嵌入添加了一个向量。这些向量遵循模型学习到的特定模式,这有助于确定每个单词的位置,或序列中不同单词之间的距离。这里的直觉是,将位置向量添加到词嵌入中使得它们在接下来的运算中,能够更好地表达的词与词之间的距离。
初识Transformer之Attention is all you need_第24张图片
为了让模型理解单词的顺序,我们添加了位置编码向量,这些向量的值遵循特定的模式。

如果我们假设词嵌入的维数为4,则实际的位置编码如下:
初识Transformer之Attention is all you need_第25张图片
尺寸为4的迷你词嵌入位置编码实例

这个模式会是什么样子?

在下图中,每一行对应一个词向量的位置编码,所以第一行对应着输入序列的第一个词。每行包含512个值,每个值介于1和-1之间。我们已经对它们进行了颜色编码,所以图案是可见的。
初识Transformer之Attention is all you need_第26张图片
20字(行)的位置编码实例,词嵌入大小为512(列)。你可以看到它从中间分裂成两半。这是因为左半部分的值由一个函数(使用正弦)生成,而右半部分由另一个函数(使用余弦)生成。然后将它们拼在一起而得到每一个位置编码向量。

原始论文里描述了位置编码的公式(第3.5节)。你可以在 get_timing_signal_1d()中看到生成位置编码的代码。这不是唯一可能的位置编码方法。然而,它的优点是能够扩展到未知的序列长度(例如,当我们训练出的模型需要翻译远比训练集里的句子更长的句子时)。

残差模块

在继续进行下去之前,我们需要提到一个编码器架构中的细节:在每个编码器中的每个子层(自注意力、前馈网络)的周围都有一个残差连接,并且都跟随着一个“层-归一化”步骤。
初识Transformer之Attention is all you need_第27张图片
层-归一化步骤:https://arxiv.org/abs/1607.06450
如果我们去可视化这些向量以及这个和自注意力相关联的层-归一化操作,那么看起来就像下面这张图描述一样:
初识Transformer之Attention is all you need_第28张图片
解码器的子层也是这样样的。如果我们想象一个2 层编码-解码结构的transformer,它看起来会像下面这张图一样:
初识Transformer之Attention is all you need_第29张图片

解码组件

既然我们已经谈到了大部分编码器的概念,那么我们基本上也就知道解码器是如何工作的了。但最好还是看看解码器的细节。

编码器通过处理输入序列开启工作。顶端编码器的输出之后会变转化为一个包含向量K(键向量)和V(值向量)的注意力向量集 。这些向量将被每个解码器用于自身的“编码-解码注意力层”,而这些层可以帮助解码器关注输入序列哪些位置合适:
初识Transformer之Attention is all you need_第30张图片
在完成编码阶段后,则开始解码阶段。解码阶段的每个步骤都会输出一个输出序列(在这个例子里,是英语翻译的句子)的元素

接下来的步骤重复了这个过程,直到到达一个特殊的终止符号,它表示transformer的解码器已经完成了它的输出。每个步骤的输出在下一个时间步被提供给底端解码器,并且就像编码器之前做的那样,这些解码器会输出它们的解码结果 。另外,就像我们对编码器的输入所做的那样,我们会嵌入并添加位置编码给那些解码器,来表示每个单词的位置。

而那些解码器中的自注意力层表现的模式与编码器不同:在解码器中,自注意力层只被允许处理输出序列中更靠前的那些位置。在softmax步骤前,它会把后面的位置给隐去(把它们设为-inf)。

这个“编码-解码注意力层”工作方式基本就像多头自注意力层一样,只不过它是通过在它下面的层来创造查询矩阵,并且从编码器的输出中取得键/值矩阵。

最终的线性变换和Softmax层

解码组件最后会输出一个实数向量。我们如何把浮点数变成一个单词?这便是线性变换层要做的工作,它之后就是Softmax层。

线性变换层是一个简单的全连接神经网络,它可以把解码组件产生的向量投射到一个比它大得多的、被称作对数几率(logits)的向量里。

不妨假设我们的模型从训练集中学习一万个不同的英语单词(我们模型的“输出词表”)。因此对数几率向量为一万个单元格长度的向量——每个单元格对应某一个单词的分数。

接下来的Softmax 层便会把那些分数变成概率(都为正数、上限1.0)。概率最高的单元格被选中,并且它对应的单词被作为这个时间步的输出。
初识Transformer之Attention is all you need_第31张图片
这张图片从底部以解码器组件产生的输出向量开始。之后它会转化出一个输出单词。

训练部分总结

既然我们已经过了一遍完整的transformer的前向传播过程,那我们就可以直观感受一下它的训练过程。

在训练过程中,一个未经训练的模型会通过一个完全一样的前向传播。但因为我们用有标记的训练集来训练它,所以我们可以用它的输出去与真实的输出做比较。

为了把这个流程可视化,不妨假设我们的输出词汇仅仅包含六个单词:“a”, “am”, “i”, “thanks”, “student”以及 “”(end of sentence的缩写形式)。
初识Transformer之Attention is all you need_第32张图片
我们模型的输出词表在我们训练之前的预处理流程中就被设定好。

一旦我们定义了我们的输出词表,我们可以使用一个相同宽度的向量来表示我们词汇表中的每一个单词。这也被认为是一个one-hot 编码。所以,我们可以用下面这个向量来表示单词“am”:
初识Transformer之Attention is all you need_第33张图片
例子:对我们输出词表的one-hot 编码

接下来我们讨论模型的损失函数——这是我们用来在训练过程中优化的标准。通过它可以训练得到一个结果尽量准确的模型。
损失函数
比如说我们正在训练模型,现在是第一步,一个简单的例子——把“merci”翻译为“thanks”。

这意味着我们想要一个表示单词“thanks”概率分布的输出。但是因为这个模型还没被训练好,所以不太可能现在就出现这个结果
初识Transformer之Attention is all you need_第34张图片
因为模型的参数(权重)都被随机的生成,(未经训练的)模型产生的概率分布在每个单元格/单词里都赋予了随机的数值。我们可以用真实的输出来比较它,然后用反向传播算法来略微调整所有模型的权重,生成更接近结果的输出。

你会如何比较两个概率分布呢?我们可以简单地用其中一个减去另一个。更多细节请参考交叉熵和KL散度。
但注意到这是一个过于简化的例子。更现实的情况是处理一个句子。例如,输入“je suis étudiant”并期望输出是“i am a student”。那我们就希望我们的模型能够成功地在这些情况下输出概率分布:

每个概率分布被一个以词表大小(我们的例子里是6,但现实情况通常是3000或10000)为宽度的向量所代表。

第一个概率分布在与“i”关联的单元格有最高的概率

第二个概率分布在与“am”关联的单元格有最高的概率

以此类推,第五个输出的分布表示“”关联的单元格有最高的概率
初识Transformer之Attention is all you need_第35张图片
依据例子训练模型得到的目标概率分布

在一个足够大的数据集上充分训练后,我们希望模型输出的概率分布看起来像这个样子:
初识Transformer之Attention is all you need_第36张图片
我们期望训练过后,模型会输出正确的翻译。当然如果这段话完全来自训练集,它并不是一个很好的评估指标(参考:交叉验证,链接https://www.youtube.com/watch?v=TIgfjmp-4BA)。注意到每个位置(词)都得到了一点概率,即使它不太可能成为那个时间步的输出——这是softmax的一个很有用的性质,它可以帮助模型训练。

因为这个模型一次只产生一个输出,不妨假设这个模型只选择概率最高的单词,并把剩下的词抛弃。这是其中一种方法(叫贪心解码)。另一个完成这个任务的方法是留住概率最靠高的两个单词(例如I和a),那么在下一步里,跑模型两次:其中一次假设第一个位置输出是单词“I”,而另一次假设第一个位置输出是单词“me”,并且无论哪个版本产生更少的误差,都保留概率最高的两个翻译结果。然后我们为第二和第三个位置重复这一步骤。这个方法被称作集束搜索(beam search)。在我们的例子中,集束宽度是2(因为保留了2个集束的结果,如第一和第二个位置),并且最终也返回两个集束的结果(top_beams也是2)。这些都是可以提前设定的参数。

二、Attention is all you need 翻译

摘要:主流序列转导模型基于复杂的循环神经网络或卷积神经网络,这些神经网络包含一个编码器和一个解码器。 性能最好的模型还通过attention机制将编码器和解码器连接起来。 我们提出一种新的简单的网络架构Transformer,仅基于attention机制并完全避免循环和卷积。 对两个机器翻译任务的实验表明,这些模型在质量上更加优越、并行性更好并且需要的训练时间显著减少。 我们的模型在WMT 2014英语-德语翻译任务上达到28.4 BLEU,超过现有最佳结果(包括整合模型)2个BLEU。 在WMT 2014英语-法语翻译任务中,我们的模型建立了单模型新的最先进的BLEU分数41.8,它在8个GPU上训练了3.5天,这个时间只是目前文献中记载的最好的模型训练成本的一小部分。 通过在解析大量训练数据和有限训练数据的两种情况下将其应用到English constituency,我们表明Transformer可以很好地推广到其他任务。

1 简介

  在序列建模和转换问题中,如语言建模和机器翻译[35, 2, 5],循环神经网络特别是长短期记忆[13]和门控循环[7]神经网络,已经被确立为最先进的方法。 自那以后,许多努力一直在推动循环语言模型和编码器-解码器架构的界限[38, 24, 15]。
  循环模型通常是对输入和输出序列的符号位置进行因子计算。通过在计算期间将位置与步骤对齐,循环模型根据前一步的隐藏状态 和输入,产生位置t的隐藏状态序列 。这种固有的顺序特性阻碍了样本训练的并行化,这在更长的序列长度上变得至关重要,因为有限的内存会限制样本的批次大小。 最近的工作通过巧妙的因子分解[21]和条件计算[32],在计算效率方面取得重大进展,后者还同时提高了模型性能。 然而,顺序计算的基本约束依然存在。
  在各种任务中,attention机制已经成为序列建模和转换模型不可或缺的一部分,它可以建模依赖关系而不考虑其在输入或输出序列中的距离[2, 19]。 除少数情况外[27],这种attention机制都与循环网络一起使用。
  在这项工作中,我们提出了Transformer,这种模型架构不使用循环网络结构,而是完全依赖于attention机制来表示输入和输出之间的全局依赖关系。Transformer允许进行更多的并行化,并且可以在八个P100 GPU上进行十二小时的训练后达到翻译质量的新的最佳结果。

2 背景

  减少序列计算的目标也构成了扩展的神经网络GPU [16],ByteNet [18]和ConvS2S [9]的基础,它们都使用卷积神经网络作为基本构建模块,并行计算所有输入和输出位置的隐藏表示。在这些模型中,关联任意两个输入或输出位置的信号所需的操作次数会随着位置之间的距离而增加,ConvS2S是线性增加,而ByteNet是对数增加。这使得学习远距离之间的依赖关系变得更加困难[12]。在Transformer中,关联两个输入或输出位置的信号所需的操作次数可以减少到固定的次数,尽管由于用attention权重化的位置取平均降低了效果,但是我们使用Multi-Head Attention抵消了效果降低,具体描述见 3.2。
  Self-attention,有时称为intra-attention,是一种attention机制,它关联单个序列的不同位置以计算序列的表示。 Self-attention已成功用于各种任务,包括阅读理解、摘要概括、文本蕴涵和学习与任务无关的句子表征[4,27,28,22]。
  端到端的记忆网络基于循环attention机制,而不是序列对齐的循环,并且已被证明在简单语言的问答和语言建模任务中表现良好[34]。
  就我们所知,Transformer是第一个完全依靠self-attention来计算输入和输出表示而不使用序列对齐RNN或卷积的转换模型。 在后续章节中,我们将描述Transformer,引出self-attention并讨论它相对 [17, 18]和[9]几个模型的优势。

3 模型架构

  大部分神经序列转换模型都有一个编码器-解码器结构[5, 2, 35]。编码器把一个输入序列( )映射到一个连续的表示 z = ( )。解码器对z中的每个元素,生成输出序列( )。在每一步中,模型都是自回归的[10],在生成下一个时,会将先前生成的符号作为附加输入。
  Transformer遵循这种整体架构,编码器和解码器都使用self-attention堆叠和point-wise、完全连接的层,分别显示在图1的左边和右边
初识Transformer之Attention is all you need_第37张图片

3.1 编码器和解码器堆栈

编码器: 编码器由N = 6 个完全相同的层堆叠组成。 每一层都有两个子层。 第一层是一个multi-head self-attention机制,第二层是一个简单的、位置全连通的前馈网络。 我们对每个子层再采用一个残差连接[11] ,接着进行层标准化[1]。 也就是说,每个子层的输出是LayerNorm(x + Sublayer(x)),其中Sublayer(x) 是由子层本身实现的函数。为了便于进行残差连接,模型中的所有子层以及embedding嵌入层产生的输出的维度都为 = 512。
解码器: 解码器也是由N = 6 个完全相同的层堆叠组成。 除了每个编码器层中的两个子层之外,解码器还有第三个子层,该层对编码器的输出执行multi-head attention。 与编码器类似,我们在每个子层再采用残差连接,然后进行层标准化。 我们还修改解码器中的self-attention子层,以防止当前位置关注后续位置。 这种掩码结合将输出嵌入偏移一个位置,确保对位置 i 的预测只依赖位置小于i 的已知输出。

3.2 Attention

  Attention功能可以描述为将query和一组key-value对映射到输出,其中query、key、value和输出都是向量。 输出为value的加权和,其中每个value的权重通过query与相应key的兼容函数来计算。
初识Transformer之Attention is all you need_第38张图片

3.2.1 缩放的点积attention

  Figure 2左侧为"缩放的点积Attention"。其输入为query、维度为的key、维度为的value。我们计算query和所有key的点积,然后对每个除以在这里插入图片描述
,最后用softmax函数获得value的权重。
在实践中,我们同时计算一组query的attention函数,并将它们组合成一个矩阵Q。 key和value也一起组成矩阵 K 和 V 。 我们计算输出矩阵为:
在这里插入图片描述
  两个最常用的attention函数是加法attention[2]和点积(乘法)attention。除了缩放因子,点积Attention跟我们的算法一样。加法attention使用具有单个隐层的前馈网络计算兼容函数。虽然理论上点积attention和加法attention复杂度相似,但在实践中,点积attention可以使用高度优化的矩阵乘法来实现,因此点积attention计算更快、更节省空间。
  当的值比较小的时候,这两个机制的性能相近。当比较大时,加法attention比不带缩放的点积attention性能好[3]。 我们怀疑,对于很大的值,点积大幅度增长,将softmax函数推向具有极小梯度的区域。 为了抵消这种影响,我们将点积缩小倍。

3.2.2 Multi-Head Attention

我们发现将query、key和value分别进行h次不同的、学到的到、和维的线性映射效果更好,而不是用维的query、key和value执行单个attention函数。 基于query、key和value的每个映射,我们并行执行attention函数,产生dv维输出值。 将它们连接并再次映射,产生最终值,如图2所示。
  Multi-head attention允许模型联合关注不同位置的不同表示子空间的信息。如果只有一个attention head,它的平均值会削弱这个信息。
在这里插入图片描述

  在这项工作中,我们采用 h = 8 个并行attention层或head。对每个head, = = /h = 64。 由于每个head的大小减小,总的计算成本与具有全部维度的单个head attention相似。

3.2.3 Applications of Attention in our Model

Transformer以3种方式使用multi-head attention:

  1. 在“编码器—解码器attention”层,query来自前一个解码器层,key和value来自编码器的输出。这样,解码器中的每个位置都能关注到输入序列中的所有位置。这种方式模仿了序列到序列模型中典型的编码器—解码器的attention机制,例如[38, 2, 9]。
  2. 编码器包含self-attention层。 在self-attention层中,所有的key、value和query来自编码器中前一层的输出。编码器中的每个位置都可以关注编码器上一层的所有位置。
  3. 类似地,解码器中的self-attention层允许解码器中的每个位置都关注解码器中直到并包括该位置的所有位置。 为了保持解码器的自回归属性,我们需要防止解码器中的向左信息流。 通过屏蔽softmax的输入中所有不合法连接的值(设置为-∞),我们在缩放的点积attention中实现了这一目标。 见图2。

3.3 基于位置的前馈网络

  除了attention子层,编码器和解码器的每层还包含一个全连接前馈网络,该网络分别单独作用于每个位置。该网络包含两个线性转换,中间有一个ReLU激活。
在这里插入图片描述
  虽然线性变换在不同位置上是相同的,但每层的参数不同。它的另一种描述方式是两个内核大小为1的卷积。 输入和输出的维度为 = 512,内层的维度为 = 2048。

3.4 嵌入和Softmax

与其他序列转换模型类似,我们使用学习到的embedding将输入词符和输出词符转换为 维的向量。我们还使用学到的线性变换和softmax函数将解码器的输出转换为预测的下一个词符的概率。在我们的模型中,我们在两个embedding层之间和pre-softmax线性变换共享相同的权重矩阵,类似于[30]。在embedding层中,我们将这些权重乘以在这里插入图片描述

3.5 位置编码

  由于我们的模型不包含循环和卷积,为了让模型利用序列的顺序,我们必须加入一些序列中词符的相对或者绝对位置的信息。为此,我们将“位置编码”添加到编码器和解码器底部的输入embeddinng中。位置编码和embedding的维度相同,也是dmodel,所以这两个向量可以相加。 有多种位置编码可以选择,例如通过学习得到的位置编码和固定的位置编码[9]。
初识Transformer之Attention is all you need_第39张图片
在这项工作中,我们使用不同频率的正弦和余弦函数:
在这里插入图片描述
其中pos是位置,i 是维度。 也就是说,位置编码的每个维度对应于一个正弦曲线。 这些波长形成一个从2π 到10000 ⋅ 2π的几何级数。 我们选择这个函数是因为我们假设它会让模型很容易学习对相对位置的关注,因为对任意确定的偏移k, 在这里插入图片描述都可以表示为 在这里插入图片描述的线性函数。
  我们还用学习到的位置embedding[9]进行了试验,发现这两个版本的结果几乎是相同的(参见表 3 行(E))。我们之所以选择正弦曲线,是因为它可以让模型推断比训练期间遇到的更长的序列。

4 为什么选择Self-Attention

  在这一节中,我们将self-attention与循环和卷积层进行比较,后者通常用于将变长的符号序列表示映射到另一个等长的序列,例如一个典型的序列转换编码器或解码器中的隐层。使用self-attention主要是为了解决以下三个问题。
  一个是每层的总计算复杂度。另一个是可以并行的计算量,以所需的最少顺序操作数来衡量。
  第三个是网络中长距离依赖之间的路径长度。在许多序列转换任务中,学习长距离依赖性是一个主要的挑战。 影响学习这种依赖性能力的一个关键因素是前向和后向信号在网络中传播的路径长度。输入和输出序列中任意位置组合之间的这些路径越短,学习远距离依赖性就越容易[12]。因此,我们还比较了由不同类型网络层组成的网络中任意两个输入和输出位置之间的最大路径长度。
  如表1所示,self-attention层只需要常量顺序执行的操作就可以将所有位置连接起来,而循环层需要O(n) 顺序操作。 在计算复杂度方面,机器翻译中最先进的模型经常遇到序列长度n小于表示的维度d的情况,例如单词[38]表示法和字节对[31]表示法,此时,self-attention层比循环层要快很多。为了提高包含很长序列的任务的计算性能,可以将self-attention限制在以各自输出位置为中心的输入序列中 r 大小的邻域内。这会将最大路径长度增加到O(n/r)。我们计划在今后的工作中进一步研究这种方法。
  核宽度为 k < n 的单层卷积不能连接每一对输入和输出的位置对。要这么做,卷积核为邻近核的情况下需要O(n/k)个卷积层,在扩展卷积的情况下需要个层[18],这增加了网络中任意两个位置之间的最长路径的长度。卷积层通常比循环层更耗费资源,大约为k倍。然而,可分卷积[6]可以把复杂度大幅减少到。 然而,即使k = n,一个可分卷积的复杂度等同于self-attention层和point-wise前馈层的组合,即我们的模型采用的方法。
  间接的好处是,self-attention可以产生更可解释的模型。我们从我们的模型中研究attention的分布,并在附录中进行展示和讨论。每个attention head不仅清楚地学习了执行不同的任务,许多attention head似乎还能学到与句子的句法和语义结构相关的行为。

5 训练

本节介绍我们的模型训练方法。

5.1 训练数据和批次

  我们在标准的WMT 2014英语-德语数据集上进行了训练,其中包含约450万个句子对。 这些句子使用字节对编码[3]进行编码,源语句和目标语句共享大约37000个词符的词汇表。 对于英语-法语翻译,我们使用大得多的WMT 2014英法数据集,它包含3600万个句子,并将词符分成32000个word-piece词汇表[38]。 序列长度相近的句子一起进行批处理。 每个训练批次的句子对包含大约25000个源词符和25000个目标词符。

5.2 硬件和时间

  我们在一台有8个NVIDIA P100 GPU的机器上训练我们的模型。使用本文描述的超参数的基础模型,每个训练步骤耗时约0.4秒。我们对基础模型进行了总共100000步或12小时的训练。对于我们的大型模型(见表3的底部),步进时间为1.0秒,模型训练了30万步(3.5天)。

  
  
  
  

你可能感兴趣的:(图像分割目标检测)