漫谈Attention-Mechanism[注意力机制]
漫谈 Attention Mechanism[注意力机制]
Attention 的核心思想就是从关注全部到关注重点。
看了这个 up 主的一些介绍【传送门】
1. 注意力机制的由来
如下面这张图,我们观察一张图片或者一段文字的时候,并不是对每个部分都付出了同样的注意力,而是有所侧重的,如下面这张图中,婴儿的脸,文字的标题这些是我们更关注的。但是对于 CNN, RNN, 以及 LSTM 等模型很难决定什么是重要的,什么不重要,于是产生了注意力机制。
2. 注意力机制的实现过程
那么注意力机制是怎么在神经网络中实现的呢?
首先我要观察一张图,我可能会习惯性的有所侧重的去看。我潜意识中会有一个Q(查询对象)表示我更关心的内容,而准备观察的图是K(被查询对象)。
看一段评论区的解释:
Q是要搜索的词, 例如 “苹果”这个词在 ,“我要吃苹果” 这句话中与每个词的相似度求解。 Q = 苹果, K1 = 我 k2=要 k3=吃 k4=苹果。 Q 分别与K1-4 进行相似度的比较得到一个score 分数,如果这个score 越高说明相似度越高。 然后通过softmax 归一化,就是相似度的百分比。 最后在和 V 相乘 求和。 得到注意力矩阵。
这里需要明白一个背景,就能记住 q k v 分别是干什么的了。 这里注意力机制的本质是提取特征,也就是说一个词在一个句子中的特征。 用一个简单的例子来说,就是你在你公司里面属于什么地位。 比如一个公司有三个人, 你, 小红,小强。 就要算出它们之间都是什么关系, 说白了关系好的之间的分数就高,最终用小数表示。 例如你和你自己的关系是 0.7, 你和小红的关系是0.2,你和小强的关系是0.1. 分值大说明关系好。 而且 三个关系相加刚好是1 也就是100%。 那么这个之间的关系是如何计算出来的呢 ?就需要对每个人设置三个值, 就是 k q v。 k 是用来被别人查的,q 是用来查别人的, v 是用来算分数的。 这三个严格来说都是矩阵向量,最开始的时候是随机生成的,通过不断迭代训练计算出来(涉及到正向传递,反向传递,损失函数,求w b ,这里不展开)。 回到你的问题,v 是用来算分的,也就是你和其他人之间的关系到底是多少得分,就是通过v 算出来的。 它是在 k 和q 两两计算计算得到的结果进行归一化的结果之后,再进行乘积求和得到的。
简单一句话,v 就是用来算分的, 算关系的,算你和其他人的关系。 算这个词和整句话中其他词的关系。
通过计算 F(Q, K) (点积运算)得到了 Q 和 K 的一个相似度 s,相似度越高,代表这部分信息我将更关注。然后将 s 用 softmax 归一化成一组比例 a。然后用这个代表了重要程度的比例 a 和原始数据 V 进行加乘操作,最终得到了附加有观察侧重信息的数据 V’(Attention Value),用这个 V‘ 替代原来的 V。
下面内容参考【传送门】
知道了 Attention 的大致原理,下面来看一下比较详细的执行过程:
Embedding 就是用一个数值向量“表示”一个对象(Object)的方法。 “实体对象”可以是image、word等,“数值化表示”就是一个编码向量。 例如对“颜色“这种实体对象用(R,G,B)这样一个三元素向量编码。 embedding还可以理解成将离散目标投影到连续空间中的某个点上。
-
首先获得输入,即用数值向量表示输入的对象,一串文本或图像。如下图,输入 X 是 800 个 200 维的向量,输出 Y 是 800 个 100 维的向量。
-
然后利用不同的权重矩阵通过线性层得到 Q、K、V。注意这里 attention 的 Q、K、V 的来源没有强制要求,如果是 Self-Attention 的话,需要 Q、K、V 同源,即三个权重矩阵与相同的输入 通过线性层得到 Q、K、V。
计算过程如下:
不同的词向量使用相同的 获得 Q, K, V。
-
然后通过点积运算分别得到不同词向量之间的相关性分数。
-
然后做一个 softmax 将分数转化为概率,然后对概率进行归一化得到重要程度的比例
-
然后利用上一步得到的比例,对各个向量 计算加权和 通过下图可以看出,如果某个输入向量对 更重要,那么其对应的 的值就会越大,其对应的 就得到了更多的关注 attention。
下面看个例子:
如果假设 是 2 维的,输入 是 3 维的,那么就需要训练一个 2*3 维的权重矩阵 。
分别计算每个输入向量:
然后将向量拼接到一起,就得到了矩阵 Q:
同理可以一次性计算出 Q, K, V 矩阵:
然后计算 q, k 点积得到的相关度分数
这一步同样可以拼成一个矩阵:
同样可以同时计算出每个 q,k 分量的点积
然后计算 V 与 的加权结果
简单来说,整个 Attention 的计算过程如下:
可以看到 attention 无视距离,无论隔多远,用我的 和你的 做内积,就知道我需要放多少注意力在你身上,然后用 乘上你的 V 就是我从你身上得到的一些信息。
如此就实现了”天涯若比邻,Attention is all you need“,但是 Attention 有问题,它不包含位置信息,对于 来说, 与它的距离是一样的。所以在处理序列任务的 Attention 模型中,需要引入位置编码。
3. 位置编码
对不同位置的输入序列加上不同的位置向量。
transformer 中用的位置向量如下:
需要知道输入向量的位置 pos 和维度
假设 pos = 2, ,即第二个输入向量的维度为 4。要算出一个维度为 4 的位置编码。
第奇数行用第二个公式计算,第偶数行用第一个公式计算,计算结果如下。
于是得到了输入向量的 的位置编码
为什么这样的操作就可以实现位置编码呢?就是因为编码的过程中同时涉及到了输入向量的位次信息 pos,和其维度信息。此后这个位置编码 会融合进输入向量 中,在之后的 Attention 过程中都会携带着这样的位置信息。
当然,位置编码的方式有很多,上面只是一种。
4. Self-Attention
Self-Attention 就是在 Attention 的基础上多了一条限制,要求 Q, K, V 同源,均来自输入的线性变换。
对比 RNN、LSTM 和 Self-Attention:
RNN 只能串行执行,并且越往后,前面的内容会被逐渐冲淡,所以无法做长序列,一段话达到 50 个字,效果就很差了。
LSTM(Long Short-Term Memory)在 RNN 的基础上改进,增加了各种门,比如遗忘门等,可以选择性遗忘一些之前不重要的信息,而巩固一些后面更可能用到的信息,提升了可处理的序列长度。不过也只有 200 字左右。
而 Self-Attention 相比前两者,具有可以并行处理长序列的优势,没有长序列的时序依赖问题。如下图可以看出句子序列中的每个词都要和其他所有词进行 Attention 处理,所以不存在时序关系。
同时,Self-Attention 能够获得句法特征和语法特征,从而得到表征更完善的词向量。
词法特征:
下图可以看出 Attention 的过程中,making 更倾向于与 more difficult 形成词组;
语法特征:
下图看出,its 和句中的 Law 和 application 的关联性更强,从语法上也是合理的,it 指代 Law,application 补充 its。
Truncated Self-Attention 提出,我们在理解一个东西的时候,可能并不需要理解全部输入,有时候只需要理解一些前后文就足够了。例如仅考虑 a2, a3, a4.
那么对于视觉领域 Self-attention 如何理解呢?
下图右侧可以看出图片可以看成多个向量(vector)组成的,所以同样可以利用 attention 来处理。
如下图,Self-attention 与 CNN 相比,CNN 可以看作简化版的 Self-attention。粗略理解就是,CNN 一次卷积处理,得到的结果只包含了一个 filter 内的信息,但是 Self-attention 可以获取整张图的信息。
5. Multi-Head Self-Attention
多头自注意力机制。
通过 Self-Attention,从输入 X 得到了具有一些额外信息的词向量 Y。Y 相比 X 有提升,通过 Multi-Head Self-Attention 要得到比 Y 提升更大的词向量。
下面是一个博主对词向量做一点解释:
机器学习的本质就是通过某个手段(训练模型),把一个看起来的不合理的东西变得合理。
非线性变换,其实就是改变空间上的位置坐标。任何一个点都可以在维度空间上找到,通过某些手段,让一个位置不合理的点(初始点),变换到合理的位置。
下图可以看出 Multi-Head Attention 就是由多个 Self-Attention 组成的。
下图是 Multi-Head Self-Attention 的执行过程:
- 输入一个序列
- 通过 one-hot 等编码方式得到一个词向量
- 随机生成 8 组权重矩阵(即 8 heads)
- 将输入的同一个 X 矩阵分别与不同的权重矩阵相乘,得到了 8 组,Q, K, V
- 产生了 8 个词向量 ,将其拼接到一起,再通过一次线性变换使得最后得到的 Z 和输入 X 的维度相同
整个这个过程,8 头可以视为产生了 8 个表示空间,在不同的空间上获得不同的词向量,最后将多样的信息叠加在一起。所以 Multi-Head Self-Attention 可以取得更好的表现。
代码参考【传送门】
1 | import torch |
输出结果为:
1 | 输入维度: torch.Size([4, 10, 256]) |
self-attention 的公式为
是词向量/隐藏层的维度
目的:防止输入 softmax 的值过大,导致偏导数趋近于 0。
6. 注意力池化
简单说就是用一个基于注意力的层来取代平均池化层。池化层和 attention 好像还挺像的,都是对输入信息的加权平均进行整合。加入注意力机制之后的池化层,可以明确的显示出不同 patch 所占的比重。表现很好。
暂时就这么多。
参考:
https://www.cnblogs.com/nickchen121/p/15105048.html
attention
https://nlp.seas.harvard.edu/2018/04/03/attention.html
https://zhuanlan.zhihu.com/p/149490072
multi-head attention
https://blog.csdn.net/weixin_44750512/article/details/124250497
注意力池化