深度学习05 - 循环神经网络-实践篇-RNN预测sin函数

1、导包

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

2、设定参数

#参数设定
num_time_steps = 50
#训练时循环次数
input_size = 1
#输入维度
hidden_size = 16
#隐藏层节点个数
output_size = 1
#输出维度

就是相当于每个节点1维扩展成了16维然后再映射到1维

3、通过pytorch建立RNN模型

#网络结构定义
class Net(nn.Module):

    def __init__(self):
        super(Net, self).__init__()
        self.rnn = nn.RNN(
            input_size=input_size,
            #输入数据的维度,比如使用one-hot编码单词,300个值表示一个字母维度就是300
            hidden_size=hidden_size,
            #隐藏层节点的个数
            num_layers=1,#叠加的层数,此处只叠加一层
            #即RNN经过几层堆叠得到结果
            batch_first=True
            #RNN默认输入是(seq_len, batch_size, input_size),此时batch_size在第一维度,所以需要设置成True
        )
        self.liner = nn.Linear(hidden_size, output_size)

    def forward(self, x, hidden_prev):
        out, hidden_prev = self.rnn(x, hidden_prev)
        out = out.view(-1, hidden_size)
        out = self.liner(out)
        out = out.unsqueeze(dim=0)
        return out, hidden_prev

参数解释:参考链接

1.input_size
说白了input_size无非就是你输入RNN的维度,比如说NLP中你需要把一个单词输入到RNN中,这个单词的编码是300维的,那么这个input_size就是300.这里的input_size其实就是规定了你的输入变量的维度。用f(wX+b)来类比的话,这里输入的就是X的维度。

2.hidden_size
和最简单的BP网络一样的,每个RNN的节点实际上就是一个BP嘛,包含输入层,隐含层,输出层。这里的hidden_size呢,你可以看做是隐含层中,隐含节点的个数。

3.num_layers
表示RNN是由几层堆叠在一起的
如果是num_layer1的话:
在这里插入图片描述
如果num_layer
2的话:
在这里插入图片描述

4.最终输出:hn与output
(1)hidden的输出size为[ num_layers* num_directions, batch_size, n_hidden].
说白了,hidden就是每个方向,每个层的 隐藏单元的输出,所以是n_hidden个。
(2)output的size(如果RNN设定的batch_first=True),那么就是[batch_size,seq_len,n_hidden],对于分类任务如果要取得最后一个output,只需添加下标 [ :,-1,:]
在这里插入图片描述
hn就是RNN的最后一个隐含状态,output就是RNN最终得到的结果。

4、训练RNN模型

#训练网络
model = Net()#初始化RNN
criterion = nn.MSELoss()#定义损失函数
optimizer = optim.Adam(model.parameters(), 1e-2)#优化器

hidden_prev = torch.zeros(1, 1, hidden_size) #初始化h0,即开始向后一层传递的记忆单元

for iter in range(6000):
    start = np.random.randint(3, size=1)[0]#在0~3之间随机取开始的时刻点
    # print(start)
    time_steps = np.linspace(start, start + 10, num_time_steps)
    #在开始点和开始点+10之间均匀的取50个点,用于绘制图像,做数据集
    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)
    #将数据转为Tensor类型:(batch_size,seq_len, input_size)
    y = torch.tensor(data[1:]).float().view(1, num_time_steps - 1, 1)

    output, hidden_prev = model(x, hidden_prev)
    #output输出的是预测的49个值的结果,hp是隐藏层每个维度的输出值
    # print('output',output.size())
    # print('prev',hidden_prev.size())
    hidden_prev = hidden_prev.detach()
    #将原来变量赋值一份并转为Tensor格式

    loss = criterion(output, y)
    #计算误差值

    model.zero_grad()
    #梯度清零

    loss.backward()
    optimizer.step()
    #反向传播优化

    #每训练100次输出一次误差
    if iter % 100 == 0:
        print("Iter: {} loss: {} ".format(iter, loss))

5、保存模型并生成test值预测

state = {'net':model.state_dict(), 'optimizer':optimizer.state_dict()}
filePath = '/Users/fengxiaolin/Library/Containers/com.kingsoft.wpsoffice.mac/Data/Library/Application Support/Kingsoft/WPS Cloud Files/userdata/qing/filecache/唐荣的云文档/00000研究生/机器学习/Model/RNN.kpl'
torch.save(state,filePath)

