注意力机制--Nadaraya-Watson核回归

部署运行你感兴趣的模型镜像

10.1介绍了框架下注意力机制主要组件查询之间交互形成注意力汇聚注意力汇聚选择性汇聚生成最终输出介绍注意力汇聚更多细节以便宏观上了解注意力机制实践中运作方式具体来说1964提出Ndaraya-Watson回归模型是一个简单但是完整例子可以用于演示具体注意力机制机器学习

import torch

from torch import nn

from d2l import torch as d2l

10.2.1 生成数据集

为简单期间考虑下面回归问题给定成对输入-输出 数据集(X1, Y1) 如何学习f预测任意输入x输出y^ = f(x)?

根据下面非线性函数生成一个人工数据集

Yi = 2 sin(Xi) + Xi^0.8 + t

其中 t加入噪声服从均值0标准差0.5分布在这里生成了50训练样本50测试样本为了更好可视化之后注意力模式需要将训练样本进行排序

n_train = 50 #训练样本数

x_train, _ = torch.sort(torch.rand(n_train) * 5) #排序后的训练样本

def f(x):

return 2 / torch.sin(x) + x ** 0.8

y_train = f(x_train) + torch.normal(0.0, 0.5, (n_train,)) #训练样本输出

x_test = torch.arange(0, 5, 0.1) #测试样本

y_truth = f(x_test)#测试样本真实输出

n_test = len(x_test) #测试样本

n_test

下面函数绘制所有的训练样本不带噪声真实数据生成函数f(标记为Truth)以及学习得到预测函数

def plot_kernel_reg(y_hat):

d2l.plot(x_test, [y_truth, y_hat], 'x', 'y', legend=['Truth', 'Pred'],

xlim = [0, 5], ylim=[-1, 5])

d2l.plt.plot(x_train, y_train, 'o', alpha=0.5)

10.2.2 平均汇聚

使用简单估计解决回归问题基于平均汇聚来计算所有训练样本输出平均值

f(x) = 1/n * Sigma i=1,yi

如下图所示这个估计确实不够聪明真实函数f(Truth)预测函数Pred相差很大

y_hat = torch.repeat_interleave(y_train.mean(), n_test)

plot_kernel_reg(y_hat)

10.2.3 参数注意力汇聚

平均汇聚忽略了输入xi, 于是NadarayaWatson提出了一个更好想法根据输入位置输出yi进行加权

f(x) = Sigma i=1,

KKernel, 所描述估计称为Nadaraya-Watson回归这里不会深入讨论函数细节受此启发可以10-3注意力机制框架角度充血使之成为一个更加通用注意汇聚公式

f(x) = Sigma i=1 a(x, xi)yi

x查询(xi,yi)键值

值得注意是Nadaray-Waston回归是个非参数模型注意力汇聚模型接下来我们将基于这个非参数注意力汇聚模型绘制预测结果从绘制结果会发现新的模型预测线平滑并且平均汇聚预测更接近真实情况

X_repeat形状(n_test, n_train)

每一行都包含相同测试输入例如同样查询

X_repeat = x_test.repeat_interleave(n_train).reshape(-1, n_train)

x_train包含attention_weights形状(n_test, n_train)

每一行都包含要在给定每个查询y_train之间分配注意力权重

attention_weights = nn.functional.softmax(-(X_repeat - x_train)**2/2, dim=1)

y_hat每个元素都是值加权平均值其中权重注意力权重

y_hat = torch.matmul(attention_weights, y_train)

plot_kernel_reg(y_hat)

现在来观察注意力权重这里测试数据输入相当于查询训练数据输入相当于因为两个输入都是经过排序所以观察可知 查询- 越接近注意力汇聚注意力权重越高

d2l.show_heatmaps(attention_weights.unsqueeze(0).unsqueeze(0), xlabel = 'Sorted trainning inputs',

ylabel = 'Sorted testint inputs')

10.2.4 带参数注意力汇聚

非参数Nadaraya_Watson回归具有一致性优点如果足够的数据模型会收敛最优结果尽管如此还是可以轻松科学系参数集成到注意力汇聚

