当前位置:   article > 正文

Attension注意力机制综述(一)——自注意力机制self_attention(含代码)_attension机制

attension机制

注意力机制综述

总结注意力机制最经典的三种模型,包括:注意力机制(包括多头注意力机制)、通道注意力机制、空间注意力机制,图源李沐、李宏毅相关课程or课件

1.注意力机制的产生

深度学习中的注意力机制(Attention Mechanism)是一种模仿人类视觉和认知系统的方法,它允许神经网络在处理输入数据时集中注意力于相关的部分。通过引入注意力机制,神经网络能够自动地学习并选择性地关注输入中的重要信息,提高模型的性能和泛化能力。

以下通过非自主性提示自主性提示来理解人类注意力的方式。

非自主性提示是基于环境中物体的突出性和易见性。假如你面前有五个物品: 一份报纸、一篇研究论文、一杯咖啡、一本笔记本和一本书,如下图所示。 所有纸制品都是黑白印刷的,但咖啡杯是红色的。 咖啡杯最突出显眼, 不由自主地引起人们的注意。 所以你把视力最敏锐的地方放到咖啡上。

在这里插入图片描述

自主性提示:喝咖啡后,你觉得精力旺盛,想要看一本书。此时你的目光主动搜索并且聚集到了书上,如下图。与非自主性提示不同,此时选择书是受到了认知和意识的控制, 因此注意力在基于自主性提示去辅助选择时将更为谨慎。 受试者的主观意愿推动,选择的力量也就更强大。

在这里插入图片描述

注意力机制从本质上讲和人类的选择性注意力机制类似,核心目标也是从众多信息中选出对当前任务目标更加关键的信息。深度学习中,注意力机制通常应用于序列数据(如文本、语音或图像序列)的处理。其中,最典型的注意力机制包括自注意力机制、空间注意力机制和时间注意力机制****。这些注意力机制允许模型对输入序列的不同位置分配不同的权重,以便在处理每个序列元素时专注于最相关的部分。

2.自注意力机制(Self-Attention Mechanism)

基本思想:处理序列数据时,每个元素都可以与序列中其他元素建立关联,而不仅仅依赖相邻位置元素,通过计算元素间的相对重要性来自适应地捕捉元素间地长程依赖关系。

具体而言,对于序列中的每个元素,自注意力机制计算其与其他元素之间的相似度,并将这些相似度归一化为注意力权重。然后,通过将每个元素与对应的注意力权重进行加权求和,可以得到自注意力机制的输出。

2.1q查询、k键、v值介绍

在注意力机制的背景下,将自主性提示称为查询(query)。 给定任何查询,注意力机制通过注意力池化(attention pooling) 将选择引导至感官输入(sensory inputs,例如中间特征表示)。 在注意力机制中,这些感官输入被称为值(value) ,更通俗的解释每个值都与一个键(key)配对, 即感官输入的每个非自主提示都与一个值(value)匹配,注意力机制通过查询选择出我们需要的key-value

如下图所示可以设计注意力池化, 以便给定的查询(自主性提示)可以与键(非自主性提示)进行匹配, 这将引导得出最匹配的值(感官输入)。

在这里插入图片描述

对于给定的成对的“输入-输出”数据集{(x1,y1),…,(xn,yn)},通过学习得到函数f()来预测任意新输入x的输出y,即y=f(x)。如下图,分子K(x-xi)即为计算输入与其他元素的相似度,将其除以所有相似度之和进行归一化得到注意力权重,分式(权重)乘以输出yi得到对每个元素进行加权,求和得到注意力机制的输出。

在这里插入图片描述

2.2Embedding操作

假设,我们有一个序列(或者说是一句话):“你好机车”,分别使用 x1,x2,x3 ,x4表示,如上图所示。

简单地说, x1表示“你”, x2表示“好”, x3表示“机”, x4表示”车“

首先,先对"你好机车"这段话进行Embedding操作(可以使用 Word2Vec等方法),得到新的向量,a1,a2,a3 ,a4 ;如下图所示。

在这里插入图片描述

其中, W表示 Embedding 的参数矩阵

2.3q,k操作

Embedding操作后,a1,a2,a3 ,a4 将会作为注意力机制的 input data。

第一步,每个a1,a2,a3 ,a4 都会分别乘以三个矩阵,分别是q,k,v ;需要注意的是,矩阵 q,k,v 在整个过程中是共享的,公式如下:

