注意力机制
众所周知,所有的模型都能在现实中找到原型,注意力机制自然也是来自于我们人类的注意力。举个例子,在视觉领域中我们会优先注意到红色、黄色这些颜色醒目的物体,这并不是我们自发去想要注意的,这就是非自主性提示。当我们自发地去关注某样东西,那我们就处在了自主性提示之下。
“是否包含自主性提示”将注意力机制与全连接层或汇聚层(pooling)区别开来。
注意力框架
主要有三个部分
查询(query): 自主性提示信息
键(key): 非自主性提示信息
值(value): 感官输入
a
1
a^1
a1到
a
4
a^4
a4是一个序列的4个部分,
α
\alpha
α是注意力分数也可以看作是关联度,我们用q(查询)去找到与q关联度高的k(键值),图上是
α
′
\alpha'
α′的原因是他还经过了一个softmax层做了归一化。
计算注意力分数的方法主要有两种,Dot-product(点积)和Additive(加性):
多头注意力
对于某些任务像是机器翻译和语音辨识,只使用一个相关性(q)去完成显然是不足的,因此我们会引入多个相关性的种类来更好的完成任务,这一点很像是CNN中使用多个卷积核去找不同的特征
位置编码
从上面的介绍应该能感受到自注意力机制比起用于处理序列的RNN其实更像是一个全连接层,
q
1
q^1
q1到
k
1
k^1
k1和
k
4
k^4
k4的距离其实是一样的。如何加入位置信息似乎是一个尚待研究的问题,现在一个解决方法是直接给
a
i
a^i
ai加上一个向量来区分位置,像这样:
简单粗暴,其中
e
i
e^i
ei的数据是由一个sin和cos函数构成的神奇式子,有兴趣可以去看一看。这样做的好处在于位置信息的加入完全不会破坏模型本身的架构,但问题就在于这个信息的加入你的模型能不能认出来
CNN与自注意力
自注意力会自行去关注数据中的一部分,这个效果就与CNN的卷积核很像,只是卷积核通常会去关注目标周围的数据而已。那么可以注意到CNN实际上就是受限制的自注意力,简单来说:
CNN只需要根据规定的感受野去计算
self-attention则是给出query然后去和全局的key去计算
在模型效果上,自注意力由于模型更加具有弹性(可以简单理解为可学习的部分更多)为了得到更好的效果需要大量的数据而,而CNN在小数据量时则比自注意力表现得更加优秀
RNN与自注意力
当序列比较长时RNN其实很难去关注到全局的信息,而自注意力则能通过查询关联度从而关注全局的信息。
另一方面,RNN的处理流程会将上一时刻的输出传给下一时刻的输入,这就导致了RNN注定会是一个串行的模型,而自注意力能同时处理所有序列并行度很高