小编采访

曾国藩,野鸡怎么做好吃,岳丽娜-高手推荐博客

Attention这种机制最开端运用于机器翻译的使命中,并且取得了巨大的成果,因而在最近的深度学习模型中受到了很多的重视。在在这个基础上,咱们提出一种彻底依据Attention机制来加快深度学习练习进程的算法模型-Transformer。事实证明Transformer结构在特定使命上现已优于了谷歌的神经网络机器翻译模型。可是,Transformer最大的优势在于其在并行化处理上做出的奉献。谷歌也在运用Transformer的并行化办法来营销自己的云TPU。所以,现在让咱们一步一步分析Transformer的奥秘面纱,让我看看他是怎样一步一步练习的。

Transformer在Goole的一篇论文Attention is All You Need被提出,为了便利完结调用Transformer Google还开源了一个第三方库,依据TensorFlow的Tensor2Tensor,一个NLP的社区研讨者奉献了一个Torch版别的支撑:guide annotating the paper with PyTorch implementation。这儿,我想用一些便利了解的办法来一步一步解说Transformer的练习进程,这样即使你没有很深的深度学习常识你也能大约了解其间的原理。

A High-Level Look

咱们先把Transformer幻想成一个黑匣子,在机器翻译的范畴中,这个黑匣子的功用便是输入一种言语然后将它翻译成其他言语。如下图:

Transfomer

掀起The Transformer的盖头,咱们看到在这个黑匣子由2个部分组成,一个Encoders和一个Decoders。

Transfomer

咱们再对这个黑匣子进一步的分析,发现每个Encoders平分别由6个Encoder组成(论文中是这样装备的)。而每个Decoders中相同也是由6个Decoder组成。

关于Encoders中的每一个Encoder,他们结构都是相同的,可是并不会同享权值。每层Encoder有2个部分组成,如下图:

每个Encoder的输入首要会经过一个self-attention层,经过self-attention层协助Endcoder在编码单词的进程中检查输入序列中的其他单词。假如你不清楚这儿在说什么,不必着急,之后咱们会具体介绍self-attention的。

Self-attention的输出会被传入一个全衔接的前馈神经网络,每个encoder的前馈神经网络参数个数都是相同的,可是他们的作用是独立的。

每个Decoder也相同具有这样的层级结构,可是在这之间有一个Attention层,协助Decoder专心于与输入语句中对应的那个单词(相似与seq2seq models的结构)

Bringing The Tensors Into The Picture

在上一节,咱们介绍了Transformer的网络结构。现在咱们以图示的办法来研讨Transformer模型中各种张量/向量,调查从输入到输出的进程中这些数据在各个网络结构中的活动。

首要仍是NLP的惯例做法,先做一个词嵌入:什么是文本的词嵌入?

咱们将每个单词编码为一个512维度的向量,咱们用上面这张简略的图形来表明这些向量。词嵌入的进程只发生在最底层的Encoder。可是关于一切的Encoder来说,你都能够按下图来了解。输入(一个向量的列表,每个向量的维度为512维,在最底层Encoder作用是词嵌入,其他层便是其前一层的output)。别的这个列表的巨细和词向量维度的巨细都是能够设置的超参数。一般状况下,它是咱们练习数据会集最长的语句的长度。

上图其实介绍到了一个Transformer的要害点。你留意调查,在每个单词进入Self-Attention层后都会有一个对应的输出。Self-Attention层中的输入和输出是存在依靠联系的,而前馈层则没有依靠,所以在前馈层,咱们能够用到并行化来提高速率。

下面我用一个简略的语句作为比方,来一步一步推导transformer每个子层的数据活动进程。

Now We’re Encoding!

正如之前所说,Transformer中的每个Encoder接纳一个512维度的向量的列表作为输入,然后将这些向量传递到‘self-attention’层,self-attention层发生一个等量512维向量列表,然后进入前馈神经网络,前馈神经网络的输出也为一个512维度的列表,然后将输出向上传递到下一个encoder。

如上图所示,每个方位的单词首要会经过一个self attention层,然后每个单词都经过一个独立的前馈神经网络(这些神经网络结构彻底相同)。

Self-Attention at a High Level

Self attention这个单词看起来如同每个人都知道是什么意思,但实质上他是算法范畴中新出的概念,你能够经过阅览:Attention is All You Need 来了解self attention的原理。

假定下面的语句便是咱们需求翻译的输入句:

”The animal didn't cross the street because it was too tired”

这句话中的"it"指的是什么?它指的是“animal”仍是“street”?关于人来说,这其实是一个很简略的问题,可是关于一个算法来说,处理这个问题其实并不简略。self attention的呈现便是为了处理这个问题,经过self attention,咱们能将“it”与“animal”联系起来。

