aboutDL自然语言处理 (让机器更懂你)

transformer再记(编码器)

2019-02-23  本文已影响2人  madeirak
transformer整体结构

Attention Is All You Need(2017.6)

本文从微观角度(张量角度)讨论transformer的前向传播


自注意力层

一、计算自注意力的第一步就是用每个编码器的输入向量(每个单词的词向量)生成三个向量。也就是说对于每个单词,我们创造一个查询向量(Query)、一个键向量(Key)和一个值向量(Value)。(在本文的讨论范围内,及目前实际中绝大多数讨论中一个词的键向量等于值向量)。这三个向量是通过每个词嵌入向量与各自的权重矩阵相乘后创建的。可以发现这些新向量在维度上比词嵌入向量更低 ,论文中词嵌入和编码器的输入/输出向量的维度是512,新向量维度是64。但实际上不强求维度更小,这只是一种基于架构上的选择,它可以使多头注意力(multiheaded attention)的大部分计算保持不变。

X1与WQ权重矩阵相乘得到q1, 就是与这个单词相关的查询向量。最终使得输入序列的每个单词的创建一个查询向量、一个键向量和一个值向量。

二、计算自注意力的第二步是计算得分。假设我们在为一个例子中的第一个词“Thinking”计算自注意力向量,我们需要拿输入句子中的每个单词对“Thinking”打分。这些分数决定了在编码单词“Thinking”的过程中有多关注句子的其它部分。这些分数是通过打分单词(输入句子的所有单词)的键向量(Key)与“Thinking”的查询向量(Query)相点积来计算的。所以如果我们是处理位置最靠前的词的自注意力的话,第一个分数是q1和k1的点积,第二个分数是q1和k2的点积。

三、分数除以8(8是论文中使用的键向量的维数64的平方根,即\sqrt{d_k} ,这会让梯度更稳定。这里也可以使用其它值,8只是默认值)

四、然后通过softmax传递结果。softmax的作用是使所有单词的分数归一化,得到的分数都是正值且和为1。这个softmax分数决定了每个单词对编码当下位置(“Thinking”)的贡献。

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

六、对加权值向量求和(译注:自注意力的另一种解释就是在编码某个单词时,就是将所有单词的表示(值向量)进行加权求和,而权重是通过该词的表示(键向量)与被编码词表示(查询向量)的点积并通过softmax得到。),然后即得到自注意力层在该位置的输出(在我们的例子中是对于第一个单词)。 

这样自自注意力的计算就完成了。得到的向量就可以传给前馈神经网络。然而实际中,这些计算是以矩阵形式完成的,以便算得更快


实际中矩阵实现上述计算:

一、计算查询矩阵(Query)、键矩阵(Key)和值矩阵(Value)。为此,我们将输入句子的词嵌入装进矩阵X中,将其乘以我们训练的权重矩阵(W^Q、W^K、W^V)。

x矩阵中的每一行对应于输入句子中的一个单词。我们再次看到词嵌入向量 (512,或图中的4个格子)和q/k/v向量(64,或图中的3个格子)的大小差异。

步骤二到六可以合并为一个公式来计算自注意力层的输出。


多头注意力(“multi-headed” attention):

较普通自注意力优势:

1、它扩展了模型专注于不同位置的能力。

2、它给出了注意力层的多个“表示子空间”(representation subspace)。对于“多头”注意机制,我们有多个查询/键/值权重矩阵集(Transformer使用八个注意力头,因此我们对于每个编码器/解码器有八个矩阵集合)。这些集合中的每一个都是随机初始化的,在训练之后,每个集合都被用来将输入词嵌入(或来自上一级编码器/解码器的向量)投影到不同的表示子空间中。

如果我们做与上述相同的自注意力计算,只需八次不同的权重矩阵运算,我们就会得到八个不同的Z矩阵。

这给我们带来了一点挑战。前馈层不需要8个矩阵,它只需要一个矩阵(由每一个单词的表示向量组成)。所以我们需要一种方法把这八个矩阵压缩成一个矩阵。可以直接把这些矩阵拼接在一起,然后用一个附加的权重矩阵W^0与它们相乘,得到最终的Z矩阵。

多头注意力(multi-headed” attention)带来的“多重注意力”

当我们编码“it”一词时,一个注意力头集中在“animal”上,而另一个则集中在“tired”上,从某种意义上说,模型对“it”一词的表达在某种程度上是“animal”和“tired”的代表。

位置编码(Positional Encoding):

为了解决上述还缺少的理解输入单词顺序的方法,Transformer为每个输入的词嵌入添加了一个向量。

如果我们假设词嵌入的维数为4,则实际的位置编码如下:

更进一步,在下图中,每一行对应一个词向量的位置编码,所以第一行对应着输入序列的第一个词。每行包含512个值,每个值介于1和-1之间。我们已经对它们进行了颜色编码,所以图案是可见的。

20字(行)的位置编码实例,词嵌入大小为512(列)。你可以看到它从中间分裂成两半。这是因为左半部分的值由一个函数(使用正弦)生成,而右半部分由另一个函数(使用余弦)生成。然后将它们拼在一起而得到每一个位置编码向量。


综上一个编码器的结构如下图所示。我们需要提到一个编码器架构中的细节:在每个编码器中的每个子层(自注意力、前馈网络)的周围都有一个残差连接(虚线),并且都跟随着一个“层归一化”步骤。

虚线是残差连接

下一篇:transformer再记(解码器)

参考文章:BERT大火却不懂Transformer?读这一篇就够了

上一篇下一篇

猜你喜欢

热点阅读