Transformer模型是一种日益流行的神经网络结构。它最近被OpenAI用于他们的语言模型中。与此同时,近期也被DeepMind用于它们的程序“星际争霸”中击败了一名顶级职业星际玩家。
Transformer模型的开发是为了解决序列转换及神经机器翻译问题。这意味着可以解决任何sequence to sequence问题,例如语音识别、文本到语音转换等。
序列转换。输入用绿色表示,模型用蓝色表示,输出用紫色表示。GIF取自3
对于执行序列转换的模型而言,有一些记忆是必要的。例如,我们把下面的句子翻译成另一种语言(法语):
“The Transformers”是日本的一个硬核朋克乐队。该乐队成立于1968年,处于日本音乐史的鼎盛期。”
在本例中,第二句中的“the band”指的是第一句中引入的“The Transformers”乐队。当你在第二句中读到这支乐队时,你知道它指的是“The Transformers”乐队。这对翻译而言十分重要。在很多的翻译内容中,其中一些句子中的单词指的是前面句子中所提到过的单词。
对于翻译这样的句子,模型需要弄清楚这些依赖关系和连接。循环神经网络(RNN)和卷积神经网络(CNN)由于其各自的特点,一直被用来解决这一问题。让我们来回顾一下这两种架构及其各自的缺点。
循环神经网络
循环神经网络中包含循环架构,允许信息持续存在。
输入表示为x_t
在上图中,我们看到神经网络的一部分A,用于处理一些输入x_t并输出h_t。循环结构使得信息能够从一个步骤传递到下一个步骤。
我们可以用不同的方式来思考循环。可以将循环神经网络视为同一网络A的多个组合形式,每个网络将消息传递给后继者。考虑如果我们展开循环会发生什么:
展开的循环神经网络
这种链式的性质表明,循环神经网络显然与序列和列表相关。这样,如果我们想翻译一些文本,便可以将每个输入设置为文本中的单词。循环神经网络将前一个单词的信息传递给下一个网络,由此便可以使用和处理该信息。
下图显示了通常情况下sequence to sequence模型使用循环神经网络的工作原理。每个单词都被单独处理,并且通过将隐藏状态传递到解码级来生成所得到的结果句,然后生成输出。
GIF取自3
长期依赖的问题
考虑一种语言模型,该模型试图根据之前的单词预测下一个单词。如果我们试图预测“the clouds in the sky”这句话的下一个单词,我们不需要进一步的语境。显而易见,下一个单词将会是sky。
在这种情况下,相关信息和所需位置之间的差异很小,RNN可以学习使用过去的信息找出该句子的下一个单词。
图片取自6
但在某些情况下,我们需要更多的语境。例如,假设你想预测文本“I grew up in France…I speak fluent…”的最后一个单词。最近的信息表明,下一个单词可能是一种语言,但如果我们想精准到某一种语言,则需要法国的语境,这在文本中还有待进一步说明。
图片取自6
当相关信息与需要信息之间的差距变得非常大时,RNN变得非常无效。这是因为信息在RNN模型中按照步骤依次传递,链条越长,信息沿着链条丢失的可能性就越大。
从理论上讲,RNN可以学习这种长期依赖关系。但在实践中,他们似乎并没有学会它们。LSTM是一种特殊类型的RNN模型,它被尝试用于解决这类问题。
长短期记忆(LSTM)
在安排当天的日历时,我们会优先考虑我们的预约情况。如果有较为重要的事情,我们可以取消一些会议优先安排紧要任务。
然而RNN模型并非如此。每当它添加新信息时,它都会通过应用函数完全转换现有信息。因此导致整个信息被修改,无法参考任务的紧要程度。
LSTM模型通过乘法和加法对信息进行细微修改。利用LSTM,信息通过一种称为单元状态的机制流动。通过这种方式,LSTM可以选择性地记住重要事务且忘记不那么重要的事物。
在内部,LSTM模型如下所示:
图片取自6
每个单元,需要根据当前时刻节点的输入X_t(在句子到句子的转换中是一个单词)、上一时刻节点的状态和上一时刻节点的输出来决定当前的输入信息。它操作这些输入并基于它们生成新的单元状态和输出。
在单元状态下,句子中对翻译单词很重要的信息可以在翻译时从一个单词传递到另一个单词。
LSTM的问题
与RNN类似,同样的问题在LSTM上通常也会发生,即当句子太长时LSTM也仍然不够完善。其原因在于,当前正在处理的单词与上下文保持联系的可能性,将随着距离的增加呈指数递减。
这意味着当句子很长时,模型往往会忘记序列中较远位置的内容。由于必须逐词处理,RNN和LSTM的另一个问题便在于难以并行处理句子的工作。不仅如此,它们还缺少长期和短期依赖关系的模型。综上所述,LSTM和RNN存在3个问题:
- 顺序计算禁止并行化
- 没有明确的长短程依赖建模
- 位置之间的“距离”是线性的
Attention模型
为了解决其中的一些问题,研究人员发明了一种关注特定单词的技术。
在翻译句子时,我会集中注意于我正在翻译的单词。当我正在录制录音时,我会仔细聆听我正在积极记录的片段。如果让我描述我所在的房间,我会在描述时环顾一眼周围的物体。
神经网络可以通过使用attention来实现同样的行为,集中注意于给定信息的一部分。例如,一个RNN可以参与到另一个RNN的输出中。在每一个time step,它都侧重于另一个RNN中的不同位置。
Attention是一种用于神经网络的技术,它的目的便在于解决这些问题。对于RNN来说,不是单纯将整个句子编码为隐藏状态,而是每个单词都有对应的隐藏状态,并一直将其传递到解码阶段。然后,在RNN的每一步中使用隐藏状态进行解码。以下的gif展示了这它的原理。
所述绿色步骤称为编码阶段,紫色的步骤为解码阶段
。其背后的想法是,句子中的每个单词都可能包含相关信息。因此,为了使解码更精确,需要使用Attention来处理输入的每一个单词。
为了在序列转换中将Attention引入RNN,我们将编码和解码分为两个主要步骤。一个步骤用绿色表示,另一个用紫色表示。绿色的步骤称为编码阶段,紫色的步骤称为解码阶段
GIF取自3
绿色的步骤负责从输入创建隐藏状态。我们没有像在使用Attention之前那样,只将一个隐藏状态传递给解码器,而是将句子中每个“单词”生成的所有隐藏状态传递给解码阶段。解码阶段使用每个隐藏状态,找出网络应该注意的地方。
例如,在将“Je suis étudiant”翻译成英语时,要求解码步骤在翻译时查看不同的单词。
这个gif显示了将句子“Je suis étudiant”翻译成英语时给予每个隐藏状态的权重。颜色越深,每个单词的权重就越大。
再举个例子,当翻译“L’accord sur la zone économique européenne a été signé en août 1992”这句话的时候。从法语到英语,对每个输入的注意程度。
GIF取自3
但是上述讨论的一些问题,仍然无法通过引入Attention机制的循环神经网络完全解决。例如,并行处理输入(单词)是不可能的。对于大型文本语料库,这会增加翻译文本所花费的时间。
卷积神经网络
卷积神经网络有助于解决这些问题。有了他们,我们可以:
- 平行化(每层)
- 利用局部依赖关系
- 位置之间的距离呈对数关系
一些用于序列转换的流行神经网络,如Wavenet和Bytenet,均为卷积神经网络。
Wavenet,模型是卷积神经网络(CNN)
卷积神经网络能够并行工作的原因是,输入的每个单词都可以同时处理,并不一定依赖于之前要翻译的单词。不仅如此,CNN的输出单词和任何输入之间的“距离”都是按照log(N)函数的顺序排列的——这表示的是从输出到输入生成的树的高度的大小,如上图GIF所示。这比一个RNN中输出和输入的距离呈指数变化要方便得多。
然而卷积神经网络在翻译句子时,并不一定有助于解决依赖关系的问题。于是Transformer模型应运而生,它是卷积神经网络与Attention机制的有效结合。
Transformer模型
为了解决并行化问题,Transformer试图将卷积神经网络和Attention模型结合。Attention的存在可以提高模型序列转换之间的速度。更确切地说,Transformer是一种利用self-Attention来提升速度的模型。
Transformer模型。图片取自4
在内部,Transformer具有与上述模型类似的体系结构。但是Transformer由六个编码器和六个解码器组成。
编码组中的每个编码器都具有相同的架构,而解码组的6个解码器则共享相同的属性。它们各自之间非常相似。每个编码器由两层组成:Self-attention和前馈神经网络。如下图所示。
每个Encoder的输入首先会流经一个self-attention层,它帮助编码器在对特定的单词编码时,查看输入语句中的其他单词。解码器同样具有这两个层,但两层之间有一个attention层,帮助解码器将关注输入语句的相关部分。
Self-Attention
注:本节来自Jay Allamar的博客文章
接下来,我们来研究一下各种向量/张量,以及它们如何在模型的各部分流动,从而将输入转换成输出的。与大部分的NLP应用程序一样,我们首先利用嵌入算法将每个输入单词转换为向量。
每个单词都嵌入到大小为512的向量中。我们用这些简单的方块表示向量。
嵌入只发生在最底层的编码器。所有编码器共有的特点是,它们接收一个大小为512的向量列表。
在底部的编码器中是词嵌入,但是在其他编码器中,它是下层编码器的输出。将单词嵌入输入序列之后,每个单词都流经编码器的两层架构。
在这里,我们开始了解到Transformer的一个关键属性,即每个位置的单词在编码器中流经自己的路径。self-attention层中的这些路径之间存在依赖关系。然而,前馈层不具有那些依赖关系,因此各种路径可以在流过前馈层时并行执行。
接下来,切换为更短的例句,我们将查看编码器的每个子层中发生的情况。
Self-Attention
我们先来看看如何使用向量来计算Self-Attention,然后再来看看它是如何利用矩阵实现的。
弄清楚句子中的单词关系并给予正确的关注。
计算self-Attention的第一步是从每个编码器的输入向量创建三个向量(在本例中,对每个单词做词嵌入)。因此,对于每个单词,我们创建一个Query向量,一个Key向量和一个Value向量。这些向量是通过将嵌入乘以我们在训练过程中训练的三个矩阵得到的。
请注意,这些新向量的维数比嵌入向量小。其维数为64,而嵌入和编码器的输入/输出向量维数为512。它们不必更小,这是一种架构选择,可以使MultiHeaded Attention的计算(大部分)保持不变。
将x1乘以WQ权重矩阵产生q1,即与该词相关联的“Query”向量。同样,最终我们可以在输入句子中对每个单词的创建“Query”,“Key”和“Value”映射。
什么是“Query”,“Key”和“Value”向量?
它们是有助于计算和思考注意力的抽象概念。下面的内容,会帮助你理解这些向量的作用。
计算self-Attention的第二个步骤是计算得分。假设我们正在计算这个例子中第一个单词“Thinking”的self-Attention。我们需要根据这个词对输入句子的每个单词进行评分。当我们在某个位置编码单词时,分数决定了对输入句子的其他部分的关注程度。
通过将query向量和key向量计算点积对相应单词评分。因此,如果我们处理位置#1中单词的self-Attention,则第一个分数将是q1和k1的点积。第二个分数是q1和k2的点积。
第三步和第四步是将分数除以8(论文中使用的key向量的维数64的平方根)。这导致了更稳定的梯度。这里可能有其他可能的值,但这是默认值),然后通过softmax操作传递结果。Softmax将这些分数标准化,使它们都是正的,加起来等于1。
这个softmax分数决定了每个单词在这个位置的表达程度。很明显,这个位置的单词将拥有最高的softmax分数,但有时Attention机制关注与当前单词相关的另一个单词也是有用的。
第五步是将每个Value向量乘以softmax分数(准备对它们求和)。这里实际上是保持我们想要关注的单词的值不变,弱化无关单词。(例如,将它们乘以0.001这样的小数字)。
第六步是对加权Value向量求和。这将在此位置生成self-attention层(对于第一个单词)的输出。
对self-Attention总结一下,就是得到一个我们可以发送到前馈神经网络的向量。然而,在实际实现中,为了加快处理速度,这种计算是以矩阵的形式进行的。现在我们来看看单词级别的计算实现。
Multihead attention
Transformer基本上就是这样的工作机制。还有一些其他细节可以使它们更好地工作。例如,Transformer使用Multihead attention的概念,使其不只在一个维度上互相关注。
其背后的想法是,无论何时翻译单词,你都可以根据你所问的问题的类型对每个单词给予不同的关注。下面的图片显示其内在意义。例如,当你在“I kick the ball”这个句子中翻译“kick”时,你可以问“Who kick”。根据答案的不同,把这个单词翻译成另一种语言可能会发生变化。或者问其他问题,比如“Did what?””等等。
位置编码(Positional Encoding)
Transformer上的另一个重要步骤,是在编码每个单词时添加位置编码。编码每个单词的位置是极具意义的,因为每个单词的位置与翻译息息相关。
以上为译文
本文由阿里云云栖社区组织翻译。
文章原标题《How Transformers Work》,译者:狮子家的袋鼠,审校:Viola。