10.6 略有不同将下面查询xxi之间距离乘以学习参数w

本节剩余部分将通过训练这个模型来学习注意力汇聚参数

1 批量矩阵乘法

为了更有效计算小批量数据注意力可以利用深度学习开发框架提供批量矩阵乘法

假设第一个小批量数据包含n矩阵Xl,,,Xn形状axb第二个小批量数据包含n矩阵Yl,,Yn形状bxc批量矩阵乘法得到n矩阵X1,Y1,,,Xn,Yn形状axc假设两个张量形状分别(n,a,b)(n,b,c) 批量矩阵乘法输出形状(n,a,c)

X=torch.ones(2,1,4)

Y = torch.ones(2,4,6)

torch.bmm(X,Y).shape

在主利益机制背景可以使用小批量矩阵乘法计算小批量数据中加权平均值

weights = torch.ones(2, 10) * 0.1

values = torch.arange(20.0).reshape(2, 10)

torch.bmm(weights.unsqueeze(1), values.unsqueeze(-1))

2 定义模型

基于10.7带参数注意力汇聚使用小批量矩阵乘法定义Nadaraya-Watson回归带参数版本

class NWKernelRegression(nn.Module):

def __init__(self, **kwargs):

super().__init__(**kwargs)

self.w = nn.Parameter(torch.rand(1,)), requires_grad = True

def forward(self, queries, keys, values):

#queriesattention_weights形状(查询数,键值对数)

queries = queries.repeat_interleave(keys.shape[l]).reshape(-1, keys.shape[l])

self.attention_weights = nn.functional.sofmax(--(queries - keys) self.w) *2 / 2, dim=1)

#values形状查询-对数

return torch.bmm(self.attention_weights_unsqueeze(1), values_unsqueeze(-1).reshape(-1))

3 训练

训练数据集变换用于训练注意力模型在带参数注意力汇聚模型任何一个训练样本输入都会自身以外所有训练样本-进行计算从而得到对应预测输出

X_tile形状n_train, n_train 每一行都包含相同训练输入

X_tile = x_train.repeat(n_train, 1)

Y_tile形状(n_train, n_train)每一行都包含相同训练输出

Y_tile = y_train.repeat(n_train, 1)

keys形状n_train, n_train - 1

keys = X_tile[(1 - torch.eye(n_train)).type(torch.bool)].reshape(n_train, -1)

values形状(n_train, n_train - 1)

values = Y_tile[(1 - torch.eye(n_train)).type(torch.bool)].reshape(n_trian, -1)

训练参数注意力汇聚模型使用平方损失函数随机梯度下降

net = NWKernelRegression()

loss = nn.MSELoss(reduction='none')

trainer = torch.optim.SGD(net.parameters(), lr=0.5)

animator = d2l.Animator(xlabel='epoch', ylabel='loss', xlim = [1,5])

for epoch in range(5):

trainer.zero_grad()

l = loss(net(x_train, keys, values), y_train)

  1. sum().backward()
  1. trainer.step()

animator.add(epoch + 1, float(l.sum()))

训练带参数注意力汇聚模型可以发现在尝试拟合噪声训练数据预测结果绘制曲线不如之前参数模型平滑

keys形状(n_test, n_train) 每一行包含相同训练输入

keys = x_train.repeat(n_test, l)

value形状n_test, n_train

values = y_train.repeat(n_test, l)

y_hat = net(x_test, keys, values).unsqueeze(1).detach()

plot_kernel_reg(y_hat)

模型更不平滑下面看一下输出结果绘制非参数注意力汇聚模型相比带参数模型加入学习参数曲线注意力权重较大区域变得更不平滑

小结

Nadaray-Watson回归是具有注意力机制机器学习范例

Nadaray-Watson 核回归注意力汇聚训练数据输出加权平均从注意力角度来看

注意力汇聚可以分为参数带参数

您可能感兴趣的与本文相关的镜像

PyTorch 2.5

PyTorch 2.5

PyTorch
Cuda

PyTorch 是一个开源的 Python 机器学习库,基于 Torch 库,底层由 C++ 实现,应用于人工智能领域,如计算机视觉和自然语言处理

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值