注意力机制的简单示例

昨天看了沐神的动手学深度学习,看了这一节,今天凭记忆把小程序给梳理一遍。书籍分享在专栏置顶了。

书中的例子是,生成了一个关于函数

y=\sin {x}

的50个训练数据和测试数据,训练数据在以上函数的基础上增加了正态分布的随机噪声项。然后,使用简单的示例“注意力机制”对原函数曲线进行预测。

首先,生成训练数据

import torch

x = torch.arange(0, 5, 0.1)
x
f = torch.sin(x)

add_errors = torch.normal(mean=0, std=0.1, size=[50])
add_errors

y = torch.sin(x)
y

y = y + add_errors
y

其中,训练样本加入了均值为0,标准差为0.1的正态分布噪声项。

下面通过核函数引入“注意力机制”。

导入绘图包和softmax函数所在包

import matplotlib.pyplot as plt
import torch.nn.functional as F

生成新的横坐标x

new_x = torch.arange(0, 5, 0.1)
new_x

将new_x进行扩维得到new_x1

new_x1 = new_x.expand(50, 50)
new_x1

new_x1结构如下

tensor([[0.0000, 0.1000, 0.2000,  ..., 4.7000, 4.8000, 4.9000],
        [0.0000, 0.1000, 0.2000,  ..., 4.7000, 4.8000, 4.9000],
        [0.0000, 0.1000, 0.2000,  ..., 4.7000, 4.8000, 4.9000],
        ...,
        [0.0000, 0.1000, 0.2000,  ..., 4.7000, 4.8000, 4.9000],
        [0.0000, 0.1000, 0.2000,  ..., 4.7000, 4.8000, 4.9000],
        [0.0000, 0.1000, 0.2000,  ..., 4.7000, 4.8000, 4.9000]])

再修改结构得到new_x2

new_x2 = new_x.reshape(50, 1)
new_x2

new_x2 = new_x2.expand(50, 50)
new_x2

new_x2结构如下

tensor([[0.0000, 0.0000, 0.0000,  ..., 0.0000, 0.0000, 0.0000],
        [0.1000, 0.1000, 0.1000,  ..., 0.1000, 0.1000, 0.1000],
        [0.2000, 0.2000, 0.2000,  ..., 0.2000, 0.2000, 0.2000],
        ...,
        [4.7000, 4.7000, 4.7000,  ..., 4.7000, 4.7000, 4.7000],
        [4.8000, 4.8000, 4.8000,  ..., 4.8000, 4.8000, 4.8000],
        [4.9000, 4.9000, 4.9000,  ..., 4.9000, 4.9000, 4.9000]])

上面两步得到的new_x1和new_x2主要是为了方便使用张量计算软最大,也就是下一步

new_x = -torch.abs(new_x1 - new_x2)**2
new_x

k = F.softmax(new_x, dim=0)
k

得到张量k的结构如下

tensor([[1.0681e-01, 9.5636e-02, 8.4927e-02,  ..., 2.2535e-11, 9.5240e-12,
         3.9922e-12],
        [1.0575e-01, 9.6597e-02, 8.7514e-02,  ..., 5.7115e-11, 2.4626e-11,
         1.0531e-11],
        [1.0262e-01, 9.5636e-02, 8.8393e-02,  ..., 1.4189e-10, 6.2415e-11,
         2.7230e-11],
        ...,
        [2.7230e-11, 6.2415e-11, 1.4189e-10,  ..., 8.8393e-02, 9.5636e-02,
         1.0262e-01],
        [1.0531e-11, 2.4626e-11, 5.7114e-11,  ..., 8.7513e-02, 9.6597e-02,
         1.0575e-01],
        [3.9922e-12, 9.5240e-12, 2.2535e-11,  ..., 8.4927e-02, 9.5636e-02,
         1.0681e-01]])

可以对k的0维求和看

k.sum(0)

结果如下

tensor([1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000,
        1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000,
        1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000,
        1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000,
        1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000,
        1.0000, 1.0000, 1.0000, 1.0000, 1.0000])

可以看到softmax计算维度元素相加为1,是对的。

修改之前生成的训练样本值y的维度

y = y.unsqueeze(0)
y.size()

使用注意力机制进行预测(这里就是简单的矩阵相乘)

pred = torch.mm(y, k)

结果如下

tensor([[ 0.4356,  0.4640,  0.4938,  0.5246,  0.5562,  0.5883,  0.6206,  0.6526,
          0.6837,  0.7133,  0.7406,  0.7650,  0.7856,  0.8018,  0.8127,  0.8179,
          0.8166,  0.8086,  0.7934,  0.7711,  0.7416,  0.7051,  0.6619,  0.6123,
          0.5569,  0.4962,  0.4309,  0.3616,  0.2891,  0.2140,  0.1370,  0.0590,
         -0.0193, -0.0972, -0.1740, -0.2490, -0.3215, -0.3909, -0.4568, -0.5187,
         -0.5764, -0.6297, -0.6784, -0.7227, -0.7627, -0.7985, -0.8304, -0.8586,
         -0.8836, -0.9054]])

对预测pred缩维,便于之后可视化

pred.squeeze(0)
tensor([ 0.4356,  0.4640,  0.4938,  0.5246,  0.5562,  0.5883,  0.6206,  0.6526,
         0.6837,  0.7133,  0.7406,  0.7650,  0.7856,  0.8018,  0.8127,  0.8179,
         0.8166,  0.8086,  0.7934,  0.7711,  0.7416,  0.7051,  0.6619,  0.6123,
         0.5569,  0.4962,  0.4309,  0.3616,  0.2891,  0.2140,  0.1370,  0.0590,
        -0.0193, -0.0972, -0.1740, -0.2490, -0.3215, -0.3909, -0.4568, -0.5187,
        -0.5764, -0.6297, -0.6784, -0.7227, -0.7627, -0.7985, -0.8304, -0.8586,
        -0.8836, -0.9054])

可视化

plt.title("show", fontsize=20)
plt.xlabel("x", fontsize=15)
plt.ylabel("y", fontsize=15)
plt.scatter(x, y, c='red', s=20)
plt.scatter(x, pred, c='gray', s=20)
plt.plot(x, f, c='blue')
plt.plot(x, torch.Tensor().new_full([50], fill_value=y.mean()), c='green')
plt.show()

其中,蓝色曲线是目标曲线即sin函数,红色圆点是我们生成的训练样本,绿色横线是训练样本均值,而灰色圆点是“注意力”预测结果,可以看到在没有经过任何训练的情况下,核函数+softmax机制就能比较好的接近目标曲线了。 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小P学长

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值