【PyTorch][chapter 26][李宏毅深度学习][attention-2]

2024-07-19 1565阅读

前言:

   Multi-Head Attention 主要作用:将Q,K,V向量分成多个头,形成多个子语义空间,可以让模型去关注不同维度语义空间的信息


目录:

  1. attention 机制
  2.  Multi-Head Attention 

一 attention 注意力

       Self-Attention(自注意力机制):使输入序列中的每个元素能够关注并加权整个序列中的其他元素,生成新的输出表示,不依赖外部信息或历史状态。

       将查询Query,键Key,值Value 映射 到输出。

       查询Query,键Key, 值Value  都是向量.

       其输出为 值的加权求和。

   【PyTorch][chapter 26][李宏毅深度学习][attention-2]

   1.1 mask 作用

【PyTorch][chapter 26][李宏毅深度学习][attention-2]

1.2 scale 作用

【PyTorch][chapter 26][李宏毅深度学习][attention-2]

# -*- coding: utf-8 -*-
"""
Created on Tue Jul 16 11:21:33 2024
@author: chengxf2
"""
import torch
import math
def attention(query,key ,value, mask=None):
    #[batchSize, seq_num, query_dim]
    d_k = query.size(-1)
    print(d_k)
    attentionMatrix = torch.matmul(query, key.transpose(-2,-1))
    
    scores = attentionMatrix/math.sqrt(d_k)
    
    if mask is not None:
        scores = scores.mask_fill(mask==0, -1e9)
    p_attn = torch.softmax(scores, dim=-1)
    out = torch.matmul(p_attn, value)
    return out
    
seq_len = 5
hid_dim = 10
out_len =3
query = torch.rand((seq_len,hid_dim))
key =  torch.rand_like(query)
value = torch.rand((seq_len, out_len))
attention(query, key, value)

二 Multi-Head Attention 

          多头注意力机制的理论基础之一是信息多元化处理的思想。通过将输入向量投影到不同的子空间,每个子空间执行自注意力操作,这样模型能够并行地学习不同类型的特征或依赖关系,增强了模型的表达能力。

【PyTorch][chapter 26][李宏毅深度学习][attention-2]

【PyTorch][chapter 26][李宏毅深度学习][attention-2]

2,1  第一步:查询Q、键K 和值V 矩阵的 生成

         输入:

                 张量A 

                 shape: [batch, seq_len, input_dim]

         输出:

                Q,K,V

                shape:[batch,seq_len, query_dim]

            

        (下面以输入seq_len=2 ,为例)

     

       【PyTorch][chapter 26][李宏毅深度学习][attention-2]

            

        【PyTorch][chapter 26][李宏毅深度学习][attention-2] 

        【PyTorch][chapter 26][李宏毅深度学习][attention-2]

        【PyTorch][chapter 26][李宏毅深度学习][attention-2]

       其中下面三个矩阵是需要学习的矩阵:

      【PyTorch][chapter 26][李宏毅深度学习][attention-2]的shape 为【input_dim, query_dim]

2.2  第二步:子空间投影

      Q,K V 乘以对应的Head 矩阵,得到对应的mulite-head  Q,K,V

【PyTorch][chapter 26][李宏毅深度学习][attention-2]

  

以 Query张量为例: 实现的时候先乘以Head 矩阵 【PyTorch][chapter 26][李宏毅深度学习][attention-2],然后再通过View 功能

分割成子空间。

【PyTorch][chapter 26][李宏毅深度学习][attention-2]

第三步: 对不同Head 的Q,K,V

    做self-attention,得到不同Head 的 【PyTorch][chapter 26][李宏毅深度学习][attention-2]

第四步: concate 

【PyTorch][chapter 26][李宏毅深度学习][attention-2]

import torch

from torch import nn

 

# 假设我们有一些查询、键和值的张量

query = torch.rand(10, 8, 64)  # (batch_size, n_query, d_model)

key = value = query  # 为了示例,我们使用相同的张量作为键和值

 

# 实例化多头注意力层

multihead_attn = nn.MultiheadAttention(embed_dim=64, num_heads=4)

 

# 执行多头注意力操作

output, attention_weights = multihead_attn(query, key, value)

 

print(output.shape)  # 输出: torch.Size([10, 8, 64])

print(attention_weights.shape)  # 输出: torch.Size([10, 4, 8, 8])

# -*- coding: utf-8 -*-
"""
Created on Wed Jul 17 09:46:40 2024
@author: chengxf2
"""
import torch
import torch.nn as nn
import copy
import math
from torchsummary import summary 
import netron
def clones(module, N):
    
    "生成N 个 相同的层"
    
    layers = nn.ModuleList(
        
        [copy.deepcopy(module)  for _ in range(N)]
        )
        
    return layers
def attention(query, key ,value):
    
     #输出[batch, head_num, seq_len,query_dim ]
  
     seq_num = query.size(-1)
     
     scores = torch.matmul(query, key.transpose(-2,-1))
     
     scores = scores/math.sqrt(seq_num)
     
     p_attn = torch.softmax(scores, dim=-1)
     
     out = torch.matmul(p_attn, value)
     print("\n out.shape",out.shape)
     return out, p_attn
class  MultiHeadedAttention(nn.Module):
    
    def __init__(self, head_num, query_dim):
        
        super(MultiHeadedAttention, self).__init__()
        self.head_num = head_num
        self.sub_query_dim = query_dim//head_num
       
        self.linears = clones(nn.Linear(query_dim,query_dim), 4)
        self.attn = None
    
    
    def forward(self, query, key, value):
        #query.shape [batch, seq_num,query_dim]
        
        batchSz = query.size(0)
        #[batchsz, seq_num, head_num, query_dim]
        query, key, value = \
            [net(x).view(batchSz, -1, self.head_num, self.sub_query_dim).transpose(1, 2)
             for net, x in zip(self.linears, (query, key, value))]
       
        #输出[batch, head_num, seq_len,sub_query_dim ]
       
        x, self.attn = attention(query, key, value)
        print("\n attn ",self.attn)
        
        x = x.transpose(1,2).contiguous().view(batchSz,-1,self.head_num*self.sub_query_dim)
        
        out = self.linears[-1](x)
        
        print(out.shape)
        return out
        
if __name__ == "__main__":
    batchSz=1
    seq_num =2
    out_dim=query_dim =9
    head_num =3
    #下面这三个矩阵是需要学习的矩阵
    query = torch.randn((batchSz, seq_num, query_dim))
    key =  torch.rand_like(query)
    value =torch.randn((batchSz, seq_num, out_dim))
    
    
    model = MultiHeadedAttention(head_num,query_dim)
    model(query,key,value)
    
    print("\n 模型参数 \n ")
   
    input_size = (seq_num, query_dim)
    summary(model,[input_size,input_size,input_size])
    # 创建一个输入样本
    input_dict = {"x1": query, "x2": key, "x3":value}
    # 导出模型为ONNX格式
    torch.onnx.export(model,               # 模型实例
                  (query,key,value),                   # 模型输入
                  "model.onnx")
 
    netron.start('model.onnx') 
         
     
     
     
     
        


https://zhuanlan.zhihu.com/p/626820422

The Annotated Transformer

VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]