当模型处理单词的时分,self attention层能够经过当时单词去检查其输入序列中的其他单词,以此来寻觅编码这个单词更好的头绪。

假如你了解RNNs,那么你能够回想一下,RNN是怎样处理从前单词(向量)与当时单词(向量)的联系的?RNN是怎样核算他的hidden state的。self-attention正是transformer中规划的一种经过其上下文来了解当时词的一种办法。你会很简略发现...相较于RNNs,transformer具有更好的并行性。

如上图,是咱们第五层Encoder针对单词'it'的图示,能够发现,咱们的Encoder在编码单词‘it’时,部分留意力机制会集在了‘animl’上,这部分的留意力会经过权值传递的办法影响到'it'的编码。

Self-Attention in Detail

这一节咱们先介绍怎样用向量的办法来核算self attention,然后再来看看它是怎样运用矩阵来完结的。

核算self attention的榜首步是从每个Encoder的输入向量上创立3个向量(在这个状况下,对每个单词做词嵌入)。所以,关于每个单词,咱们创立一个Query向量,一个Key向量和一个Value向量。这些向量是经过词嵌入乘以咱们练习进程中创立的3个练习矩阵而发生的。

留意这些新向量的维度比嵌入向量小。咱们知道嵌入向量的维度为512,而这儿的新向量的维度只要64维。新向量并不是有必要小一些,这是网络架构上的挑选使得Multi-Headed Attention(大部分)的核算不变。

咱们将乘以的权重矩阵得到新向量,既是“query”的向量。同理,终究咱们能够对输入语句的每个单词创立“query”,

“key”,“value”的新向量表明办法。

对了..“query”,“key”,“value”是什么向量呢?有什么用呢?

这些向量的概念是很笼统,可是它的确有助于核算留意力。不过先不必纠结去了解它,后边的的内容,会协助你了解的。

核算self attention的第二步是核算得分。以上图为例,假定咱们在核算榜首个单词“thinking”的self attention。咱们需求依据这个单词对输入语句的每个单词进行评分。当咱们在某个方位编码单词时,分数决议了对输入语句的其他单词的照顾程度。

经过将query向量和key向量点击来对相应的单词打分。所以,假如咱们处理开端方位的的self attention,则榜首个分数为和的点积,第二个分数为和的点积。如下图

第三步和第四步的核算,是将第二部的得分除以8()(论文中运用key向量的维度是64维,其平方根=8,这样能够使得练习进程中具有更安稳的梯度。这个并不是仅有值,经历所得)。然后再将得到的输出经过softmax函数标准化,使得终究的列表和为1。

这个softmax的分数决议了当时单词在每个语句中每个单词方位的表明程度。很明显,当时单词对应语句中此单词所在方位的softmax的分数最高,可是,有时分attention机制也能重视到此单词外的其他单词,这很有用。

第五步是将每个Value向量乘以softmax后的得分。这儿实践上的含义在于保存对当时词的重视度不变的状况下,下降对不相关词的重视。

第六步是 累加加权值的向量。 这会在此方位发生self-attention层的输出(关于榜首个单词)。

总结self-attention的核算进程,(单词等级)便是得到一个咱们能够放到前馈神经网络的矢量。 可是在实践的完结进程中,该核算会以矩阵的办法完结,以便更快地处理。下面咱们来看看Self-Attention的矩阵核算办法。

Matrix Calculation of Self-Attention

榜首步是去核算Query,Key和Value矩阵。咱们将词嵌入转化成矩阵X中,并将其乘以咱们练习的权值矩阵(wQ,wK,wV)

X矩阵中的每一行对应于输入语句中的一个单词。 咱们看到的X每一行的方框数实践上是词嵌入的维度,图中所示的和论文中是有间隔的。X(图中的4个方框论文中为512个)和q / k / v向量(图中的3个方框论文中为64个)

终究,由于咱们正在处理矩阵,咱们能够在一个公式中浓缩前面进程2到6来核算self attention层的输出。

The Beast With Many Heads

本文经过运用“Multi-headed”的机制来进一步完善self attention层。“Multi-headed”首要经过下面2中办法改进了attention层的功能:

1. 它拓宽了模型重视不同方位的才能。在上面比方中能够看出,”The animal didn't cross the street because it was too tired”,咱们的attention机制核算出“it”指代的为“animal”,这在对言语的了解进程中是很有用的。

2.它为attention层供给了多个“representation subspaces”。由下图能够看到,在self attention中,咱们有多个个Query / Key / Value权重矩阵(Transformer运用8个attention heads)。这些调会集的每个矩阵都是随机初始化生成的。然后经过练习,用于将词嵌入(或许来自较低Encoder/Decoder的矢量)投影到不同的“representation subspaces(表明子空间)”中。

