什么是循环神经网络RNN?|(基于pytorch)代码+详细注释

一、循环神经网络

它并非刚性地记忆所有固定长度的序列,而是通过隐藏状态来存储之前时间步的信息。

我们想象现在有一组序列数据 data 0,1,2,3。 在当预测 result0 的时候,我们基于的是 data0, 同样在预测其他数据的时候, 我们也都只单单基于单个的数据。 每次使用的神经网络都是同一个 NN(neural network)。不过这些数据是有关联顺序的 , 就像在厨房做菜, 酱料 A 要比酱料 B 早放, 不然就串味了。所以普通的神经网络结构并不能让 NN 了解这些数据之间的关联。

那我们如何让数据间的关联也被 NN 加以分析呢? 想想我们人类是怎么分析各种事物的关联吧, 最基本的方式,就是记住之前发生的事情. 那我们让神经网络也具备这种记住之前发生的事的能力. 再分析 Data0 的时候, 我们把分析结果存入记忆. 然后当分析 data1的时候, NN会产生新的记忆, 但是新记忆和老记忆是没有联系的. 我们就简单的把老记忆调用过来, 一起分析. 如果继续分析更多的有序数据 , RNN就会把之前的记忆都累积起来, 一起分析.

我们再重复一遍刚才的流程, 不过这次是以加入一些数学方面的东西. 每次 RNN 运算完之后都会产生一个对于当前状态的描述 , state. 我们用简写 S(t) 代替, 然后这个 RNN开始分析 x(t+1) , 他会根据 x(t+1)产生s(t+1), 不过此时 y(t+1) 是由 s(t) 和 s(t+1) 共同创造的. 所以我们通常看到的 RNN 也可以表达成这种样子.

二、代码案例:

1.相关包

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

 2.网络结构

time_step和input_size的关系:每一个time_step,也就是每一次时间节点,都会读取input_size大小的数据。例如本次案例中,steps = np.linspace(start, end, 10, dtype=np.float32),每一步随机给出10个数据点,而input_size=1,也就是每一次时间节点读取1个数据,而共有10个数据点,因此time_step=10.

# Hyper Parameters
TIME_STEP = 10      # rnn time step 
INPUT_SIZE = 1      # rnn input size 
LR = 0.02           # learning rate

class RNN(nn.Module):
    def __init__(self):
        super(RNN,self).__init__()
        self.rnn=nn.RNN(
            input_size=1, #输入特征值
            hidden_size=32,#隐藏层
            num_layers=1,#有几层RNN layers
            batch_first=True## input & output 会是以 batch size 为第一维度的特征集 e.g. (batch, time_step, input_size)
        )
        self.out=nn.Linear(32,1)
    def forward(self,x,h_state):
        # x (batch, time_step, input_size)
        # h_state (n_layers, batch, hidden_size)
        # r_out (batch, time_step, output_size)
        r_out,h_state=self.rnn(x,h_state)  #会输出目标值,还有状态值
        outs=[]#保存所有时间点的预测值
        for time_step in range(TIME_STEP):
            outs.append(self.out(r_out[:,time_step,:]))
        return torch.stack(outs,dim=1),h_state #因为outs是一个列表,转化成torch要进行压缩
        # r_out, h_state = self.rnn(x, h_state)
        # r_out = r_out.view(-1, 32)
        # outs = self.out(r_out)
        # return outs.view(-1, 32, TIME_STEP), h_state

 3.训练及其可视化

rnn=RNN()
optimizer = torch.optim.Adam(rnn.parameters(), lr=LR)   # optimize all rnn parameters
loss_func = nn.MSELoss()

h_state = None   # 要使用初始 hidden state, 可以设成 None

plt.ion()
for step in range(100):
    start, end = step * np.pi, (step+1)*np.pi   # time steps
    # sin 预测 cos
    steps = np.linspace(start, end, 10, dtype=np.float32)
    x_np = np.sin(steps)    # float32 for converting torch FloatTensor
    y_np = np.cos(steps)

    x = torch.from_numpy(x_np[np.newaxis, :, np.newaxis])    # shape (batch, time_step, input_size)
    y = torch.from_numpy(y_np[np.newaxis, :, np.newaxis])

    prediction, h_state = rnn(x, h_state)   # rnn 对于每个 step 的 prediction, 还有最后一个 step 的 h_state
    # !!  下一步十分重要 !!
    h_state = h_state.data  # 要把 h_state 重新包装一下才能放入下一个 iteration, 不然会报错

    loss = loss_func(prediction, y)     # cross entropy loss
    optimizer.zero_grad()               # clear gradients for this training step
    loss.backward()                     # backpropagation, compute gradients
    optimizer.step()                    # apply gradients
    plt.plot(steps,prediction.data.numpy().flatten(),'b-')#因为最后prediction的shape为(1,10,1),需要压缩
    plt.plot(steps,y_np,'r-')
    plt.draw()
    plt.pause(0.1)
plt.ioff()
plt.show()

可视化输出结果:

 

  • 7
    点赞
  • 79
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值