Self Attention Mechanism
对于特征X,同时通过 Positional Encoding 得到所有的位置向量,将其相加(维度相同,可以直接相加),得到该语音真正的向量表示。第 t 个字的向量记作
接着我们定义三个矩阵,使用这三个矩阵分别对所有的字向量进行三次线性变换,于是所有的字向量又衍生出三个新的向量
。我们将所有的
向量拼成一个大矩阵,记作查询矩阵 Q,将所有的
向量拼成一个大矩阵,记作键矩阵 K,将所有的
向量拼成一个大矩阵,记作值矩阵 V(见下图).
![](https://img.haomeiwen.com/i4388713/03b3694200c09a8a.gif)
为了获得第一个字的注意力权重,我们需要用第一个字的查询向量 乘以键矩阵 K(见下图)
![](https://img.haomeiwen.com/i4388713/c98bfc29ab59b686.png)
![](https://img.haomeiwen.com/i4388713/aabf982c54c58622.gif)
之后还需要将得到的值经过 softmax,使得它们的和为 1 : softmax ([2,4,4,]) =([0.0634, 0.4683, 0.4683])
有了权重之后,将权重其分别乘以对应字的值向量 (见下图)
![](https://img.haomeiwen.com/i4388713/fc636e1bc5c33423.gif)
对其它的输入向量也执行相同的操作,即可得到通过 self-attention 后的所有输出
![](https://img.haomeiwen.com/i4388713/745691ad3a87a97a.gif)
![](https://img.haomeiwen.com/i4388713/64c099a47b1af6a8.gif)
![](https://img.haomeiwen.com/i4388713/1e43de85ef3af613.png)
Padding Mask
![](https://img.haomeiwen.com/i4388713/6a04269640159d68.png)
上面 Self Attention 的计算过程中,我们通常使用 mini-batch 来计算,也就是一次计算多句话,即 X 的维度是 [batch_size, sequence_length],sequence_length 是句长,而一个 mini-batch 是由多个不等长的句子组成的,我们需要按照这个 mini-batch 中最大的句长对剩余的句子进行补齐,一般用 0 进行填充,这个过程叫做 padding
但这时在进行 softmax 就会产生问题。回顾 softmax 函数 ,
是 1,是有值的,这样的话 softmax 中被 padding 的部分就参与了运算,相当于让无效的部分参与了运算,这可能会产生很大的隐患。因此需要做一个 mask 操作,让这些无效的区域不参与运算,一般是给无效区域加一个很大的负数偏置,即
![](https://img.haomeiwen.com/i4388713/58a7a3a67319cf17.png)
Masked Self-Attention
具体来说,传统 Seq2Seq 中 Decoder 使用的是 RNN 模型,因此在训练过程中输入 t 时刻的词,模型无论如何也看不到未来时刻的词,因为循环神经网络是时间驱动的,只有当 t 时刻运算结束了,才能看到 t+1 时刻的词。而 Transformer Decoder 抛弃了 RNN,改为 Self-Attention,由此就产生了一个问题,在训练过程中,整个 ground truth 都暴露在 Decoder 中,这显然是不对的,我们需要对 Decoder 的输入进行一些处理,该处理被称为 Mask
举个例子,Decoder 的 ground truth 为 " <start> I am fine",我们将这个句子输入到 Decoder 中,经过 WordEmbedding 和 Positional Encoding 之后,将得到的矩阵做三次线性变换。然后进行 self-attention 操作,首先通过
得到 Scaled Scores,接下来非常关键,我们要对 Scaled Scores 进行 Mask,举个例子,当我们输入 "I" 时,模型目前仅知道包括 "I" 在内之前所有字的信息,即 "<start>" 和 "I" 的信息,不应该让其知道 "I" 之后词的信息。道理很简单,我们做预测的时候是按照顺序一个字一个字的预测,怎么能这个字都没预测完,就已经知道后面字的信息了呢?Mask 非常简单,首先生成一个下三角全 0,上三角全为负无穷的矩阵,然后将其与 Scaled Scores 相加即可
![](https://img.haomeiwen.com/i4388713/a277df631597f7c5.png)
之后再做 softmax,就能将 - inf 变为 0,得到的这个矩阵即为每个字之间的权重
![](https://img.haomeiwen.com/i4388713/fec9ff6ae31276bc.png)
![](https://img.haomeiwen.com/i4388713/f2ff38a15d9f533b.png)
网友评论