1. 媒介
The Transformer——一个利用留意力来进步这些模型的练习速率的模型。Transformer 在特定任务中的表现优于谷歌神经呆板翻译模型。然而,最大的利益来自于 The Transformer 怎样使自己适合并行化。毕竟上,Google Cloud 建议利用 The Transformer 作为参考模型来利用他们的Cloud TPU产物。所以让我们试着把模型拆开,看看它是怎样运作的。
Transformer 是在论文Attention is All You Need中提出的。它的 TensorFlow 实现作为Tensor2Tensor包的一部门提供。哈佛大学的 NLP 小组创建了一个指南,用 PyTorch 实现对论文举行解释。在这篇文章中,我们将尝试将事变过分简单化,并逐一先容这些概念,以期使没有深入相识该主题的人更容易明确。

Query,Key,Value的概念取自于信息检索体系,举个简单的搜索的例子来说。当你在某电商平台搜索某件商品(年轻密斯冬季穿的赤色薄款羽绒服)时,你在搜索引擎上输入的内容便是Query,然后搜索引擎根据Query为你匹配Key(比方商品的种类,颜色,形貌等),然后根据Query和Key的相似度得到匹配的内容(Value)。
self-attention中的Q,K,V也是起着类似的作用,在矩阵盘算中,点积是盘算两个矩阵相似度的方法之一,因此式1中利用了 Q K T QK^{T} QKT 举行相似度的盘算。接着便是根据相似度举行输出的匹配,这里利用了加权匹配的方式,而权值就是query与key的相似度。
下面是英语翻译成法语的Encoding和Decoding的例子,句子"I arrived at the"

2. 自留意力机制(self-Attention)和Transformer
自留意力(Attention)机制[2]由Bengio团队与2014年提出并在比年广泛的应用在深度学习中的各个范畴,比方在盘算机视觉方向用于捕获图像上的感受野,大概NLP中用于定位关键token大概特性。谷歌团队近期提出的用于天生词向量的BERT[3]算法在NLP的11项任务中取得了结果的大幅提拔,堪称2018年深度学习范畴最奋发人心的消息。而BERT算法的最重要的部门便是本文中提出的Transformer的概念。
正如论文的题目所说的,Transformer中扬弃了传统的CNN和RNN,整个网络结构完全是由Attention机制构成。更准确地讲,Transformer由且仅由self-Attenion和Feed Forward Neural Network构成。一个基于Transformer的可练习的神经网络可以通过堆叠Transformer的情势举行搭建,作者的实行是通过搭建编码器息争码器各6层,总共12层的Encoder-Decoder,并在呆板翻译中取得了BLEU值得新高。
作者采用Attention机制的原因是考虑到RNN(大概LSTM,GRU等)的盘算限定为是序次的,也就是说RNN干系算法只能从左向右依次盘算大概从右向左依次盘算,这种机制带来了两个题目:
- 时间片 t的盘算依赖 t-1 时间的盘算结果,如许限定了模型的并行本事;
- 序次盘算的过程中信息会丢失,只管LSTM等门机制的结构肯定程度上缓解了长期依赖的题目,但是对于特殊长期的依赖征象,LSTM依旧无能为力。
Transformer的提出解决了上面两个题目,起首它利用了Attention机制,将序列中的恣意两个位置之间的距离是缩小为一个常量;其次它不是类似RNN的序次结构,因此具有更好的并行性,符合现有的GPU框架。论文中给出Transformer的定义是:Transformer is the first transduction model relying entirely on self-attention to compute representations of its input and output without using sequence aligned RNNs or convolution。
3. Transformer 简化架构图
让我们起首将模型视为一个黑盒子。在呆板翻译应用步伐中,它会用一种语言输入一个句子,然后用另一种语言输出它的翻译。例子:法语翻译为英语。

简化Transformer的优点,我们会看到一个编码组件Encoders、一个解码组件Decoders以及它们之间的连接。

Encoder编码组件是一堆编码器(论文上将其中六个堆叠在一起——数字 6 并没有什么神奇之处,当然可以尝试其他分列方式)。解码组件是一堆雷同数量的解码器。

Encoder编码器在结构上都是雷同的(但它们不共享权重)。每一个都分为两个子层:

- 编码器的输入起首流经自留意力层Self-Attention——该层资助编码器在对特定单词举行编码时查看输入句子中的其他单词。我们将在后面的文章中过细研究自留意力层。
- 自留意力层的输出被馈送到前馈神经网络Feed Forward Neural Network。完全雷同的前馈网络独立应用于每个位置。
解码用具有这两个层,但在它们之间多了一个留意力层Encoder-Decoder Attention,资助解码器专注于输入句子的干系部门(类似于seq2seq 模型中的留意力)。