#预测以及绘图
start = np.random.randint(3, size=1)[0]
print(start)
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)
#将数据x转为Tensor类型
y = torch.tensor(data[1:]).float().view(1, num_time_steps - 1, 1)
#将数据y转为Tensor类型
prediction = [] #预期数据矩阵
input = x[:, 0, :]
for _ in range(x.shape[1]):
    input = input.view(1, 1, 1)
    (pred, hidden_prev) = model(input, hidden_prev)
    input = pred
    prediction.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:], prediction)
plt.show()

6、结果

在这里插入图片描述

7、整体代码

# Python TR
# Time:2021/1/26 4:30 下午
import torch.utils.data
from torch import optim, nn
import numpy as np
import matplotlib.pyplot as plt
import torch

#参数设定
num_time_steps = 50
#训练时循环次数
input_size = 1
#输入维度
hidden_size = 16
#隐藏层节点个数
output_size = 1
#输出维度

#网络结构定义
class Net(nn.Module):

    def __init__(self):
        super(Net, self).__init__()
        self.rnn = nn.RNN(
            input_size=input_size,
            #输入数据的维度,比如使用one-hot编码单词,300个值表示一个字母维度就是300
            hidden_size=hidden_size,
            #隐藏层节点的个数
            num_layers=1,#叠加的层数,此处只叠加一层
            #即RNN经过几层堆叠得到结果
            batch_first=True
            #RNN默认输入是(seq_len, batch_size, input_size),此时batch_size在第一维度,所以需要设置成True
        )
        self.liner = nn.Linear(hidden_size, output_size)

    def forward(self, x, hidden_prev):
        out, hidden_prev = self.rnn(x, hidden_prev)
        out = out.view(-1, hidden_size)
        # print(out.shape)
        out = self.liner(out)
        out = out.unsqueeze(dim=0)
        return out, hidden_prev

#训练网络
model = Net()#初始化RNN
criterion = nn.MSELoss()#定义损失函数
optimizer = optim.Adam(model.parameters(), 1e-2)#优化器

hidden_prev = torch.zeros(1, 1, hidden_size) #初始化h0,即开始向后一层传递的记忆单元

for iter in range(6000):
    start = np.random.randint(3, size=1)[0]#在0~3之间随机取开始的时刻点
    #??
    # print(start)
    time_steps = np.linspace(start, start + 10, num_time_steps)
    #在开始点和开始点+10之间均匀的取50个点,用于绘制图像,做数据集
    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)
    #将数据转为Tensor类型:(batch_size,seq_len, input_size)
    y = torch.tensor(data[1:]).float().view(1, num_time_steps - 1, 1)

    output, hidden_prev = model(x, hidden_prev)
    #output输出的是预测的49个值的结果,hp是隐藏层每个维度的输出值
    # print('output',output.size())
    # print('prev',hidden_prev.size())
    hidden_prev = hidden_prev.detach()
    #??分离出变量并且在新变量中不使用梯度

    loss = criterion(output, y)
    #计算误差值

    model.zero_grad()
    #梯度清零

    loss.backward()
    optimizer.step()
    #反向传播优化

    #没训练100次输出一次误差
    if iter % 100 == 0:
        print("Iter: {} loss: {} ".format(iter, loss))

state = {'net':model.state_dict(), 'optimizer':optimizer.state_dict()}
filePath = '/Users/fengxiaolin/Library/Containers/com.kingsoft.wpsoffice.mac/Data/Library/Application Support/Kingsoft/WPS Cloud Files/userdata/qing/filecache/唐荣的云文档/00000研究生/机器学习/Model/RNN.kpl'
torch.save(state,filePath)

#预测以及绘图
start = np.random.randint(3, size=1)[0]
print(start)
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)
#将数据x转为Tensor类型
y = torch.tensor(data[1:]).float().view(1, num_time_steps - 1, 1)
#将数据y转为Tensor类型
prediction = [] #预期数据矩阵
input = x[:, 0, :]
for _ in range(x.shape[1]):
    input = input.view(1, 1, 1)
    (pred, hidden_prev) = model(input, hidden_prev)
    input = pred
    prediction.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:], prediction)
plt.show()
  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值