【深度学习】注意力机制

https://blog.csdn.net/weixin_43334693/article/details/130189238

https://blog.csdn.net/weixin_47936614/article/details/130466448

https://blog.csdn.net/qq_51320133/article/details/138305880

注意力机制:在处理信息的时候,会将注意力放在需要关注的信息上,对于其他无关的外部信息进行过滤,这种处理方式被称为注意力机制。

注意力机制可以使模型在处理序列数据时更加准确和有效。在传统的神经网络中,每个神经元的输出只依赖于前一层的所有神经元的输出,而在注意力机制中,每个神经元的输出不仅仅取决于前一层的所有神经元的输出,还可以根据输入数据的不同部分进行加权,即对不同部分赋予不同的权重。这样可以使模型更加关注输入序列中的关键信息,从而提高模型的精度和效率。

注意力机制原理

1.计算注意力权重:注意力机制的第一步是计算每个输入位置的注意力权重。这个权重可以根据输入数据的不同部分进行加权,即对不同部分赋予不同的权重。权重的计算通常是基于输入数据和模型参数的函数,可以使用不同的方式进行计算,比如点积注意力、加性注意力、自注意力等。

2.加权求和输入表示:计算出注意力权重之后,下一步就是将每个输入位置的表示和对应的注意力权重相乘,并对所有加权结果进行求和。这样可以得到一个加权的输入表示,它可以更好地反映输入数据中重要的部分。

3.计算输出:注意力机制的最后一步是根据加权的输入表示和其他模型参数计算输出结果。这个输出结果可以作为下一层的输入,也可以作为最终的输出。

需要注意的是,注意力机制并不是一种特定的神经网络结构,而是一种通用的机制,可以应用于不同的神经网络结构中。比如,可以在卷积神经网络中使用注意力机制来关注输入图像中的重要区域,也可以在循环神经网络中使用注意力机制来关注输入序列中的重要部分。

查询(Query): 指的是查询的范围,自主提示,即主观意识的特征向量

键(Key): 指的是被比对的项,非自主提示,即物体的突出特征信息向量

值(Value) : 则是代表物体本身的特征向量,通常和Key成对出现
注意力机制是通过Query与Key的注意力汇聚(给定一个 Query,计算Query与 Key的相关性,然后根据Query与Key的相关性去找到最合适的 Value)实现对Value的注意力权重分配,生成最终的输出结果。

注意力机制计算过程:

阶段1、根据Query和Key计算两者之间的相关性或相似性(常见方法点积、余弦相似度,MLP网络),得到注意力得分

阶段2、对注意力得分进行缩放scale(除以维度的根号),再softmax函数,一方面可以进行归一化,将原始计算分值整理成所有元素权重之和为1的概率分布;另一方面也可以通过softmax的内在机制更加突出重要元素的权重。一般采用如下公式计算

阶段3、根据权重系数对Value值进行加权求和,得到Attention Value(此时的V是具有一些注意力信息的,更重要的信息更关注,不重要的信息被忽视了)

自注意力机制

神经网络接收的输入是很多大小不一的向量,并且不同向量向量之间有一定的关系,但是实际训练的时候无法充分发挥这些输入之间的关系而导致模型训练结果效果极差。比如机器翻译(序列到序列的问题,机器自己决定多少个标签),词性标注(Pos tagging一个向量对应一个标签),语义分析(多个向量对应一个标签)等文字处理问题。

自注意力机制实际上是想让机器注意到整个输入中不同部分之间的相关性

自注意力机制是注意力机制的变体,其减少了对外部信息的依赖,更擅长捕捉数据或特征的内部相关性。自注意力机制的关键点在于,Q、K、V是同一个东西,或者三者来源于同一个X,三者同源。通过X找到X里面的关键点,从而更关注X的关键信息,忽略X的不重要信息。不是输入语句和输出语句之间的注意力机制,而是输入语句内部元素之间或者输出语句内部元素之间发生的注意力机制。

自注意力机制原理

1、得到Q,K,V的值

对于每一个向量x,分别乘上三个系数 W^q^,W^k^,W^v^,得到的Q,K和V分别表示query,key和value (这三个W就是我们需要学习的参数)

2、计算注意力权重

利用得到的Q和K计算每两个输入向量之间的相关性,一般采用点积计算

3、Scale+Softmax

将刚得到的相似度除以 d k \sqrt{d~k~} d k (d~k~ 表示键向量的维度),再进行Softmax。经过Softmax的归一化后,每个值是一个大于0且小于1的权重系数,且总和为1,这个结果可以被理解成一个权重矩阵。

4、使用刚得到的权重矩阵,与V相乘,计算加权求和。

自注意力机制问题:

1、自注意力机制的原理是筛选重要信息,过滤不重要信息。这就导致自注意力机制无法完全利用图像本身具有的尺度,平移不变性,以及图像的特征局部性。这就导致自注意力机制只有在大数据的基础上才能有效地建立准确的全局关系

2、自注意力机制虽然考虑了所有的输入向量,但没有考虑到向量的位置信息。在实际的文字处理问题中,可能在不同位置词语具有不同的性质(可通过位置编码解决:对每一个输入向量加上一个位置向量e,位置向量的生成方式有多种,通过e来表示位置信息带入self-attention层进行计算)

多头注意力机制:Multi-Head Self-Attention

多头注意力机制在自注意力的基础上,通过增加多个注意力头来并行地对输入信息进行不同维度的注意力分配,从而捕获更丰富的特征和上下文信息。

第1步:定义多组W,生成多组Q、K、V

线性变换:首先,对输入序列中的每个位置的向量分别进行三次线性变换(即加权和偏置),生成查询矩阵Q, 键矩阵K, 和值矩阵V。在多头注意力中,这一步骤实际上会进行h次(其中h为头数),每个头拥有独立的权重矩阵,从而将输入向量分割到h个不同的子空间。

第2步:

并行注意力计算:对每个子空间,应用自注意力机制计算注意力权重,并据此加权求和值矩阵V,得到每个头的输出。公式上表现为:

第3步:

合并与最终变换:将所有头的输出拼接起来,再经过一个最终的线性变换和层归一化,得到多头注意力的输出。这一步骤整合了不同子空间学到的信息,增强模型的表达能力。

python 复制代码
import torch
from torch.nn import Module, Linear, Dropout, LayerNorm
 
class MultiHeadAttention(Module):
    def __init__(self, d_model, num_heads, dropout=0.1):
        super(MultiHeadAttention, self).__init__()
        assert d_model % num_heads == 0, "d_model must be divisible by num_heads"
        self.d_head = d_model // num_heads
        self.num_heads = num_heads
        
        self.linear_q = Linear(d_model, d_model)
        self.linear_k = Linear(d_model, d_model)
        self.linear_v = Linear(d_model, d_model)
        self.linear_out = Linear(d_model, d_model)
        
        self.dropout = Dropout(dropout)
        self.layer_norm = LayerNorm(d_model)
    
    def forward(self, q, k, v, mask=None):
        batch_size = q.size(0)
        
        # 线性变换
        q = self.linear_q(q).view(batch_size, -1, self.num_heads, self.d_head)
        k = self.linear_k(k).view(batch_size, -1, self.num_heads, self.d_head)
        v = self.linear_v(v).view(batch_size, -1, self.num_heads, self.d_head)
        
        # 转置以便于计算注意力
        q, k, v = q.transpose(1, 2), k.transpose(1, 2), v.transpose(1, 2)
        
        # 计算注意力权重
        scores = torch.matmul(q, k.transpose(-2, -1)) / math.sqrt(self.d_head)
        if mask is not None:
            scores = scores.masked_fill(mask == 0, -1e9)
        attn_weights = torch.softmax(scores, dim=-1)
        attn_weights = self.dropout(attn_weights)
        
        # 加权求和得到输出
        outputs = torch.matmul(attn_weights, v)
        
        # 转换回原始形状并进行最终线性变换
        outputs = outputs.transpose(1, 2).contiguous().view(batch_size, -1, self.d_model)
        outputs = self.linear_out(outputs)
        outputs = self.layer_norm(outputs + q)
        
        return outputs
相关推荐
xiandong202 分钟前
240701_昇思学习打卡-Day13-Vision Transformer图像分类
网络·图像处理·人工智能·深度学习·学习·分类·transformer
AcademicIdeas学境思源19 分钟前
AI与学术的交响:ChatGPT辅助下的实验设计新篇章
人工智能
21 分钟前
拍摄泡咖啡的剧本!
深度学习·学习·游戏·智能手机·生活
简过网27 分钟前
简过网:考教师编制报培训班有用吗?
人工智能·机器学习
Geektec31 分钟前
AI在软件开发:助力开发者还是取而代之?
人工智能·驱动开发·计算机·chatgpt·变革
欣慰的三叶草(● ̄(エ) ̄●)1 小时前
01--SpringAI接入大模型,chatgpt,Java接入人工智能大模型
java·人工智能·chatgpt
小兮风1 小时前
Forecasting from LiDAR via Future Object Detection
人工智能·目标检测·计算机视觉·端到端检测预测
一尘之中1 小时前
IT专业入门,高考假期预习指南
人工智能·高考
不掉马甲的NPC1 小时前
「豆包MarsCode初体验」使用 node.js 搭建图片服务器
人工智能
LewisFung1 小时前
性能超越 YOLO、GPT-4 的图像自动标注工具:T-Rex Label
人工智能·深度学习·计算机视觉