经过multi-headed attention,咱们为每个“header”都独立保护一套Q/K/V的权值矩阵。然后咱们仍是如之前单词等级的核算进程相同处理这些数据。

假如对上面的比方做相同的self attention核算,而由于咱们有8头attention,所以咱们会在八个时刻点去核算这些不同的权值矩阵,但终究完毕时,咱们会得到8个不同的矩阵。如下图:

瞧瞧,这会给咱们后续作业构成什么问题?

咱们知道在self-attention后边紧跟着的是前馈神经网络,而前馈神经网络承受的是单个矩阵向量,而不是8个矩阵。所以咱们需求一种办法,把这8个矩阵压缩成一个矩阵。

咱们怎样做?

咱们将这8个矩阵衔接在一起然后再与一个矩阵相乘。进程如下图所示:

这样multi-headed self attention的全部内容就介绍完了。之前或许都是一些进程的图解,现在我将这些进程衔接在一起,用一个全体的框图来表明一下核算的进程,希望能够加深了解。

现在咱们现已触及了attention的header,让咱们从头审视咱们之前的比方,看看例句中的“it”这个单词在不同的attention header状况下会有怎样不同的重视点。

如图:当咱们对“it”这个词进行编码时,一个留意力的焦点首要会集在“animal”上,而另一个留意力会集在“tired”

可是,假如咱们将一切留意力增加到图片中,那么作业或许更难了解:

Representing The Order of The Sequence Using Positional Encoding

# 运用方位编码表明序列的次序

咱们或许疏忽了去介绍一个重要的内容,便是怎样考虑输入序列中单词次序的办法。

为了处理这个问题,transformer为每个输入单词的词嵌入上增加了一个新向量-方位向量。

为了处理这个问题,变换器为每个输入嵌入增加了一个向量。这些方位编码向量有固定的生成办法,所以获取他们是很便利的,可是这些信息确是很有用的,他们能捕捉大奥每个单词的方位,或许序列中不同单词之间的间隔。将这些信息也增加到词嵌入中,然后与Q/K/V向量点击,取得的attention就有了间隔的信息了。

为了让模型捕捉到单词的次序信息,咱们增加方位编码向量信息(POSITIONAL ENCODING)-方位编码向量不需求练习,它有一个规矩的发生办法。

假如咱们的嵌入维度为4,那么实践上的方位编码就如下图所示:

那么生成方位向量需求遵从怎样的规矩呢?

调查下面的图形,每一行都代表着对一个矢量的方位编码。因而榜首行便是咱们输入序列中榜首个字的嵌入向量,每行都包括512个值,每个值介于1和-1之间。咱们用色彩来表明1,-1之间的值,这样便利可视化的办法表现出来:

这是一个20个字(行)的(512)列方位编码示例。你会发现它咋中心方位被分为了2半,这是由于左半部分的值是一由一个正弦函数生成的,而右半部分是由另一个函数(余弦)生成。然后将它们衔接起来构成每个方位编码矢量。

方位编码的公式在论文(3.5节)中有描绘。你也能够在中检查用于生成方位编码的代码get_timing_signal_1d()。这不是方位编码的仅有或许办法。可是,它具有能够扩展到看不见的序列长度的长处(例如,假如咱们练习的模型被要求翻译的语句比咱们练习会集的任何语句都长)。

The Residuals

这一节我想介绍的是encoder进程中的每个self-attention层的左右衔接状况,咱们称这个为:layer-normalization 进程。如下图所示:

在进一步探究其内部核算办法,咱们能够将上面图层可视化为下图:

Decoder的子层也是相同的,假如咱们想做堆叠了2个Encoder和2个Decoder的Transformer,那么它可视化就会如下图所示:

The Decoder Side

咱们现已根本介绍完了Encoder的大多数概念,咱们根本上也能够预知Decoder是怎样作业的。现在咱们来细心讨论下Decoder的数据核算原理,

当序列输入时,Encoder开端作业,终究在其顶层的Encoder输出矢量组成的列表,然后咱们将其转化为一组attention的调集(K,V)。(K,V)将带入每个Decoder的“encoder-decoder attention”层中去核算(这样有助于decoder捕获输入序列的方位信息)

完结encoder阶段后,咱们开端decoder阶段,decoder阶段中的每个进程输出来自输出序列的元素(在这种状况下为英语翻译语句)。

上面实践上现已是运用的阶段了,那咱们练习阶段是怎样的呢?

