认知神经学中的注意力
(1)自上而下的有意识的注意力,称为聚焦式注意力(Focus Attention)
(2)自下而上的无意识的注意力,称为基于显著性的注意力(Saliency-Based Attention)
Core idea
组输入信息
,对于某个任务为了体现注意力,需要计算每个输入向量的权重,决定孰轻孰重
引入和任务相关的查询向量
,需要根据任务来计算每个输入向量和查询向量之间的相关性。以
表示选择了第
个位置的输入向量
称为注意力分布,
称为注意力打分函数,这样就计算出了每个输入向量在特定任务下的注意力分布,也就是每个输入的重要程度
注意力函数有多种形式加性模型
点积模型
缩放点积模型
双线性模型
其中
为可学习的参数,
为输入向量的维度
软性注意力机制,对输入信息进行加权平均
键值对注意力机制,用键值对表示输入信息,key计算注意力分布,value计算聚合信息
表示
组输入信息,给定任务查询向量
时,注意力函数为
当
时,键值对模式退化为一般注意力机制
多头注意力机制(Multi-Head Attention),利用多个查询
来并行地从输入信息中选取多组信息,每个注意力关注输入信息的不同部分。
表示向量拼接
这里放一个实现的利用注意力机制检索查询图片的代码,其实在这里注意力机制就是一个分配相似度权重的功能,可能有点简单,但是可以帮助理解。
def prepare_data(dirpath):
"""The function is used to randomly generate a query vector and an input data from a given directory:params dirpath: the directory of data:return query_data: the query vector,input_data: the data input"""
np.random.seed(1023)
imgs_lst = os.listdir(dirpath)
query_id = np.random.randint(len(imgs_lst))
query_data = cv2.imread(os.path.join(dirpath, imgs_lst[query_id]), 0)
imgs_lst.remove(imgs_lst[query_id])
h, w = query_data.shape
query_data = torch.Tensor(query_data)
input_data = torch.zeros(h, w, len(imgs_lst))
for i in range(len(imgs_lst)):
cur_data = cv2.imread(os.path.join(dirpath, imgs_lst[i]), 0)
cur_data = torch.Tensor(cur_data)
input_data[:, :, i] = cur_data
return query_data, input_data
def score_attention(method, q, x_n):
"""The function is used to choose a method for scoring the attention:params method: the scoring method we want:return score_value: the attention scoring value, a scalar"""
np.random.seed(1023)
size = q.size()
D = size[0]
if method=="add":
v = torch.rand(D, 1)
W = torch.rand(D, D)
U = torch.rand(D, D)
score_value = v.t() @ torch.tanh(W @ x_n + U @ q)
if method=="prod":
score_value = x_n.t() @ q
if method=="zoom_prod":
score_value = x_n.t() @ q / torch.sqrt(torch.Tensor([D]))
if method=="double_linear":
W = torch.rand(D, D)
score_value = x_n.t() @ W @ q
return score_value
def compute_attention(query_data, input_data, method):
"""The function is used to compute the attention between the query vector and the input data:params query_data: the query vector,input_data: the input data:return att: the attention between the query vector and the input data"""
input_size = input_data.size()
query_size = query_data.size()
N = input_size[-1]
input_data = input_data.view(-1, N)
query_data = query_data.view(-1, 1)
s = torch.zeros(N)
att = torch.zeros(N)
for i in range(N):
s[i] = score_attention(method, query_data, input_data[:, [i]])
s /= torch.sum(s)
att = torch.exp(s) / torch.sum(torch.exp(s))
return att
Self-Attention
自注意力机制提出的目的是为了解决动态生成不同连接的权重问题图1. self-attention(QKV)
输入序列为
,输出序列为
(1)对于输入,先将其线性映射到三个不同的空间,得到Q, K, V
(2)对于每一个查询向量
,计算输出向量
表示第n个输出关注到第j个输入的权重
多头自注意力模型(multi-head self-attention)
为了提取更多交互信息,可以使用多头自注意力模型,在多个不同的投影空间中捕捉不同的交互信息。假设在M个投影空间中分别应用自注意力模型,有
注:文章主要参考复旦大学邱锡鹏教授《神经网络与深度学习》内容