4. 输入编码
如今我们已经相识了模型的重要组件,让我们开始研究各种向量/张量Tensor以及它们如安在这些组件之间活动,以将练习模型的输入转化为输出。
与一样平常 NLP 应用步伐中的情况一样,我们起首利用Embedding嵌入算法将每个输入单词转换为向量。

每个单词都嵌入到一个大小为 512 的向量中。我们将用这些简单的框来表现这些向量。
Embedding嵌入仅发生在最底部的编码器中。所有编码器共有的抽象是它们接收一个大小为 512 的向量列表——在底部的编码器中,这将是词嵌入,但在其他编码器中,它将是直接在下方的编码器的输出. 这个列表的大小是我们可以设置的超参数——根本上它是我们练习数据会合最长句子的长度。
在我们的输入序列中嵌入单词之后,它们中的每一个都流过编码器的两层中的每一层。

在这里,我们开始看到 Transformer 的一个关键属性,那就是每个位置的单词在Encoders编码器中流过自己的路径。在自留意力层Self-Attention中,这些路径之间存在依赖关系。然而,Feed Forward前馈层没有这些依赖关系,因此各种路径可以在流过前馈层的同时并行执行。
接下来,我们将把这个例子转换成一个更短的句子,我们将看看在编码器的每个子层中发生了什么。
4.1 如今我们正在编码!
正如我们已经提到的,编码器接收向量列表作为输入。它通过将这些向量传递到“自留意力Self-Attention ”层来处理这个列表,然后传递到前馈神经网络Feed Forward Neural Network,然后将输出向上发送到下一个编码器。

每个位置的单词都会颠末一个自留意力过程。然后,它们每个都通过一个前馈神经网络——完全雷同的网络,每个向量分别流过它。
5. Self-Attention 自留意力机制
假设以下句子是我们要翻译的输入句子:
” The animal didn’t cross the street because it was too tired”
这句话中的“it”指的是什么?it指的是street还是animal?这对人类来说是一个简单的题目,但对算法来说却不是那么简单。
当模型处理“it”这个词时,self-attention 允许它把“it”和“animal”联系起来。
当模型处理每个单词(输入序列中的每个位置)时,自留意力允许它查看输入序列中的其他位置以探求有助于更好地编码该单词的线索。
如果您认识 RNN,请考虑怎样保持隐蔽状态允许 RNN 将其已处理的先前单词/向量的表现与其正在处理的当前单词/向量联合起来。自留意力是 Transformer 用来将其他干系单词的“明确”融入我们当前正在处理的单词的方法。

当我们在编码器#5(堆栈中的顶部编码器)中对单词“it”举行编码时,部门留意力机制专注于“The Animal”(连线权重比力大),并将其表现的一部门集成到“it”的编码中。
请务必查看Tensor2Tensor jupyter notebook,您可以在其中加载 Transformer 模型,并利用此交互式可视化举行检查。
5.1 自留意力细节
让我们先看看怎样利用向量盘算自留意力,然后继承看看它是怎样现实实现的——利用矩阵。
盘算自留意力的第一步是从每个编码器的输入向量创建三个向量Q、K、V(在这种情况下,每个词的嵌入)。因此,对于每个单词,我们创建一个查询向量Q、一个键向量K和一个值向量V。这些向量是通过将嵌入乘以我们在练习过程中练习的三个矩阵来创建的。
请留意,这些新向量Q、K、V的维度小于嵌入向量。它们的维数为 64,而嵌入和编码器输入/输出向量的维数为 512。它们不必更小,这是使多头留意力(大部门)的盘算保持稳定的架构选择。

将 x 1 x_1 x1 乘以 W Q W^Q WQ权重矩阵会产生 q 1 q_1 q1 ,即与该词关联的“查询”向量。我们终极为输入句子中的每个单词创建了一个“查询Q”、一个“键K”和一个“值V”投影。
5.2 什么是“查询Q”、“键K”和“值V”向量?
它们是用于盘算和思考留意力的抽象概念。一旦你继承阅读下面的留意力是怎样盘算的,你就会知道险些所有你需要知道的关于每个向量所饰演的脚色。
盘算self-attention的第二步是盘算一个分数。假设我们正在盘算本例中第一个单词“Thinking”的自留意力。我们需要根据这个词对输入句子的每个词举行评分。当我们在某个位置对单词举行编码时,分数决定了对输入句子其他部门的关注程度。
分数是通过查询向量与我们正在评分的各个单词的关键向量的点积来盘算的。因此,如果我们正在处理位置#1中单词的自留意力,第一个分数将是 q 1 q_1 q1和 k 1 k_1 k1的点积。第二个分数是 q 2 q_2 q2和 k 2 k_2 k2的点积。

第三步和第四步是将分数除以 8(论文中利用的关键向量维度的平方根 64。这会导致梯度更稳固。这里大概尚有其他大概的值,但这是默认),然后通过 softmax 利用传递结果。Softmax 将分数归一化,因此它们都是正数而且加起来为 1。

这个 softmax 分数决定了每个单词在这个位置上的表达量。显然,这个位置的单词将具有最高的 softmax 分数,但偶然关注与当前单词干系的另一个单词很有效。
第五步是将每个值向量乘以 softmax 分数(预备将它们相加)。这里的直觉是保持我们想要关注的单词的值稳定,并沉没不干系的单词(比方,将它们乘以 0.001 之类的小数字)。
第六步是对加权值向量求和。这会在这个位置产生自留意力层的输出(对于第一个词)。

自留意力盘算到此竣事。结果向量是我们可以发送到前馈神经网络的向量。然而,在现实实现中,这种盘算是以矩阵情势举行的,以便更快地处理。既然我们已经看到了单词级别的盘算直觉,那么让我们来看看。
5. 3 自留意力的矩阵盘算
第一步是盘算查询Q、键K和值V矩阵。我们通过将嵌入打包到矩阵X中,并将其乘以我们练习的权重矩阵( W Q W^Q WQ、 W K W^K WK、 W V W^V WV)来做到这一点。

X矩阵 中的每一行对应于输入句子中的一个单词。我们再次看到嵌入向量(512,或图中 4 个框)和 q/k/v 向量(64,或图中 3 个框)大小的差别
末了,由于我们处理的是矩阵,我们可以将步调二到六合一公式来盘算自留意力层的输出。

矩阵情势的self-attention盘算
5.4 “多头”留意力Multi-Head Attention
该论文通过添加一种称为“多头”留意力的机制进一步美满了自留意力层self attention。

这通过两种方式进步了留意力层的性能:
- 它扩展了模型关注不同位置的本事。是的,在上面的示例中,z1 包罗一点其他编码,但它大概由现实单词自己主导。如果我们要翻译“The animal didn’t cross the street because it was too tired”如许的句子,那么知道“it”指的是哪个词会很有效。
- 它为留意力层提供了多个“表现子空间”。正如我们接下来将看到的,利用多头留意力,我们不仅有一个,而且尚有多组查询/键/值权重矩阵(Transformer 利用八个留意力头,所以我们终极每个编码器/解码器都有八个集合) . 这些集合中的每一个都是随机初始化的。然后,在练习之后,每个集合用于将输入嵌入(或来自较低编码器/解码器的向量)投影到不同的表现子空间中。

通过多头留意力,我们为每个头维护单独的 Q/K/V 权重矩阵,从而产生不同的 Q/K/V 矩阵。正如我们之前所做的那样,我们将 X 乘以 W Q W^Q WQ/ W K W^K WK/ W V W^V WV 矩阵以产生 Q/K/V 矩阵。
如果我们举行与上述雷同的自留意力盘算,只是利用不同的权重矩阵举行八次不同的盘算,我们终极会得到八个不同的 Z 矩阵

这给我们带来了一些寻衅。前馈层不需要八个矩阵——它需要一个矩阵(每个单词的向量)。所以我们需要一种方法将这八个Concatenate浓缩成一个矩阵。
我们怎样做到这一点?我们连接这些矩阵,然后将它们乘以一个额外的权重矩阵 W O W^O WO。

这就是多头自留意力的全部内容。我意识到,这是相当多的矩阵。让我尝试将它们全部放在一个视觉结果中,以便我们可以在一个地方查看它们

既然我们已经接触了自留意力头,让我们重新回顾之前的例子,看看当我们在例句中编码单词“it”时不同的留意力头在哪里会合:

当我们对“it”这个词举行编码时,一个留意力头最关注“animal”,而另一个留意力头则专注于“tire”——在某种意义上,模型对“it”这个词的表现包罗了一些表现“animal”和“tire”。
但是,如果我们将所有留意力都添加到图片中,事变大概会更难表明:

