
Pytorch 第十一回:循环神经网络——RNN模型
本次开启深度学习第十一回,基于Pytorch的RNN循环神经网络模型。前面我们已经分享过线性神经网络、多层神经网络和卷积神经网络。接下来,开始学习循环神经网络。本回分享的第一个循环神经网络,叫做RNN模型。在本回中,设计通过RNN模型来对股票收盘价格进行预测。接下来给大家分享具体思路。本次学习,借助的平台是PyCharm 2024.1.3,python版本3.11 numpy版本是1.26.4,p
Pytorch 第十一回:循环神经网络——RNN模型
本次开启深度学习第十一回,基于Pytorch的RNN循环神经网络模型。前面我们已经分享过线性神经网络、多层神经网络和卷积神经网络。接下来,开始学习循环神经网络。本回分享的第一个循环神经网络,叫做RNN模型。在本回中,设计通过RNN模型来对股票收盘价格进行预测。接下来给大家分享具体思路。
本次学习,借助的平台是PyCharm 2024.1.3,python版本3.11 numpy版本是1.26.4,pytorch版本2.0.0+cu118,d2l的版本是1.0.3
文章目录
前言
讲述模型前,先讲述两个概念,统一下思路:
1、RNN
RNN(Recurrent Neural Network)翻译成中文就是循环神经网络。RNN通过加入状态变量使模型可存储过去的信息,再结合当前的输入,从而形成完整的输入数据。因此RNN模型可以很好地处理序列数据。
2、隐藏层
RNN的隐藏层是RNN模型的核心机制。隐藏层不仅用于处理当前输入,还通过记忆历史信息,实现对序列数据的动态建模。
RNN的隐藏层在每个时间步接收两个输入:一个是当前时刻的输入;另一个是前一时刻的隐藏状态,即历史信息的压缩表示。之后,RNN模型通过权重矩阵和非线性激活函数(如 tanh 或 ReLU),将这两个输入融合为新的隐藏状态。
3、隐藏状态
隐藏状态是RNN处理序列数据的“记忆单元”,通过动态的方式更新、传递历史数据,从而使RNN模型能够分析出序列中的时序关联关系。
注:
1)在每个时间步中,隐藏状态是当前输入和过去所有输入的压缩表示,表达了序列的上下文关系。
2)隐藏状态保存了从序列起始位置到当前时间步的所有历史数据,并进行动态更新,从而反映输入的变化。
4、RNN 对比 CNN
1)应用上:RNN,常用来处理序列数据的;CNN主要用于图像处理。
RNN的特点是具有循环结构,可以记住历史信息,因此常用来处理时间序列或者自然语言。CNN通过卷积核提取空间特征,比如边缘、纹理等,因此主要用于图像处理。
2)结构上,RNN是循环反馈的,而CNN是层级递进,。RNN的每个时间步会处理输入,并且隐藏层的状态会传递到下一个时间步,这样就有了记忆能力。而CNN是通过卷积层、池化层这些来逐步减少数据维度,提取特征。
3)信号输入上,RNN的输入是可变长度的序列,CNN通常处理固定大小的输入。
4)参数共享上,RNN的参数在时间步之间共享,也就是每个时间步用的都是同一组参数,这样处理变长序列时更高效;CNN的卷积核在图像的不同位置共享参数,这样减少参数数量并捕捉空间局部特征。
闲言少叙,直接展示逻辑,先上引用:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import torch
from torch import nn
import time
一、数据准备
1、读取数据
首先,从csv文件中读取股票的收盘价格。csv文件可以从本人分享的资源中下载。
data_csv = pd.read_csv('./stock_data.csv', usecols=[3])
价格的趋势图如下所示:
2、数据预处理
为方便处理数据,这里将数据进行归一化。
data_csv = data_csv.dropna()
dataset = data_csv.values
dataset = dataset.astype('float32')
max_value = np.max(dataset)
min_value = np.min(dataset)
interval = max_value - min_value
dataset = list(map(lambda x: x / interval, dataset))
3、数据划分
进行数据预测时,设计用前三天的数据预测今天的数据。因此需要将数据进行一个划分,即三天前的数据集data_X和当天的数据集data_Y 。代码如下:
def optimize_dataset(dataset, primitive=3):
dataX, dataY = [], []
for i in range(len(dataset) - primitive):
a = dataset[i:(i + primitive)]
dataX.append(a)
dataY.append(dataset[i + primitive])
return np.array(dataX), np.array(dataY)
data_X, data_Y = optimize_dataset(dataset)
获得数据后,需要将数据划分为训练集和测试集。这里取数据的百分之七十作为训练集,剩下的百分之三十作为测试集。
train_size = int(len(data_X) * 0.7)
test_size = len(data_X) - train_size
train_X = data_X[:train_size]
train_Y = data_Y[:train_size]
test_X = data_X[train_size:]
test_Y = data_Y[train_size:]
4、类型转换
获得训练集和测试集后,为符合训练需求,需要修改其数据格式。并将数据转换为tensor类型。
train_X = train_X.reshape(-1, 1, 3)
train_Y = train_Y.reshape(-1, 1, 1)
test_X = test_X.reshape(-1, 1, 3)
train_x = torch.from_numpy(train_X)
train_y = torch.from_numpy(train_Y)
test_x = torch.from_numpy(test_X)
二、数据模型
1.定义RNN模型
这里定义的RNN模型由pytorch自带的rnn函数和全连接层组成。
class rnn_net(nn.Module):
def __init__(self, channels_in, channels_hidden, channels_out=1):
super(rnn_net, self).__init__()
self.rnn = nn.RNN(channels_in, channels_hidden)
self.connect = nn.Linear(channels_hidden, channels_out)
def forward(self, x):
x, _ = self.rnn(x)
a, b, c = x.shape
x = x.view(a * b, c)
x = self.connect(x)
x = x.view(a, b, -1)
return x
2.定义损失函数和优化函数
定义计算均方误差损失函数;定义Adam优化器,学习率设定为0.01。
loss_f = nn.MSELoss()
optimizer = torch.optim.Adam(forecast_net.parameters(), lr=1e-2)
三、模型训练
1、实例化模型
这里实例化了一个输入为3个数据,隐藏层为6层的RNN模型。
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print("device=", device)
forecast_net = rnn_net(3, 6).to(device)
注:
为节省时间,本次采用GPU进行训练。如果想知道如何采用GPU进行训练,可以查看第六回内容。
2、模型训练
进行1000次迭代训练,代码如下:
for k in range(1000):
train_x = train_x.to(device)
train_y = train_y.to(device)
out = forecast_net(train_x)
loss = loss_f(out, train_y).to(device)
optimizer.zero_grad()
loss.backward()
optimizer.step()
time_consume = time.time() - time1
if (k + 1) % 100 == 0: #
print('Epoch: {}, Loss: {:.5f},consume time:{:.3f}s'.format(k + 1, loss, time_consume))
3、输出展示
Epoch:100, Loss:0.00024, consume time:2.022s
Epoch:200, Loss:0.00013, consume time:3.585s
Epoch:300, Loss:0.00010, consume time:5.172s
Epoch:400, Loss:0.00010, consume time:6.816s
Epoch:500, Loss:0.00009, consume time:8.384s
Epoch:600, Loss:0.00009, consume time:9.932s
Epoch:700, Loss:0.00008, consume time:11.494s
Epoch:800, Loss:0.00008, consume time:13.055s
Epoch:900, Loss:0.00008, consume time:14.618s
Epoch:1000, Loss:0.00008, consume time:16.165s
从输出结果可以看出,训练集的训练精度较高。
4、预测收盘价格
接着使用训练好的模型预测股票的收盘价格。
forecast_net = forecast_net.eval()
data_X = data_X.reshape(-1, 1, 3)
data_X = torch.from_numpy(data_X)
pred_data = data_X.to(device)
y_pred= forecast_net(pred_data).to("cpu")
y_pred = y_pred.view(-1).data.numpy()
plt.figure("股票数据预测")
plt.plot(y_pred, 'r', label='forecast data')
plt.plot(dataset, 'g', label='real data')
plt.legend(loc='best')
plt.show()
生成股票收盘预测趋势与实际收盘趋势的对比图,对比图如下所示:
从上图可以看出:RNN模型在此数据集的应用较好,预测结果与实际结果重合度较高。
总结
1)数据准备:准备收盘趋势的训练集和预测集;
2)模型准备:定义RNN模型、损失函数和优化器;
3)数据训练:实例化模型并训练,并生成股票收盘趋势与实际收盘趋势的对比图。
更多推荐
所有评论(0)