多头注意力

在实践中,当给定相同的查询、键和值的集合时,我们希望模型可以基于相应的注意力机制学习到不同的行为,然后将不同的行为作为知识组合起来,捕获序列内各种范围的依赖关系(例如,段距离依赖和长距离依赖关系)。因此,运行注意力机制组合使用查询、键和值的不同子空间表示(representation subspaces)可能时有益的

为此,与其只使用单独一个注意力汇聚。我们可以用独立学习得到的h组不同的线性投影(linear projections)来变换查询、键和值。然后,这h组变换后的查询、键和值将并行地送到注意力汇聚中。最后,将这h个注意力汇聚的输出拼接在一起,并且通过另一个可以学习线性投影进行变换,以产生最终输出。这种设计被称为多头注意力(multihead attention)。对于h个注意力汇聚输出,每一个注意力汇聚都被称作一个头(head)。展示了使用全连接层来实现可学习的线性变换的多头注意力

1 - 模型

import math
import torch
from torch import nn
from d2l import torch as d2l

2 - 实现

class MultiHeadAttention(nn.Module):"""多头注意力"""def __init__(self,key_size,query_size,value_size,num_hiddens,num_heads,dropout,bias=False,**kwargs):super(MultiHeadAttention,self).__init__(**kwargs)self.num_heads = num_headsself.attention = d2l.DotProductAttention(dropout)self.W_q = nn.Linear(query_size,num_hiddens,bias=bias)self.W_k = nn.Linear(key_size,num_hiddens,bias=bias)self.W_v = nn.Linear(value_size,num_hiddens,bias=bias)self.W_o = nn.Linear(num_hiddens,num_hiddens,bias=bias)def forward(self,queries,keys,values,valid_lens):# queries,keys,values的形状# (batch_size,查询或者“键-值”对的个数,num_hiddens)# valid_lens 的形状# (batch_size,)或(batch_size,查询的个数)# 经过变换后,输出的queries,keys,values的形状:(batch_size*num_heads,查询或者“键-值”对的个数,num_hiddens/num_heads)queries = transpose_qkv(self.W_q(queries),self.num_heads)keys = transpose_qkv(self.W_k(keys),self.num_heads)values = transpose_qkv(self.W_v(values),self.num_heads)if valid_lens is not None:# 在轴0,将第一项(标量或者矢量)复制num_heads次# 然后如此复制第二项,然后著如此类valid_lens = torch.repeat_interleave(valid_lens,repeats=self.num_heads,dim=0)# output的形状:(batch_size*num_heads,查询的个数,num_hiddens/num_heads)output = self.attention(queries,keys,values,valid_lens)# output_concat的形状:(batch_size,查询的个数,num_hiddens)output_concat = transpose_output(output,self.num_heads)return self.W_o(output_concat)

为了能够使多个头并行计算,上面的MultiHeadAttention类将使用下面定义的两个转置函数。具体来说,transpose_output函数反转了transpose_qkv函数的操作

def transpose_qkv(X,num_heads):"""为了多注意力头的并行计算而变换形状"""# 输入X的形状:(batch_size,查询或者“键-值”对的个数,num_hiddens)# 输出X的形状:(batch_size,查询或者“键-值”对的个数,num_heads,num_hiddens/num_heads)X = X.reshape(X.shape[0],X.shape[1],num_heads,-1)# 输出X的形状:(batch_size,num_heads,查询或者“键-值”对的个数,num_hiddens/num_heads)X = X.permute(0,2,1,3)# 最终输出的形状为:(batch_size*num_heads,查询或者“键-值”对的个数,num_hiddens/num_heads)return X.reshape(-1,X.shape[2],X.shape[3])def transpose_output(X,num_heads):"""逆转transpose_qkv函数的操作"""X = X.reshape(-1,num_heads,X.shape[1],X.shape[2])X = X.permute(0,2,1,3)return X.reshape(X.shape[0],X.shape[1],-1)

下面我们使用键和值相同的小例子来测试我们编写的MultiHeadAttention类。多头注意力输出的形状是(batch_size,num_queries,num_hiddens)

num_hiddens,num_heads = 100,5
attention = MultiHeadAttention(num_hiddens,num_hiddens,num_hiddens,num_hiddens,num_heads,0.5)
attention.eval()
MultiHeadAttention((attention): DotProductAttention((dropout): Dropout(p=0.5, inplace=False))(W_q): Linear(in_features=100, out_features=100, bias=False)(W_k): Linear(in_features=100, out_features=100, bias=False)(W_v): Linear(in_features=100, out_features=100, bias=False)(W_o): Linear(in_features=100, out_features=100, bias=False)
)
batch_size,num_queries = 2,4
num_kvpairs,valid_lens = 6,torch.tensor([3,2])
X = torch.ones([batch_size,num_queries,num_hiddens])
Y = torch.ones([batch_size,num_kvpairs,num_hiddens])
attention(X,Y,Y,valid_lens).shape
torch.Size([2, 4, 100])

