0%

注意力机制

注意力机制三个核心要素:

  • Query:即主动注意力。
  • key:突出性的环境带给人的被动注意力
  • value:注意力汇聚之后得到的最终输入
通过注意力汇聚将query和key结合在一起,然后对value进行选择输出

注意力——本质是一种加权平均

假设有\([(x_i,y_i), ... ,(x_j,y_j)]\) 一系列配对输入,对于一个新的 \(x\) ,我们想要预测它的 \(y\) 。此时我们会想参考过往的所有配对情况,来试着加权平均出这个 \(y\),例如我们可以平等对待所有过往经验:

\[ f(x)=\frac{1}{n}\sum_{i=1}^{n} y_{i} \]

显然这样是不准确的,对于任意输入\(x\)都会得到同样的结果。因此我们还需要考虑\(x\)的影响。继续直观地想,我们可以考虑\(x\)与哪一个\(x_i\)更接近,那么\(y\)给到\(y_i\)的权重也应该更大一些:

\[ f(x)=\sum_{i=1}^{n} \frac{K\left(x-x_{i}\right)}{\sum_{j=1}^{n} K\left(x-x_{j}\right)} y_{i}=\sum_{i=1}^{n} \alpha\left(x, x_{i}\right) y_{i} \]

其中\(K\)是一种核函数,来表示\(x_i\)\(x\)的权重关系,分母是权重和(即对于\(x\)来说的固定值)。缩写之后得到\(\alpha(x,x_i)\),即表示所谓的注意力权重,其累积和为1。回到注意力框架中,\(x\)即是query,(x_i,y_i)即是(key,value)。\(\alpha\)\(y_i\)的加权即是注意力汇聚,注意力权重即query和key的关系度量。

对于核函数\(K\),如果\(K\)中计算函数固定,这样得到的就是非参数的注意力汇聚。如果\(K\)中带有一些可变可学习的参数\(w\),那么得到的就是 带参数的注意力汇聚

有了核函数以及加权平均的概念,此时就可以来看更细致的注意力机制:

注意力机制的详细结构

其中核函数的单项计算部分可以看做是注意力评分函数(attention scoring function),核函数的多项累计部分可以看做softmax,转化评分为累计和为1的权重系数。最后与value数组进行加权计算,即是注意力汇聚的过程。

评分函数

Masked Softmax

虽然是加权平均,但实际计算中存在很多value不需要进入加权计算。例如文本处理中的填充字符。因此可以使用一个Mask来过滤掉这些不必要的字符,再进行softmax。实际使用中对于想要去掉的元素,会赋值为一个非常大的负数,这样其softmax输出就是0.

Additive Attention

当query和key是同样形状的张量时,各种核函数都可以简单的应用。但是query和key是不同长度的时候呢?这时可以使用Additive Attention作为评分函数,本质上就是通过两个线性变换层将它们投影到统一长度空间:

\[ a(\mathbf{q}, \mathbf{k})=\mathbf{w}_{v}^{\top} \tanh \left(\mathbf{W}_{q} \mathbf{q}+\mathbf{W}_{k} \mathbf{k}\right) \in \mathbb{R}, \]

\(\mathbf{W}_{q} \in \mathbb{R}^{h \times q} 、 \mathbf{W}_{k} \in \mathbb{R}^{h \times k}\)\(\mathbf{w}_{v} \in \mathbb{R}^{h}\) 是用于学习自适应调整的参数。

Scaled Dot-Product Attention

点积是一种很容易想到的计算query和key距离的方式,而且效率很高。因此结合缩放思想可以构造出方差为1的度量距离方式:

\[ a(\mathbf{q}, \mathbf{k})=\mathbf{q}^{\top}\mathbf{k}/\sqrt{d} \]

其中\(d\)为向量长度(显然query和key需要相同长度)。当然,为优化性能,实际计算会使用矩阵计算一个批量的点积。

编码器-解码器中的注意力机制

在编码器-解码器框架中,会将这一批所有的输入做成一个不变的上下文,再通过这个上下文去计算这一批所有的预测。显然对于某些预测计算来说,可能会与一部分输入毫无关系,这样粗暴的使用一个统一的上下文并不合理。因此可以想到对每次预测计算,定制一个属于它的上下文,即基于注意力机制定制上下文

\[ \mathbf{c}_{t^{\prime}}=\sum_{t=1}^{T} \alpha\left(\mathbf{s}_{t^{\prime}-1}, \mathbf{h}_{t}\right) \mathbf{h}_{t} \]

对于某时刻\(t\)的预测计算,\(s\)为解码器上一时刻隐状态,\(h\)为编码器该时刻隐状态。将\(s\)视为query,\(h\)视为key,同时也视为value,最终加权得到基于注意力的上下文\(c_{t^`}\),再与解码器的输入进行连接,送入RNN进行计算:

基于注意力的编码器-解码网络:其中解码器的每一次计算都需要(编码器隐状态,解码器上一时间隐状态),并且这里评分函数使用的是加性注意力。

MultiHead Attention

和多个卷积核学习多种特征一样,我们也可以想到使用多个Attention来学习到多种联系。其中每一个Attention被称作一个Head。而为了实现多个Head学习到不同的联系,需要给它们不完全相同的数据,如使用全连接层进行线性投影,取一部分原数据的子空间给一个Head。当然汇聚不同Head的输出也需要一种连接方式,即也采用一个线性变换将Multi Head组合起来:

MultiHead Attention

因此可以容易给出MultiHead Attention的数学模型:给定query \(\mathbf{q} \in \mathbb{R}^{d_{q}}\) 、key \(\mathbf{k} \in \mathbb{R}^{d_{k}}\) 和value \(\mathbf{v} \in \mathbb{R}^{d_{v}}\), \(\quad f\) 为注意力汇聚操作,每个Head \(\mathbf{h}_{i}(i=1, \ldots, h)\) 的计算方法为:

\[ \mathbf{h}_{i}=f\left(\mathbf{W}_{i}^{(q)} \mathbf{q}, \mathbf{W}_{i}^{(k)} \mathbf{k}, \mathbf{W}_{i}^{(v)} \mathbf{v}\right) \in \mathbb{R}^{p_{v}} \]

Self-Attention

顾名思义,就是query,key,value都是同一个序列\([x_1,...,x_n]\)。其输出结果\([y_1,...,y_n]\)为:

\[ \mathbf{y}_i = f(\mathbf{x}_i, (\mathbf{x}_1, \mathbf{x}_1), \ldots, (\mathbf{x}_n, \mathbf{x}_n)) \in \mathbb{R}^d \]

注意力和卷积

从某种直观上来看,卷积的局部加权平均 和 注意力的加权平均(特别是自注意力) 有点相似?

推荐资料

The Illustrated Transformer