咱们以下图的进程进行练习,直到输出一个特别的符号,表明现已完结了。 The output of each step is fed to the bottom decoder in the next time step, and the decoders bubble up their decoding results just like the encoders did. 关于Decoder,和Encoder相同,咱们在每个Decoder的输入做词嵌入并增加上表明每个字方位的方位编码

Decoder中的self attention与Encoder的self attention略有不同:

在Decoder中,self attention只重视输出序列中的较早的方位。这是在self attention核算中的softmax进程之前屏蔽了特征方位(设置为 -inf)来完结的。

“Encoder-Decoder Attention”层的作业办法与"Multi-Headed Self-Attention"相同,仅仅它从下面的层创立其Query矩阵,并在Encoder仓库的输出中获取Key和Value的矩阵。

The Final Linear and Softmax Layer

Decoder的输出是浮点数的向量列表。咱们是怎样将其变成一个单词的呢?这便是终究的线性层和softmax层所做的作业。

线性层是一个简略的全衔接神经网络,它是由Decoder仓库发生的向量投影到一个更大,更大的向量中,称为对数向量

假定试验中咱们的模型从练习数据集上一共学习到1万个英语单词(“Output Vocabulary”)。这对应的Logits矢量也有1万个长度-每一段表明了一个仅有单词的得分。在线性层之后是一个softmax层,softmax将这些分数转换为概率。选取概率最高的索引,然后经过这个索引找到对应的单词作为输出。

上图是从Decoder的输出开端到终究softmax的输出。一步一步的图解。

Recap Of Training

现在咱们现已讲解了transformer的练习全进程了,让咱们回忆一下。

在练习期间,未经练习的模型将经过如上的流程一步一步核算的。并且由于咱们是在对符号的练习数据集进行练习(机器翻译能够看做双语平行语聊),那么咱们能够将模型输出与实践的正确答案相比较,来进行反向传达。

为了更好的了解这部分内容,咱们假定咱们输出的词汇只要(“a”,“am”,“i”,“thanks”,“student”和“”(“句末”的缩写))

在咱们开端练习之前,咱们模型的输出词汇是在预处理阶段创立的。

一旦咱们界说了输出的词汇表,那么咱们就能够运用相同宽度的向量来表明词汇表中的每个单词。称为one-hot编码。例如,咱们能够运用下面向量来表明单词“am”:

示例:咱们的输出词汇表的one-hot编码

下一节咱们再讨论一下模型的丢失函数,咱们优化的目标,引导一个练习有素且令人惊奇的准确模型。

The Loss Function

假定咱们正在练习一个模型,比方将“merci”翻译成“谢谢”。这意味着咱们希望模型核算后的输出为“谢谢”,但由于这种形式还没有承受过练习,所以这种状况不太或许发生。

这是由于模型的参数(权重)都是随机初始化的,因而(未经练习的)模型对每个单词发生的概率散布是具有无限或许的,可是咱们能够经过其他实践咱们希望的输出进行比较,然后运用反向传达调整一切模型的权重,使得输出更挨近所需的输出。

那么怎样比较算法猜测值与实在希望值呢?

实践上,咱们对其做一个简略的减法即可。你也能够了解穿插熵和Kullback-Leibler散度来把握这种差值的判别办法。

可是,需求留意的是,这仅仅一个很简略的demo,实在状况下,咱们需求输出一个更长的语句,例如。输入:“je suis étudiant”和预期输出:“I am a student”。这样的语句输入,意味着咱们的模型能够接连的输出概率散布。其间:

每个概率散布由宽度为vocab_size的向量表明(在咱们的示例中vocab_size为6,但实践上或许为3,000或10,000维度)

榜首概率散布在与单词“i”相关联的单元处具有最高概率

第二概率散布在与单词“am”相关联的单元格中具有最高概率

依此类推,直到第五个输出散布表明' '符号,意味着猜测完毕。

上图为:输入:“je suis étudiant”和预期输出:“I am a student”的希望猜测概率散布状况。

在算法模型中,尽管不能到达希望的状况,可是咱们需求在练习了满足长时刻之后,咱们的算法模型能够有如下图所示的概率散布状况:

现在,由于模型一次生成一个输出,咱们能够了解为这个模型从该概率散布(softmax)矢量中挑选了具有最高概率的单词并丢掉了其他的单词。

现在,由于模型一次生成一个输出,咱们能够假定模型从该概率散布中挑选具有最高概率的单词并丢掉其他的单词。

这儿有2个办法:一个是贪婪算法(greedy decoding),一个是波束查找(beam search)。波束查找是一个优化提高的技能,能够测验去了解一下,这儿不做更多解说

论文地址:https://arxiv.org/abs/1706.03762

原文转自:https://blog.csdn.net/qq_41664845/article/details/84969266

推荐新闻