3 - 小结

  • 多头注意力融合了来自于多个注意力汇聚的不同知识,这些知识的不同来源于相同的查询、键和值的不同的子空间表示
  • 基于适当的张量操作,可以实现多头注意力的并行计算

注意力机制 - 多头注意力相关推荐

  1. 注意力机制-多头注意力

    文章目录 多头注意力 多头注意力 给定一个Query(查询)和一系列的Key-Value对一起映射出一个输出.包括下面三个关键性步骤: 将Query与Key进行相似性度量 将求得的相似性度量进行缩放标 ...

  2. 自注意力机制与注意力机制

    基本内容理解的话推荐看一下这篇博客Transformer:注意力机制(attention)和自注意力机制(self-attention)的学习总结,这个博主讲的很细致,比较容易理解. 这里借用一下上述 ...

  3. 空间注意力机制sam_Attention注意力机制介绍

    什么是Attention机制 Attention机制通俗的讲就是把注意力集中放在重要的点上,而忽略其他不重要的因素.其中重要程度的判断取决于应用场景,拿个现实生活中的例子,比如1000个人眼中有100 ...

  4. 注意力机制 - Bahdanau注意力

    文章目录 Bahdanau注意力 1 - 模型 2 - 定义注意力解码器 3 - 训练 4 - 小结 Bahdanau注意力 我们在 9.7节中探讨了机器翻译问题:通过设计⼀个基于两个循环神经⽹络的编 ...

  5. 什么是注意力机制?注意力机制的实现步骤

    我们观察事物时,之所以能够快速判断一种事物(当然允许判断是错误的),是因为我们大脑能够很快把注意力放在事物最具有辨识度的部分从而作出判断,而并非是从头到尾的观察一遍事物后,才能有判断结果,正是基于这样 ...

  6. 注意力机制之注意力分数

    目录 注意力分数 扩展到高维 加性注意力 scaled 点积注意力 总结 代码 注意力分数 注意力分数和注意力权重的区别: 扩展到高维 这里,q的数量和key-value对的数量可以不一致.q,k,v ...

  7. transformer学习之多头注意力机制

    文章目录 题目 注意力机制 多头注意力机制 为什么要使用多头注意力机制 代码实现 题目 transformer学习之多头注意力机制 注意力机制 详细了解 ➡️ 注意力机制 之前我们也学习过了Seq2S ...

  8. 注意力机制(四):多头注意力

    专栏:神经网络复现目录 注意力机制 注意力机制(Attention Mechanism)是一种人工智能技术,它可以让神经网络在处理序列数据时,专注于关键信息的部分,同时忽略不重要的部分.在自然语言处理 ...

  9. Pytorch:Transformer(Encoder编码器-Decoder解码器、多头注意力机制、多头自注意力机制、掩码张量、前馈全连接层、规范化层、子层连接结构、pyitcast) part1

    日萌社 人工智能AI:Keras PyTorch MXNet TensorFlow PaddlePaddle 深度学习实战(不定时更新) Encoder编码器-Decoder解码器框架 + Atten ...

最新文章

  1. CUDA C++编程手册(总论)
  2. 使用Metasploit工作区
  3. sizeof 和strlen的区别
  4. boost::geometry::detail::copy_segments的用法测试程序
  5. python笔记之if练习
  6. AFNetWorking 使用记录
  7. 植物冠层部分参数的定义及含义解释
  8. 如何判断工作簿中是否存在某个工作表
  9. P1069 微博转发抽奖
  10. emule中节点加入Kad网络过程(源代码详解)
  11. python画频率直方图_用matplotlib画直方图(histogram)
  12. 【歌曲分享-第一期】Bendy and the Ink Machine
  13. LR(1)分析法的总控的实现(C++实现)
  14. i217lm网卡驱动linux,【电脑不能上网怎么安装网卡驱动】i217lm网卡驱动xp
  15. 7-利用函数交换两个变量值的方法
  16. 拉普拉斯变换(与傅里叶变换的关系)
  17. Spring 教程01
  18. 电商野史:中酒网CEO 顾建兴
  19. 动力学(dynamics)与动理学(kinetics)概念辨析
  20. 用函数求斐波那契数列前n项和

热门文章

  1. dw软件打开php,php新手求助,为什么在DW中设计里能看到运行php程序的结果,但…...
  2. matlab微分方程稳定流形,基于matlab的lorenz系统仿真研究
  3. 淘宝美工是做什么的?主要工作内容是什么
  4. 青龙面板详细搭建教程
  5. 当数据元素只有一个数据项时,其关键字即为该数据元素的值。
  6. 强化学习的状态值函数与状态动作值函数
  7. 【14】processing-数据(中文)
  8. 看源码,搞明白Logback是如何自动生效的?
  9. 酷睿i5 12490f和i5 12600k差距大吗
  10. HTC VIVE Tracker的二次开发(实际操作篇)附软件