顾名思义,多头注意力是指我们可以使用多个注意力头,而不是只用一个。也就是说,我们可以应用在上篇中学习的计算注意力矩阵Z的方法,来求得多个注意力矩阵。让我们通过一个例子来理解多头注意力层的作用。以All is well这句话为例,假设我们需要计算well的自注意力值。在计算相似度分数后,我们得到图所示的结果。
从图中可以看出,well的自注意力值是分数加权的值向量之和,并且它实际上是由All主导的。也就是说,将All的值向量乘以0.6,而well的值向量只乘以了0.4。这意味着
z
w
e
l
l
z_{well}
zwell将包含60%的All的值向量,而well的值向量只有40%。
这只有在词义含糊不清的情况下才有用。以下句为例:A dog ate the food because it was hungry(一只狗吃了食物,因为它很饿)假设我们需要计算it的自注意力值。在计算相似度分数后,我们得到下图所示的结果。
从图中可以看出,it的自注意力值正是dog的值向量。在这里,单词it的自注意力值被dog所控制。这是正确的,因为it的含义模糊,它指的既可能是dog,也可能是food。
如果某个词实际上由其他词的值向量控制,而这个词的含义又是模糊的,那么这种控制关系是有用的;否则,这种控制关系反而会造成误解。为了确保结果准确,我们不能依赖单一的注意力矩阵,而应该计算多个注意力矩阵,并将其结果串联起来。使用多头注意力的逻辑是这样的:使用多个注意力矩阵,而非单一的注意力矩阵,可以提高注意力矩阵的准确性。我们将进一步探讨这一点。
假设要计算两个注意力矩阵 Z 1 Z_1 Z1和 Z 2 Z_2 Z2。首先,计算注意力矩阵 Z 1 Z_1 Z1。
我们已经知道,为了计算注意力矩阵,需要创建三个新的矩阵,分别为查询矩阵、键矩阵和值矩阵。为了创建查询矩阵 Q 1 Q_1 Q1、键矩阵 K 1 K_1 K1和值矩阵 V 1 V_1 V1,我们引入三个新的权重矩阵,称为 W 1 Q , W 1 K , W 1 V W_1^Q , W_1^K, W_1^V W1Q,W1K,W1V。用矩阵X分别乘以矩阵 W 1 Q , W 1 K , W 1 V W_1^Q , W_1^K, W_1^V W1Q,W1K,W1V,就可以依次创建出查询矩阵、键矩阵和值矩阵。
基于以上内容,注意力矩阵
Z
1
Z_1
Z1可按以下公式计算得出。
Z
1
=
s
o
f
t
m
a
x
(
Q
1
⋅
K
1
T
d
k
)
V
1
Z_1 = softmax(\frac{Q_1·K_1^T}{\sqrt{d_k}})V_1
Z1=softmax(dkQ1⋅K1T)V1
接下来计算第二个注意力矩阵 Z 2 Z_2 Z2。
为了计算注意力矩阵 Z 2 Z_2 Z2,我们创建了另一组矩阵:查询矩阵 Q 2 Q_2 Q2、键矩阵 K 2 K_2 K2和值矩阵 V 2 V_2 V2,并引入了三个新的权重矩阵,即 W 2 Q , W 2 K , W 2 V W_2^Q , W_2^K, W_2^V W2Q,W2K,W2V。用矩阵 X X X分别乘以矩阵 W 2 Q , W 2 K , W 2 V W_2^Q , W_2^K, W_2^V W2Q,W2K,W2V,就可以依次得出对应的查询矩阵、键矩阵和值矩阵。注意力矩阵 Z 2 Z_2 Z2可按以下公式计算得出。
Z 2 = s o f t m a x ( Q 2 ⋅ K 2 T d k ) V 2 Z_2 = softmax(\frac{Q_2·K_2^T}{\sqrt{d_k}})V_2 Z2=softmax(dkQ2⋅K2T)V2
同理,可以计算出
h
h
h个注意力矩阵。假设我们有8个注意力矩阵,即
Z
1
Z_1
Z1到
Z
8
Z_8
Z8,那么可以直接将所有的注意力头(注意力矩阵)串联起来,并将结果乘以一个新的权重矩阵
W
0
W_0
W0,从而得出最终的注意力矩阵,公式如下所示。
现在,我们已经了解了多头注意力层的工作原理。下篇将介绍另一个有趣的概念,即位置编码(positional encoding)。