topic: 该如何对注意力机制进行改进
普遍的修改分为三个部分
- Attention 内部的改进
- Attention 结构的改进
- Attention 应用的改进
PART01:Attention 内部的改进
首先要明确Attention的计算流程,Attention接受$QKV$3个输入, 首先通过矩阵乘法来度量向量之间的相似性
相似性度量
除了点积能够度量相似性之外,欧式距离,皮尔逊相关系数都可以,或者根据你的数据类型,还可以选择DTW等等算法来替换掉原始的点积操作,再或者,直接构造一个度量函数,例如可以通过一个全连接层,把要建立相关性的a和b作为输入,然后后面再接一个Sigmoid 激活函数,这样的话,输出可以看做一个权重
$$ \alpha = sigmoid(MLP(a,b)) $$当然了,点积的效率是最高的,如果不缺那点计算资源,可以尽情的修改,修改之后,故事能够多写一点
那么在得到注意力矩阵之后,应该通过softmax来归一化权重表示,将它们拉到同一个量纲上面,避免过大或者过小的权重值
归一化
在这里的归一化操作,除了 softmax,还可以通过 Sigmoid 函数直接生成权重,Sigmoid函数是一个天然的权重生成器
此外还可以使用最大值归一化,再或者干脆不使用归一化
实际这一部分并没有很大的创新价值,除非能在你的任务上提供实验或者理论证明,能说明白,为什么你使用的归一化的方法在你的任务上它们要比softmax要好,这样才会更好一点
加权
那么归一化权重之后,还要通过归一化以后得注意力权重矩阵,对value矩阵进行加权,得到最终的输出
首先,传统的注意力,归一化以后得注意力权重矩阵是 $N×N$ 的,与 Value 矩阵进行矩阵乘法
- 第一行与第一列相乘,来更新第一个节点的第一个特征
- 第一行与第二列相乘,来更新第一个节点的第二个特征
- 每一个特征的更新,都是对所有节点进行加权平均
这样的计算很慢,对于一些任务来说,一些微小的计算负担,就能够影响模型在实际系统上的部署
那么为了降低计算负担, 思考能不能为每一个节点只学习一个权重?
这里有 N 个节点,,我们可以为 N 个节点只学习一个权重,这样的话,这里的注意力矩阵就不是 $N×N$ ,而是 $ N×1 $
这样的话不仅加权平均的时候计算负担小,那么很有可能在计算这个注意力矩阵的时候,也就不需要 $N×N$ 的计算复杂度了
PART02:Attention 结构的改进
第二类的改进,主要集中在对Attention的结构上进行修改,要知道,Attention核心是加权平均,先有权重然后再加权求和
优点是什么呢?
优点是拥有全局的感受野,在这一类的改进中,权重的计算已经不是最重要的了,这一部分涉及到的改进可能需要权重,也有可能不需要权重. 但是它们保留了attention的优点,那就是依然具有全局感受野,更新之后,也具有全局的上下文表示,这一类主要是以线性注意力为主
这一块,新手很难去做创新,最简单的就是可以将线性注意力迁移到自己的任务上
换一换领域,换一换数据,在保证性能的前提下,降低计算复杂度是一个很好的切入点的
PART03:Attention 应用的改进
第三个改进最简单,上限也高,下限也低,那就是Attention的应用
下限低主要是指将Attention直接应用到自己的任务上,现在来看这样的创新是比较low的,因为用的人太多
那么attention的应用能有什么创新呢?
这应用能有什么创新呢?应用除了使用,还有…
Attention接收$QKV$3个输入 ,这就说明了它的输入可以是多样化的,既然可以实现多样化的输入,那么应用于任何一个不同的任务它都能够具有不同的意义
这里提供两种改进思路
分别是QKV以及注意力矩阵的mask操作
1️⃣ 首先来看对QKV的修改
QKV也有两个改进思路
① 第一个你的QKV是什么?仅仅就是一个单纯的输入吗?
考虑到几乎所有的任务都存在局部和全局特征,那是不是可以定义K矩阵为局部特征或者全局特征表示,那这样的话Q和K再相乘,就可以使Q矩阵拥有更大的感受野
再进一步,想要实现多尺度的特征表示,就可以堆叠多个这样的注意力层,在任何一个不同的注意力层,都使这个 K 矩阵具备不同的局部特征表示
其中局部特征表示可以通过简单的卷积层来实现,那么这样的话,就能够使模型具有一个多尺度的感受野,还能够降低计算复杂度
如果卷积操作不使用padding操作的话,长度是会缩短的,就会提高计算效率
反过来说,既然可以使K矩阵具有局部特征表示,那么同样的Q矩阵也可以具有局部特征表示
保持K矩阵不变,通过卷积来提取Q矩阵的局部特征表示,同样的操作堆叠多个具有不同感受野的注意力层,也能够提取多尺度的特征表示
最后可以将每个层的输出,通过上采样恢复原有的shape大小, 最后进行拼接相加,加权求和
② 第二个改进思路,QKV怎么来的?
和第一个思路具有共同点,首先K矩阵既可以是原始的输入,也可以是通过卷积层提取的局部特征表示
如果节点个数太多的话,不仅计算负担比较大,还有可能因为关注所有节点出现信息冗余现象,那我们就可以选择部分节点,具体来说,可以生成一个随机数来选择,也可以规律的去选择选择第一个,第三个,第五个,第七个,或者说,第二个,第四个,第六个,第八个,第十个节点
2️⃣ 第二个改进点是注意力矩阵的mask操作
当计算完成之后,可以选择性的保留注意力矩阵中的某些值,选择性的过滤掉一些不重要的节点对之间的关系
这也是比较重要的创新,也有两个创新方向
① 当出发点是局部全局关系的时候
可以通过mask操作,为每一个节点保留局部或者是全局的其他相关性节点,局部全局可以分开考虑
② 第二个通过所做任务的一些先验知识,或者说从中挖掘到知识,判断该保留哪些节点对之间的关系,或者说该丢掉哪些节点对之间的关系