李沐65_注意力分数——自学笔记

ops/2024/9/23 2:28:00/

Additive Attention

等价于将key和value合并起来后放入到一个隐藏大小为h输出大小为1的单隐藏层

总结

1.注意力分数是query和key的相似度,注意力权重是分数的softmax结果

2.两种常见的分数计算:

(1)将query和key合并起来进入一个单输出单隐藏层的MLP

(2)直接将query和key做内积

注意力打分函数

python">!pip install d2l
python">import math
import torch
from torch import nn
from d2l import torch as d2l

masked_softmax函数 实现了这样的掩蔽softmax操作(masked softmax operation), 其中任何超出有效长度的位置都被掩蔽并置为0。

python">def masked_softmax(X, valid_lens):"""通过在最后一个轴上掩蔽元素来执行softmax操作"""# X:3D张量,valid_lens:1D或2D张量if valid_lens is None:return nn.functional.softmax(X, dim=-1)else:shape = X.shapeif valid_lens.dim() == 1:valid_lens = torch.repeat_interleave(valid_lens, shape[1])else:valid_lens = valid_lens.reshape(-1)# 最后一轴上被掩蔽的元素使用一个非常大的负值替换,从而其softmax输出为0X = d2l.sequence_mask(X.reshape(-1, shape[-1]), valid_lens,value=-1e6)return nn.functional.softmax(X.reshape(shape), dim=-1)

考虑由两个2X4
矩阵表示的样本, 这两个样本的有效长度分别为2
和3
。 经过掩蔽softmax操作,超出有效长度的值都被掩蔽为0。

python">masked_softmax(torch.rand(2, 2, 4), torch.tensor([2, 3]))
tensor([[[0.3505, 0.6495, 0.0000, 0.0000],[0.5069, 0.4931, 0.0000, 0.0000]],[[0.2469, 0.4668, 0.2863, 0.0000],[0.2865, 0.3008, 0.4127, 0.0000]]])

同样,也可以使用二维张量,为矩阵样本中的每一行指定有效长度。

python">masked_softmax(torch.rand(2, 2, 4), torch.tensor([[1, 3], [2, 4]]))
tensor([[[1.0000, 0.0000, 0.0000, 0.0000],[0.2102, 0.3264, 0.4634, 0.0000]],[[0.4785, 0.5215, 0.0000, 0.0000],[0.1783, 0.1803, 0.3615, 0.2800]]])

additive attention

python">class AdditiveAttention(nn.Module):"""加性注意力"""def __init__(self, key_size, query_size, num_hiddens, dropout, **kwargs):super(AdditiveAttention, self).__init__(**kwargs)self.W_k = nn.Linear(key_size, num_hiddens, bias=False)self.W_q = nn.Linear(query_size, num_hiddens, bias=False)self.w_v = nn.Linear(num_hiddens, 1, bias=False)self.dropout = nn.Dropout(dropout)def forward(self, queries, keys, values, valid_lens):queries, keys = self.W_q(queries), self.W_k(keys)# 在维度扩展后,# queries的形状:(batch_size,查询的个数,1,num_hidden)# key的形状:(batch_size,1,“键-值”对的个数,num_hiddens)# 使用广播方式进行求和features = queries.unsqueeze(2) + keys.unsqueeze(1)features = torch.tanh(features)# self.w_v仅有一个输出,因此从形状中移除最后那个维度。# scores的形状:(batch_size,查询的个数,“键-值”对的个数)scores = self.w_v(features).squeeze(-1)self.attention_weights = masked_softmax(scores, valid_lens)# values的形状:(batch_size,“键-值”对的个数,值的维度)return torch.bmm(self.dropout(self.attention_weights), values)

用一个小例子来演示上面的AdditiveAttention类, 其中查询、键和值的形状为(批量大小,步数或词元序列长度,特征大小), 实际输出为(2,1,20)
、(2,10,2)
和(2,10,4)
。 注意力汇聚输出的形状为(批量大小,查询的步数,值的维度)。

python">queries, keys = torch.normal(0, 1, (2, 1, 20)), torch.ones((2, 10, 2))
# values的小批量,两个值矩阵是相同的
values = torch.arange(40, dtype=torch.float32).reshape(1, 10, 4).repeat(2, 1, 1)
valid_lens = torch.tensor([2, 6])attention = AdditiveAttention(key_size=2, query_size=20, num_hiddens=8,dropout=0.1)
attention.eval()
attention(queries, keys, values, valid_lens)
tensor([[[ 2.0000,  3.0000,  4.0000,  5.0000]],[[10.0000, 11.0000, 12.0000, 13.0000]]], grad_fn=<BmmBackward0>)

管加性注意力包含了可学习的参数,但由于本例子中每个键都是相同的, 所以注意力权重是均匀的,由指定的有效长度决定

python">d2l.show_heatmaps(attention.attention_weights.reshape((1, 1, 2, 10)),xlabel='Keys', ylabel='Queries')

在这里插入图片描述

缩放点积注意力

(scaled dot-product attention)评分函数

python">class DotProductAttention(nn.Module):"""缩放点积注意力"""def __init__(self, dropout, **kwargs):super(DotProductAttention, self).__init__(**kwargs)self.dropout = nn.Dropout(dropout)# queries的形状:(batch_size,查询的个数,d)# keys的形状:(batch_size,“键-值”对的个数,d)# values的形状:(batch_size,“键-值”对的个数,值的维度)# valid_lens的形状:(batch_size,)或者(batch_size,查询的个数)def forward(self, queries, keys, values, valid_lens=None):d = queries.shape[-1]# 设置transpose_b=True为了交换keys的最后两个维度scores = torch.bmm(queries, keys.transpose(1,2)) / math.sqrt(d)self.attention_weights = masked_softmax(scores, valid_lens)return torch.bmm(self.dropout(self.attention_weights), values)

为了演示上述的DotProductAttention类, 我们使用与先前加性注意力例子中相同的键、值和有效长度。 对于点积操作,我们令查询的特征维度与键的特征维度大小相同。

python">queries = torch.normal(0, 1, (2, 1, 2))
attention = DotProductAttention(dropout=0.5)
attention.eval()
attention(queries, keys, values, valid_lens)
tensor([[[ 2.0000,  3.0000,  4.0000,  5.0000]],[[10.0000, 11.0000, 12.0000, 13.0000]]])

与加性注意力演示相同,由于键包含的是相同的元素, 而这些元素无法通过任何查询进行区分,因此获得了均匀的注意力权重。

python">d2l.show_heatmaps(attention.attention_weights.reshape((1, 1, 2, 10)),xlabel='Keys', ylabel='Queries')

在这里插入图片描述


http://www.ppmy.cn/ops/19597.html

相关文章

《设计模式之美》第五章 总结

《设计模式之美》第五章 总结 第五章 重构技巧 5.1 重构四要素&#xff1a;目的、对象、时机和方法 5.1.1 重构的目的&#xff1a;为什么重构 定义&#xff1a;重构是一种对软件内部结构的改善&#xff0c;目的是在不改变软件对外部的可见行为的情况下&#xff0c;使其更容…

FPGA verilog 模板设计示例(持续更新)

重温一下大道至简的至简设计法&#xff0c;正式开发两年多回顾当时的设计方法&#xff0c;又有了更多的体会和感触&#xff0c;希望将模块化运用起来会更有条例。1 FPGA设计代码模板 信号命名规范&#xff1a; 1 clk 表示时钟信号小写 2 rstn 表示高电平复位信号 小写 3 rst_n…

MATLAB矩阵

MATLAB 矩阵 矩阵是数字的二维数组。 在MATLAB中&#xff0c;您可以通过在每行中以逗号或空格分隔的数字输入元素并使用分号标记每行的结尾来创建矩阵。 例如&#xff0c;让我们创建一个45矩阵一- 示例 a [ 1 2 3 4 5; 2 3 4 5 6; 3 4 5 6 7; 4 5 6 7 8] MATLAB将执行上述语…

gitlab关联新仓库

如果你想要将现有的Git仓库提交&#xff08;或推送&#xff09;到一个新的远程地址&#xff0c;你可以通过以下步骤来完成&#xff1a; 查看现有的远程仓库&#xff1a; 首先&#xff0c;确认你当前的仓库有哪些远程地址。 git remote -v如果输出中显示了旧的远程地址&#x…

粒子群算法与优化储能策略python实践

粒子群优化算法&#xff08;Particle Swarm Optimization&#xff0c;简称PSO&#xff09;, 是1995年J. Kennedy博士和R. C. Eberhart博士一起提出的&#xff0c;它是源于对鸟群捕食行为的研究。粒子群优化算法的基本核心是利用群体中的个体对信息的共享从而使得整个群体的运动…

SSH Key生成

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

【海博】雅思该怎么考?

文章目录 考试类型 考试内容 考试形式 备考资源 考试报名 考试成绩 考试类型 学术类&#xff08;A类&#xff09;适用于&#xff1a;出国留学申请本科&#xff0c;研究生及以上学位&#xff0c;或获得专业资质。学术类考试评估考生的英语水平是否满足进行大学或研究生学习…

线程的状态

1.线程状态的种类 NEW:Thread 对象有了,调用 start系统内部的线程还未创建。RUNNABLE:指的是,这个线程"随叫随到"。 a)这个线程正在 CPU 上执行 b)这个线程虽然没在 CPU 上执行,随时可以调度到 CPU 上执行BLOCKED:进行锁竞争的时候产生的阻塞&#xff08;本文暂不涉…