Transformer来自于谷歌的工作attention is you need!
1.先把transformer想象成一个黑匣子在机器翻译中的处理流程如下:
2剖开transformer结构:内部是一个encoders-decoders框架
3.再剖开encoders-decoders:分别为6个encoder和6个decoder组成
4.再剖开encoder:对于Encoders中的每一个Encoder,他们结构都是相同的,但是并不会共享权值。每层Encoder有2个部分组成:self-attention层和一个前向神经网络组成。
5.剖开decoder:每个Decoder也同样具有这样的层级结构,但是在这之间有一个Attention层,帮助Decoder专注于与输入句子中对应的那个单词(类似与seq2seq models的结构)
1.词嵌入:将每个单词编码为一个512维度的向量,我们用上面这张简短的图形来表示这些向量。词嵌入的过程只发生在最底层的Encoder。但是对于所有的Encoder来说,你都可以按下图来理解。输入(一个向量的列表,每个向量的维度为512维,在最底层Encoder作用是词嵌入,其他层就是其前一层的output)。另外这个列表的大小和词向量维度的大小都是可以设置的超参数。一般情况下,它是我们训练数据集中最长的句子的长度。
2.encoding词向量,首先经过self-attrntion处理再把处理结果给前向神经网络进行处理最后传到下一个encoder继续处理:
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的第一步是从每一个encoder的输入向量上创建三个向量(在这个情况下,对每个单词做词嵌入)。所以,对于每一个单词,这里创建一个Query向量,一个Key向量,一个Value向量,这几个向量是我们的词嵌入之后乘以3个训练矩阵而产生的。
这个时候新的向量的维度就相应的降低了(这取决于那三个训练矩阵),这个时候新的向量的维度只有64维了,为什么要降低,为什么是64维呢?这个问题在后面的多头注意力中说明。这里只要知道经过这个处理会后相应的维数下降就行了。
这里,将X1乘以WQ得到q1,将X1乘以WK得到k1,将X1乘以WV得到v1,同理q2,k2,v2的计算过程也一样。计算的第二步是计算得分,以上图为例,假设我们在计算第一个词thinking的self-attention。我们需要根据这个单词对输入句子的每个单词进行评分。当我们在某个位置编码单词时,分数决定了对输入句子的其他单词的关注程度。
通过将query向量和key向量点击来对相应的单词打分。所以,如果我们处理开始位置的的self attention,则第一个分数为q1和k1的点积,第二个分数为q2和k2的点积。如下图
第三步和第四步的计算,是将第二部的得分除以8(根号dk)(论文中使用key向量的维度是64维,其平方根=8,这样可以使得训练过程中具有更稳定的梯度。这个根号dk并不是唯一值,经验所得)。然后再将得到的输出通过softmax函数标准化,使得最后的列表和为1。
这个softmax的分数决定了当前单词在每个句子中每个单词位置的表示程度。很明显,当前单词对应句子中此单词所在位置的softmax的分数最高,但是,有时候attention机制也能关注到此单词外的其他单词,这很有用。
第五步是将每个Value向量乘以softmax后的得分。这里实际上的意义在于保存对当前词的关注度不变的情况下,降低对不相关词的关注。
第六步是 累加加权值的向量。 这会在此位置产生self-attention层的输出(对于第一个单词)。
总结self-attention的计算过程,(单词级别)就是得到一个我们可以放到前馈神经网络的矢量。 然而在实际的实现过程中,该计算会以矩阵的形式完成,以便更快地处理。下面我们来看看Self-Attention的矩阵计算方式。
第一步是去计算Query,Key和Value矩阵。我们将词嵌入转化成矩阵X中,并将其乘以我们训练的权值矩阵(WQ,WK,WV)。
矩阵中的每一行对应于输入句子中的一个单词。 我们看到的X每一行的方框数实际上是词嵌入的维度,图中所示的和论文中是有差距的。X(图中的4个方框论文中为512个)和q / k / v向量(图中的3个方框论文中为64个)
最后,由于我们正在处理矩阵,我们可以在一个公式中浓缩前面步骤2到6来计算self attention层的输出。
论文中通过使用“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个矩阵连接在一起然后再与一个矩阵WO相乘。步骤如下图所示
整体的计算流程如下:
知道了attention和header后再来看之前的列子,看看句子中it这个单词在不同的attention header情况下的关注点:
这个时候,在对it编码时,it的一个注意力集中在animal,而另一个就集中在tird上面了。但是,如果我们将所有注意力添加到图片中,那么事情可能更难理解:
到此注意相关的就介绍完了!
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。