在这里插入图片描述

其中, q (Query) 的含义一般的解释是用来和其他单词进行匹配,即我们的查询目标,更准确地说是用来计算当前单词或字与其他的单词或字之间的关联或者关系; k (Key) 的含义则是被用来和 q进行匹配,也可理解为单词或者字的关键信息。

如下图所示,若需要计算a1 和 a2,a3 ,a4 之间的关系(或关联),则需要用 q1 和 k2,k3 ,k4 进行匹配计算,计算公式如下:

​ *α1,i=q1ki/ d1/2

其中, d 表示 q 和 k 的矩阵维度,在 Self-Attention 中, q和 k 的维度是一样的。除以d1/2是防止q和k的点乘结果较大,softmax会被推到非常小的区域中

在这里插入图片描述

2.4 v操作

v的含义主要是表示当前单词或字的重要信息表示,也可以理解为单词的重要特征,例如: v1 代表"你"这个字的重要信息。在 v操作中,会将 q,k 操作后得到的在这里插入图片描述和 v1,v2,v3 ,v4 分别相乘,如下图所示,计算公式如下:

在这里插入图片描述

以此类推求得b2,b3,b4 ,可以看作是提取出来的features,这些features可以用作下游任务的训练和推理,每个b都包含全局信息

由此可见,自注意力机制通过计算序列中不同位置之间的相关性( q,k 操作),为每个位置分配一个权重,然后对序列进行加权求和( v 操作)

实现self-attention的两种方式

在这里插入图片描述

总结:

在这里插入图片描述

从矩阵乘法的方式看:

  • 从a得到q、k、v、

在这里插入图片描述

  • 得到注意力分数

在这里插入图片描述

  • 得到注意力输出

在这里插入图片描述

  • 总流程

在这里插入图片描述

2.5代码

在这里插入图片描述

在这里插入图片描述

dot_product方式

在这里插入图片描述

import torch
from torch import  nn
#定义自注意力模块,这个类阐释了注意力机制的原理
class Self_Attention(nn.Module):
    def __init__(self,input_dim,dk,dv):
        #dk表示k的长度
        super().__init__()
        self.scale=dk**-0.5#根号dk
        #从输入提取q、k、v
        self.query=nn.Linear(input_dim,dk)
        self.key=nn.Linear(input_dim,dk)
        self.value=nn.Linear(input_dim,dv)

    def forward(self,x):
        #提取出q、k、v
        q=self.query(x)
        k=self.key(x)
        v=self.value(x)
        #比如 q.shape=(1,4,2)(batch,4个token,token长为2)
        attention_weights=torch.matmul(q,k.transpose(-2,-1))*self.scale#求注意力分数
        #or  attention_weights=torch.matmul(q,k.transpose(1,2))*self.scale#根据q的维度,本质是一样的
        attention_weights=nn.functional.softmax(attention_weights,dim=-1)#对注意力分数归一化,最后一个维度做
        attended_values=torch.matmul(attention_weights,v)#将归一化后的权重与value相乘
        return attended_values

#定义自注意力分类器模型
class SelfAttentionClassifier(nn.Module):
    def __init__(self,input_dim,dk,dv,hidden_dim,num_classes):
        super().__init__()
        self.attention=Self_Attention(input_dim,dk,dv)#
        self.fc1=nn.Linear(dv,hidden_dim)
        self.relu=nn.ReLU()
        self.fc2=nn.Linear(hidden_dim,num_classes)

    def forward(self,x):
        attended_values=self.attention(x)
        x=attended_values.mean(dim=1)
        x=self.fc1(x)
        x=self.relu(x)
        x=self.fc2(x)
        return x

if __name__=='__main__':
    # att=Self_Attention(dim=2,dk=2,dv=3)
    model=SelfAttentionClassifier(input_dim=2,dk=2,dv=3,hidden_dim=32,num_classes=2)
    x=torch.randn((1,4,2))#batch,4个token,每个token长度=input_dim
    output=model(x)
    print(output)


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50

输出tensor([[0.2541, 0.0059]], grad_fn=<AddmmBackward0>)

参考

self-Attention|自注意力机制|位置编码|理论+代码

转载修改自:注意力机制综述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/696044
推荐阅读
相关标签
  

闽ICP备14008679号