注意力机制,就像是建立了上文的一张表,每次生成时,通过查表获取相关的上文信息,然后继续生成。
其核心在于三张表:
- K(Key):键,也就是信息向外暴露匹配的接口
- V(Value):值,也就是匹配后需要向外传递的信息
- Q(Query):查询匹配的规则接口
核心公式就一个:
$${\rm Attn}(Q, K, V) = {\rm Softmax}\left(\frac {QK^T}{\sqrt {d_k}}\right) V $$
在模型 encoder 中,有 self-attention。这指的是对于输入序列,对于每一个元素,都查询其与其他元素的联系,并获取信息。
例如有一串输入 $X = [x_1, x_2, \cdots, x_n]^T \in {\mathbb R}^{n \times d}$(每行一个词元),那么可以利用三个投影矩阵 $W^Q, W^K, W^V$,将输入投影到 $Q, K, V$ 三个空间上:
$$\begin{aligned} Q = X W^Q \in {\mathbb R}^{n \times t} \\ K = X W^K \in {\mathbb R}^{n \times t} \\ V = X W^V \in {\mathbb R}^{n \times t} \end{aligned} $$
得到的矩阵每行代表一个词元的相关值,那么查询的部分就是 $q_i k_t^T$,整体查询就是 $QK^T \in {\mathbb R}^{n \times n}$,对其做 softmax 计算后,就可以得出两两间的关联度,根据其大小,乘上 $V$ 获取真实的信息即可。
$${\rm Attn}(Q, K, V) = {\rm Softmax}\left(\frac {QK^T}{\sqrt {d_k}}\right) V \in {\mathbb R}^{n \times t} $$
类似于 CNN 多个卷积核升维的操作,我们也可以利用多个投影来获取多个 Attn,最后聚合:
$${\rm MultiAttn}(Q, K, V) = {\rm Concat}_i \{{\rm Attn(Q W_i^Q, K W_i^K, V W_i^V)}) \} W^O $$
换句话来说,我们可以得到若干 ${\rm Attn}_i = {\rm Attn}(X W_i^Q, X W_i^K, X W_i^V)$,于是可以构造:
$${\rm Attn} = [{\rm Attn}_1, {\rm Attn}_2, \cdots, {\rm Attn}_k] \in {\mathbb R}^{n \times (nt)} $$
但是我们需要合并这些信息,所以增加一个 $W^O \in {\mathbb R}^{nt \times s}$
$${\rm Z} = {\rm Attn} W^O \in {\mathbb R}^{n \times s} $$
继续类似 CNN 感受野的想法,我们其实完全可以做一个 self-attention(restricted),也就是对于每一个元素,做一个滑动窗口,只做窗口内的全连接。这样,虽然需要 $O(n/r)$ 层才能达到相同的效果(复杂度没变),但是每一个矩阵大大减小,对于计算显存的要求大大减小,对 Mem Cache 更友好,这使得在资源首先的机器上计算注意力成为可能,并且可以实现并行计算,层内的计算可以高度并行进行。
根据 神秘 言论,堆叠注意力可以实现局部注意力 + 多层聚合关注全局语义,对细节的把控甚至可能更好。层次化提取吗,感觉和 CNN 很想,只是变成了序列,并且更换了另一个卷积核。
而且其实可以可以实现 Sparse Attention。
但是显然语言是有顺序的,而我们忽略了这一点,所以需要对 $x$ 进行处理,加入位置信息。一个方式就是利用 三角函数的 embedding。其提出的要求是:
因此,我们需要这样一种位置表示方式,满足于:
(1)它能用来表示一个token在序列中的绝对位置
(2)在序列长度不同的情况下,不同序列中token的相对位置/距离也要保持一致
(3)可以用来表示模型在训练过程中从来没有看到过的句子长度。
为了让编码相对连续,并且有很好的变化,相邻的相似性,可以考虑三角函数的正交空间。可以有这样一个事实:
$$\begin{bmatrix} \sin(t + \Delta) \\ \cos(t + \Delta) \end{bmatrix} = \begin{bmatrix} \cos \Delta & \sin \Delta \\ - \sin \Delta & \cos \Delta \end{bmatrix} \begin{bmatrix} \sin t \\ \cos t \end{bmatrix} $$
也就是说,我们既可以用三角函数表示绝对位置,也可以很好通过该线性性获取相对位置。于是就可以提出 PE 编码:
$$PE_t = [\sin \omega_0 t, \cos \omega_0 t, \sin \omega_1 t, \cos \omega_1 t, \cdots, \sin \omega_{\frac {d} 2 - 1} t, \cos \omega_{\frac d 2 - 1} t] $$
其中 $\omega_k$ 表示一个很小的频率,例如 $(10000^{\frac k {d - 1}})^{-1}$ 。
该编码最巧妙的性质是:
$$PE_m^T PE_n = PE_n^T PE_m = \sum \cos(w_i (m - n)) $$
也就是位置编码的乘积只和相对位置有关,并且保有对称性(交换律)。而且对于这个乘积,如果 $m - n$ 越大,那么值越小,也就是保有了距离的衰减性。
但实际上这个性质看似优秀,真的在 Attention 中使用到了吗?需要严肃论证一下。
我目前的想法是,考虑到矩阵的乘法没有交换性,而且在 $QK^T$ 的过程中,我们实际上是 $X_i W^Q (W^K)^T X_j$,所以几乎没法保留其“距离的衰减性”
更多变体: