注意力机制
什么是注意力机制
自我理解
当人类在观察一个物体时,有时候并不是观察这个物体的全部,而是这个物体区别于其他物体的特征,这种观察到局部特征的行为叫做注意力。
官方解释
注意力机制(attention mechanism)是解决信息超载问题的主要手段的一种资源分配方案,将计算资源分配给更重要的任务。
为什么要有注意力机制
前面我们学习了循环神经网络(RNN),它最大的缺点是记忆能力随着文本序列的变长而记忆力下降,虽然RNN有变种体GRU和LSTM,但是他们关注对于降低复杂度的方法都是根据上一步的状态值来选择性遗忘,这和注意力是两种完全不同的观点。
就好比你在准备考研期间要背诵一道大题,但是这道题的答案非常长,那么你有两种方法来进行背诵:
- 选择性遗忘一部分信息,从而来减少记忆负担
- 记住关键词来减少记忆负担
单从字面方法来说,是不是第二种比较靠谱一点呀?
所以注意力机制还是一个值得好好学习的知识!
当用神经网络来处理大量的输入信息时,也可以借鉴人脑的注意力机制,只选择一些关键的信息输入进行处理,来提高神经网络的效率。
注意力分类
聚焦式(focus)注意力
:自上而下的有意识的注意力- 聚焦式注意力是指有预定目的、依赖任务的、主动有意识地聚焦于某一对象的注意力
基于显著性(saliency-based)的注意力
:自下而上的无意识的注意力- 基于显著性的注意力是由外界刺激驱动的注意,不需要主动干预,也和任务无关
注意力机制的计算
虽然有很多资料都介绍了这一部分,但是理解起来的难度千差万别,对于初学者来说,自认为还是《机器阅读理解》这本书中讲解的很通俗易懂
注意力机制的输入包含两个部分
- 被注意的对象,用向量x={x1,x2···xn}来表示N 个输入信息
- 一个进行注意的对象,为一个向量q
过程
向量q对被注意的对象x进行关注,因为不可能把所有注意力都注意在一个xi上,所以需要对x中的各个向量进行打分来给予其相应的关注,打分
越高的向量xi理所应当地得到更多的关注。然后,根据打分用softmax归一化
并对向量x={x1,x2···xn}计算加权和,得到最终的注意力向量c。
举个例子来说就好比一个有很多宠物的人,因为他一个人的精力有限,所以他对每一个宠物的关注度不同,有些宠物很可爱所以它的关注度为a,有些宠物既可爱又聪明所以它的关注度加倍2*a···,由此来说明不同的向量的关注度不同
那么怎么打分呢?
注意力打分函数
$$ s(x_i,q)为注意力机制打分函数,其中W, U,v为可学习的网络参数 $$ softmax归一化以点积模型来说
x={x1,x2···xn}一共n个输入
i
=
s
i
=
s
(
x
i
,
q
)
i=s_i = s(x_i,q)
i=si=s(xi,q)
j = s j = s ( x j , q ) j=s_j = s(x_j,q) j=sj=s(xj,q)
β m = e i ∑ 1 n e j \beta_m = \frac{e^i}{\sum_1^ne^j} βm=∑1nejei
注 意 m 为 S i 的 下 标 i , ( 1 < = m < = n ) 注意m为S_i的下标i,(1<=m<=n) 注意m为Si的下标i,(1<=m<=n)
结果
c
=
β
1
x
1
+
β
2
x
2
+
.
.
.
+
β
m
x
n
c = \beta_1x_1+\beta_2x_2+...+\beta_mx_n
c=β1x1+β2x2+...+βmxn
A t t e n t i o n ( { x 1 , x 2... x n } ; q ) = c Attention(\{x1,x2...xn\};q)=c Attention({x1,x2...xn};q)=c
当存在多个进行注意的对象q时的注意力机制
A
t
t
e
n
t
i
o
n
(
{
x
1
,
x
2...
x
n
}
;
{
q
1
,
q
2...
q
n
}
)
=
{
c
1
,
c
2...
c
n
}
Attention(\{x1,x2...xn\};\{q1,q2...qn\})=\{c1,c2...cn\}
Attention({x1,x2...xn};{q1,q2...qn})={c1,c2...cn}
代码操作
'''
Description: 注意力机制
Autor: 365JHWZGo
Date: 2021-12-11 20:40:52
LastEditors: 365JHWZGo
LastEditTime: 2021-12-11 20:51:21
'''
import torch
import torch.nn.functional as F
# 被注意向量x [batch*m*dim]
# 进行注意力的向量q [batch*n*dim]
class attentionDistribute(object):
def attention(self,x,q):
scores = q.bmm(x.transpose(1,2))
beta = F.softmax(scores,dim=-1)
attended = beta.bmm(x)
return attended
if __name__ == '__main__':
x = torch.randn(3,4,5)
q = torch.randn(3,2,5)
attended = attentionDistribute().attention(x,q)
print(attended)
Run:
tensor([[[ 0.9438, 1.8321, 0.9153, -0.0252, 0.9194],
[ 1.3176, 0.2811, 0.5573, 0.2658, 0.9961]],
[[ 0.1135, -1.2943, -0.0739, 0.3639, -1.2125],
[-0.3872, -0.7483, -0.9124, 0.7017, -0.2436]],
[[-0.0599, -0.3369, -0.8418, -0.7753, -0.9477],
[ 0.2832, -0.1715, -0.4047, -0.3461, 0.7615]]])