6. 利用位置编码表现序列的序次
正如我们到如今为止所形貌的,模型中缺少的一件事是一种表明输入序列中单词序次的方法。
为相识决这个题目,转换器为每个输入嵌入添加了一个向量。这些向量遵照模型学习的特定模式,这有助于确定每个单词的位置,或序列中不同单词之间的距离。这里的直觉是,一旦将这些值投影到 Q/K/V 向量中以及在点积留意力期间,将这些值添加到嵌入中会在嵌入向量之间提供故意义的距离。

为了让模型相识单词的序次,我们添加了位置编码向量——其值遵照特定的模式。
如果我们假设嵌入的维度为 4,那么现实的位置编码将如下所示:

嵌入大小为 4 的位置编码的真实示例
这种模式大概是什么样子?
在下图中,每一行对应一个向量的位置编码。所以第一行将是我们添加到输入序列中第一个词的嵌入的向量。每行包罗 512 个值——每个值都介于 1 和 -1 之间。我们对它们举行了颜色编码,因此图案可见。

嵌入大小为 512(列)的 20 个单词(行)的位置编码的真实示例。您可以看到它在中间被分成两半。这是由于左半部门的值是由一个函数(利用正弦Sin)天生的,而右半部门是由另一个函数(利用余弦Cos)天生的。然后将它们连接起来形成每个位置编码向量。
论文中形貌了位置编码的公式(第 3.5 节)。您可以在 中查看天生位置编码的代码get_timing_signal_1d()。这不是位置编码的唯一大概方法。然而,它具有可以大概扩展到看不见的序列长度的优势(比方,如果我们练习的模型被要求翻译比我们练习会合的任何一个句子更长的句子)。
上面表现的位置编码来自 Transformer 的 Tranformer2Transformer 实现。论文中展示的方法略有不同,它不是直接串联,而是将两个信号交错在一起。下图表现了它的表面。这是天生它的代码:

7. 残差 The Residuals Network
在继承之前我们需要提到的编码器架构中的一个细节是,每个编码器中的每个子层(self-attention)在其四周都有一个残差连接,然后是一个层归一化步调。

如果我们要可视化与 self attention 干系的向量和 layer-norm 利用,它看起来像如许:

这也适用于解码器的子层。如果我们想一个由 2 个堆叠编码器息争码器构成的 Transformer,它看起来像如许:

8. 解码器端 The Decoder Side
如今我们已经涵盖了编码器方面的大部门概念,我们根本上知道解码器的组件是怎样工作的。但是让我们来看看它们是怎样协同工作的。
编码器起首处理输入序列。然后将顶部编码器的输出转换为一组留意向量 K 和 V。这些将由每个解码器在其“编码器-解码器留意”层中利用,这有助于解码器将留意力会合在输入序列中的得当位置:

以下步调重复该过程,直到出现特殊到达符号表现变压器解码器已完成其输出。每一步的输出在下一个时间步被馈送到底部的解码器,解码器就像编码器一样冒泡它们的解码结果。就像我们对编码器输入所做的那样,我们将位置编码嵌入并添加到这些解码器输入中,以指示每个单词的位置。

解码器中的自留意力层的利用方式与编码器中的方式略有不同:
在解码器中,自留意力层只允许关注输出序列中较早的位置。这是通过在 self-attention 盘算中的 softmax 步调之前masking屏蔽未来位置(将它们设置为 )来完成的。
“Encoder-Decoder Attention”层的工作方式与多头自留意力相似,不同之处在于它从其下方的层创建其查询矩阵,并从编码器堆栈的输出中获取 Keys 和 Values 矩阵。
9. 终极的线性和 Softmax 层
解码器堆栈输出一个浮点向量。我们怎样把它变成一个词?这是末了一个线性层的工作,后面是一个 Softmax 层。
线性层是一个简单的全连接神经网络,它将解码器堆栈产生的向量投影到一个更大的向量中,称为 logits 向量。
假设我们的模型知道从练习数据会合学习到的 10,000 个独特的英语单词(我们模型的“输出词汇”)。这将使 logits 向量有 10,000 个单元格宽——每个单元格对应一个唯一单词的分数。这就是我们怎样表明模型的输出,然后是线性层。
然后,softmax 层将这些分数转化为概率(全部为正,全部加起来为 1.0)。选择概率最高的单元格,并天生与其关联的单词作为该时间步的输出。

