(八)循环神经网络(RNN)

(八)循环神经网络(RNN)

why RNN

在这里插入图片描述

当我们采用此种方式构建网络的时候,需要对所有单词都进行编码,然后每个单词都需要进行w,b向量运算。这样当输入的单词句子很长的时候就需要很多的w,b这样就增大了我们的计算量。更为致命的一个问题是,这样的网络计算的构建没有考虑上下文的语境信息,只是考虑了当前单词的信息,这样不方便我们更好理解句子的意思。

在这里插入图片描述

基于没法考虑上下文信息和参数过大的问题,我们可以采用权值共享的方法。但是这样还是存在一个问题,上文的语境信息会随着句子不断向后而变弱,所以我们需要让上文的语境信息随着时间的推移而衰减。这样我们需要一个长期的记忆来保存上文的语境信息

在这里插入图片描述

如上,我们可以在计算当前参数的时候利用前一个的信息加上一定的权值做运算,这样保证用到了上文的语境信息也保证了上文的语境信息会随着句子单词的向后推移而衰减。

这样得到如下的:

在这里插入图片描述

给定一个初始的值,然后不断加入特征迭代计算就可以得到考虑上下文语境的当前语境的信息。

RNN的标准计算如下:

在这里插入图片描述

下面我来看怎么去训练RNN

在这里插入图片描述

上图给出了计算梯度的公式,我们可以根据这些公式去进行训练得到最好的解。

在这里插入图片描述

下面我们根据上图的计算公式来在pytorch中实现

在这里插入图片描述

下面我们来用RNN来实战时间序列预测问题。

import torch
from torch import nn
from torch import optim
import numpy as np
import matplotlib.pyplot as plt

num_time_steps = 50
input_size = 1
hidden_size = 16
output_size = 1
lr = 0.01

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.rnn = nn.RNN(
            input_size=input_size,
            hidden_size=hidden_size,
            num_layers=1,  # 一层
            batch_first=True
        )
        for p in self.rnn.parameters():
            nn.init.normal_(p, mean=0.0, std=0.001)
        self.linear = nn.Linear(hidden_size, output_size)

    def forward(self, x, hidden_prev):
        out, hidden_prev = self.rnn(x, hidden_prev)
        # [b, seq, h]
        out = out.view(-1, hidden_size)
        out = self.linear(out)
        out = out.unsqueeze(dim=0)
        return out, hidden_prev

model = Net()
criterion = nn.MSELoss()
optimizer = optim.Adam(model.parameters(), lr)
hidden_prev = torch.zeros(1, 1, hidden_size)

for iter in range(6000):
    start = np.random.randint(3, size=1)[0]
    time_steps = np.linspace(start, start + 10, num_time_steps)
    data = np.sin(time_steps)
    data = data.reshape(num_time_steps, 1)
    x = torch.tensor(data[:-1]).float().view(1, num_time_steps - 1, 1)
    y = torch.tensor(data[1:]).float().view(1, num_time_steps - 1, 1)

    output, hidden_prev = model(x, hidden_prev)
    hidden_prev = hidden_prev.detach()

    loss = criterion(output, y)
    model.zero_grad()
    loss.backward()

    optimizer.step()

    if iter % 100 == 0:
        print("Iteration:{} loss {}".format(iter, loss.item()))

start = np.random.randint(3, size=1)[0]
time_steps = np.linspace(start, start + 10, num_time_steps)
data = np.sin(time_steps)
data = data.reshape(num_time_steps, 1)
x = torch.tensor(data[:-1]).float().view(1, num_time_steps - 1, 1)
y = torch.tensor(data[1:]).float().view(1, num_time_steps - 1, 1)

predictions = []
input = x[:,0,:]
for _ in range(x.shape[1]):
    input = input.view(1, 1, 1)
    (pred, hidden_prev) = model(input, hidden_prev)
    input = pred
    predictions.append(pred.detach().numpy().ravel()[0])

x = x.data.numpy().ravel()
y = y.data.numpy()
plt.scatter(time_steps[:-1], x.ravel(), s=90)
plt.plot(time_steps[:-1], x.ravel())

plt.scatter(time_steps[1:], predictions)
plt.show()

结果如下:

[外链图片转存中...(img-mWDTYYbT-1644299056819)]

可以看到预测点(黄色)和实际的点(蓝色)的区别不大

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值