多头注意力
在实践中,当给定相同的查询、键和值的集合时,我们希望模型可以基于相同的注意力机制学习到不同的行为,然后将不同的行为作为知识组合起来,捕获序列内各种范围的依赖关系(例如,短距离依赖和长距离依
赖关系)。因此,允许注意力机制组合使用查询、键和值的不同子空间表示(representation subspaces)可能是有益的。为此,与其只使用单独一个注意力汇聚,我们可以用独立学习得到的h组不同的线性投影(linear projections)来变换查询、键和值。然后,这h组变换后的查询、键和值将并行地送到注意力汇聚中。最后,将这h个注意力汇聚的输出拼接在一起,并且通过另一个可以学习的线性投影进行变换,以产生最终输出。这种设计被称为多头注意力(multihead attention)(Vaswani et al., 2017)。对于h个注意力汇聚输出,每一个注意力汇聚都被称作一个头(head)。下图展示了使用全连接层来实现可学习的线性变换的多头注意力。
模型
在实现多头注意力之前,让我们用数学语言将这个模型形式化地描述出来。给定查询\(q \in R^{d_q}\)、键\(k \in R^{d_k}\)和值\(v \in R^{d_v}\),每个注意力头\(h_i(i = 1, . . . , h)\)的计算方法为:
\[h_i = f(W^{(q)}_iq, W^{(k)}_ik,W^{(v)}_iv) \in R^{p_v} \]其中,可学习的参数包括\(W^{(q)}_i \in R^{p_q×d_q}\)、\(W^{(k)}_i \in R^{p_k×d_k}\)和\(W^{(v)}_i \in R^{p_v×d_v}\),以及代表注意力汇聚的函数f。f可以的加性注意力和缩放点积注意力。多头注意力的输出需要经过另一个线性转换,它对应着h个头连结后的结果,因此其可学习参数是 \(W_o \in R^{p_o×hp_v}\):
总结
多头注意力机制现在的使用是非常广泛的。为什么需要比较多的head呢?可以想成相关这件事情在做Self-attention的时候,就是用q去找相关的k,但是相关这件事情有很多种不同的形式,有很多种不同的定义,所以我们不能只有一个q,应该要有多个q,不同的q负责不同种类的相关性。
我们应在怎么做呢?首先对于这个\(q_i\)我们分别乘两个矩阵变成\(q^{i,1}\)和\(q^{i,2}\)。这个可以理解为两种不同的相关性。之后q,k,v都要有两个:
用第一个head:
用第二个head:
将这两个接起来,然后通过一个trannsform,也就是乘上一个矩阵,得到\(b_i\)传到下一层去。