10. 总结
如今我们已经通过一个练习有素的 Transformer 先容了整个前向传递过程,看看练习模型的直觉会很有效。
在练习期间,未经练习的模型将通过完全雷同的前向传递。但是由于我们是在一个带标签的练习数据集上练习它,我们可以将它的输出与现实精确的输出举行比力。
为了形象化,假设我们的输出词汇表只包罗六个单词(“a”、“am”、“i”、“thanks”、“student”和“”(“end of sentence”的缩写)) .

我们模型的输出词汇表是在我们开始练习之前的预处理阶段创建的。
一旦我们定义了我们的输出词汇表,我们就可以利用一个雷同宽度的向量来表现我们词汇表中的每个单词。这也称为 one-hot 编码。因此,比方,我们可以利用以下向量表现单词“am”:

示例:我们的输出词汇表的 one-hot 编码
在此回顾之后,让我们讨论模型的丧失函数——我们在练习阶段正在优化的指标,以天生一个颠末练习的而且盼望非常准确的模型。
10.1 丧失函数
假设我们正在练习我们的模型。假设这是我们在练习阶段的第一步,我们正在通过一个简单的例子来练习它——将“merci”翻译成“thanks”。
这意味着,我们盼望输出是一个概率分布,表现“谢谢”这个词。但由于这个模型还没有颠末练习,所以如今还不太大概发生。

由于模型的参数(权重)都是随机初始化的,因此(未经练习的)模型会为每个单元格/单词天生具有恣意值的概率分布。我们可以将其与现实输出举行比力,然后利用反向流传调解所有模型的权重,以使输出更靠近所需的输出。
你怎样比力两个概率分布?我们只是从另一个中减去一个。有关更多具体信息,请查看 交错熵和Kullback-Leibler 散度。
但请留意,这是一个过于简单的示例。更现实的是,我们会利用比一个词更长的句子。比方——输入:“je suis étudiant”,预期输出:“I am a student”。这真正意味着,我们盼望我们的模型可以大概一连输出概率分布,其中:
- 每个概率分布都由一个宽度为 vocab_size 的向量表现(在我们的示例中为 6,但更现实的是一个数字,比方 30,000 或 50,000)
- 第一个概率分布在与单词“i”干系的单元格中具有最高概率
- 第二个概率分布在与单词“am”干系的单元格中具有最高概率
- 依此类推,直到第五个输出分布指示 ’ ’ 符号,它也有一个来自 10,000 个元素词汇表的单元格与之关联。

我们将在练习示例中针对一个样本句子练习模型的目标概率分布。
在充足大的数据集上练习模型充足的时间后,我们盼望天生的概率分布如下所示:

盼望在练习后,模型会输出我们渴望的精确翻译。当然,如果这个短语是练习数据集的一部门,这并没有真正的迹象(拜见:交错验证)。请留意,每个位置都有一点概率,纵然它不太大概是那个时间步的输出——这是 softmax 的一个非常有效的属性,有助于练习过程。
如今,由于模型一次产生一个输出,我们可以假设模型正在从该概率分布中选择具有最高概率的单词并丢弃别的的单词。这是一种方法(称为贪心解码)。另一种方法是生存前两个单词(比方,“I”和“a”),然后在下一步中运行模型两次:假设第一个输出位置是单词’I’,另一次假设第一个输出位置是单词’a’,而且考虑到位置#1和#2,无论哪个版本产生的错误更少。我们对#2 和#3 等位置重复此利用。这种方法称为“beam search”,在我们的示例中,beam_size 为 2(这意味着在任何时间,两个部门假设(未完成的翻译)都生存在内存中),而且 top_beams 也是两个(意味着我们将返回两个翻译)。这些都是您可以试验的超参数。
11. 延伸阅读
我盼望您发现这是一个有效的地方,可以开始利用 Transformer 的重要概念冲破僵局。如果您想更深入,我建议您执行以下步调:
观看原作的视频:https://youtu.be/-QH8fRhqFHM

- 阅读Attention Is All You Need论文、Transformer 博客文章(Transformer: A Novel Neural Network Architecture for Language Understanding)和Tensor2Tensor 公告。
- 观看Łukasz Kaiser 的演讲,相识模型及其细节
- 利用作为 Tensor2Tensor 存储库的一部门提供的Jupyter Notebook
- 探索Tensor2Tensor repo。
参考
- https://arxiv.org/abs/1706.03762
- https://jalammar.github.io/illustrated-transformer/
- https://zhuanlan.zhihu.com/p/48508221
来源:https://blog.csdn.net/zgpeace/article/details/126635650
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |