第九章(1):循环神经网络与pytorch示例(RNN实现股价预测)
作者:安静到无声 个人主页
作者简介:人工智能和硬件设计博士生、CSDN与阿里云开发者博客专家,多项比赛获奖者,发表SCI论文多篇。
Thanks♪(・ω・)ノ 如果觉得文章不错或能帮助到你学习,可以点赞👍收藏📁评论📒+关注哦! o( ̄▽ ̄)d
欢迎大家来到安静到无声的 《基于pytorch的自然语言处理入门与实践》,如果对所写内容感兴趣请看《基于pytorch的自然语言处理入门与实践》系列讲解 - 总目录,同时这也可以作为大家学习的参考。欢迎订阅,请多多支持!
目录标题
- 第九章(1):循环神经网络与pytorch示例(RNN实现股价预测)
- 1. 概述
- 2. 简单的循环神经网络
- 3. RNN实现股价预测
- 参考
1. 概述
循环神经网络(Recurrent Neural Network,RNN)是一种基于神经网络的机器学习模型,主要用于处理序列数据。与传统的前馈神经网络不同,RNN引入了循环连接,使得模型能够捕捉到输入序列中的上下文信息和时间依赖关系。
假设给定一个序列,
x
1
:
T
=
(
x
1
,
x
2
,
…
,
x
t
,
…
,
x
T
)
x_{1:T}=(x_{1},x_{2},\ldots,x_{t},\ldots,x_{T})
x1:T=(x1,x2,…,xt,…,xT),RNN神经网络通过下面公式更新带反馈边的隐藏层的活性值
h
t
h_t
ht。
h
t
=
f
(
h
t
−
1
,
x
t
)
,
\boldsymbol{h}_{t}=f(\boldsymbol{h}_{t-1},\boldsymbol{x}_{t}),
ht=f(ht−1,xt),
其中 h 0 = 0 {}_{\boldsymbol{h}_{0}=0} h0=0, f ( ⋅ ) f(\cdot) f(⋅)为一个非线性的函数,例如前馈神经网络。
下图给出了循环神经网络的示例,其中“延时器”为一个虚拟单元,记录神经元的最近一次或几次活性值。
从数学上讲,上文公式可以看成一个动力系统。隐藏层的活性值 h t h_t ht,在很多文献上也称为状态( State ) 或隐状态( Hidden State )。
2. 简单的循环神经网络
简单循环网络( Simple Recurrent Network,SRN)是一个非常简单的循环神经网络,只有一个隐藏层的神经网络. 在一个两层的前馈神经网络中,连接存在相邻的层与层之间,隐藏层的节点之间是无连接的。而简单循环网络增加了从隐藏层到隐藏层的反馈连接。
向量
x
t
∈
R
M
{\boldsymbol{x}}_{t}\in\mathbb{R}^{M}
xt∈RM表示在
t
t
t时刻的一个输入,
h
t
∈
R
D
h_t\in\mathbb{R}^D
ht∈RD表示一个隐藏层的状态,这时
h
t
h_t
ht与当前时刻的
x
t
x_t
xt有关系,而且也和上一时刻的
h
t
−
1
h_{t-1}
ht−1有关系,简单的循环神经网络在
t
t
t时刻的更新公式如下所示:
z
t
=
U
h
t
−
1
+
W
x
t
+
b
z_{t}=U\boldsymbol{h}_{t-1}+Wx_{t}+\boldsymbol{b}
zt=Uht−1+Wxt+b
h
t
=
f
(
z
t
)
h_t=f(\boldsymbol{z}_t)
ht=f(zt)其中
z
t
z_{t}
zt为隐藏层的净输入,
U
∈
R
D
×
D
U\in\mathbb{R}^{D\times D}
U∈RD×D为状态-状态的矩阵,
W
∈
R
D
×
M
W\in\mathbb{R}^{D\times M}
W∈RD×M为状态-输入的权重矩阵,
b
∈
R
D
b\in\mathbb{R}^{D}
b∈RD为偏置项,
f
(
⋅
)
f(\cdot)
f(⋅)为一个非线性的激活函数。上述公式可以和写为:
h
t
=
f
(
U
h
t
−
1
+
W
x
t
+
b
)
.
\boldsymbol{h}_{t}=f(\boldsymbol{Uh}_{t-1}+\boldsymbol{W}\boldsymbol{x}_{t}+\boldsymbol{b}).
ht=f(Uht−1+Wxt+b).
如果我们把每个时刻的状态都看作前馈神经网络的一层,循环神经网络可以看作在时间维度上权值共享的神经网络。下给出了按时间展开的循环神经网络。
3. RNN实现股价预测
建立RNN基于zgpa train.csv数据,建立RNN模型,预测股价。
- 完成数据预处理,将序列数据转化为可用子RNN输入的数据
- 对新数据zgpa_test.csv进行预测,可视化结果
模型结构:RNN 输出有120个神经元,每次使用前8个数据预测第9个数据。
import pandas as pd
import numpy as np
data = pd.read_csv(r'./zgpa_train.csv')
data.head()
price = data.loc[:,'close']
price.head()
0 28.78
1 29.23
2 29.26
3 28.50
4 28.67
Name: close, dtype: float64
#归一化处理
price_norm = price/max(price)
%matplotlib inline
from matplotlib import pyplot as plt
fig1 = plt.figure(figsize=(8,5))
plt.plot(price)
plt.title('close price')
plt.xlabel('time')
plt.ylabel('price')
plt.show()
#define X and y
#define method to extract X and y
def extract_data(data,time_step):
X = []
y = []
#0,1,2,3...9:10个样本;time_step=8;0,1...7;1,2...8;2,3...9三组(两组样本)
for i in range(len(data)-time_step):
X.append([a for a in data[i:i+time_step]])
y.append(data[i+time_step])
X = np.array(X)
X = X.reshape(X.shape[0],X.shape[1],1)
return X, y
time_step = 8
X,y = extract_data(price_norm,time_step)
# 转换为Tensor
import torch
input_data = torch.tensor(X, dtype=torch.float32)
target_data = torch.tensor(y, dtype=torch.float32).unsqueeze(-1)
# 定义RNN模型
import torch.nn as nn
class RNN(nn.Module):
def __init__(self, input_size, hidden_size, output_size): #分别是输入,隐藏和输出的维度
super(RNN, self).__init__()
self.hidden_size = hidden_size
self.rnn = nn.RNN(input_size, hidden_size, batch_first=True)
self.fc = nn.Linear(hidden_size, output_size)
def forward(self, x):
out, _ = self.rnn(x)
out = self.fc(out[:, -1, :])
return out
input_size = 1
hidden_size = 120
output_size = 1
# 创建模型实例
rnn = RNN(input_size, hidden_size, output_size)
criterion = nn.MSELoss()
optimizer = torch.optim.Adam(rnn.parameters(), lr=0.01)
# 训练模型
num_epochs = 1000
for epoch in range(num_epochs):
outputs = rnn(input_data)
loss = criterion(outputs, target_data)
optimizer.zero_grad()
loss.backward()
optimizer.step()
if (epoch+1) % 100 == 0:
print(f"Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.10f}")
Epoch [100/1000], Loss: 0.0004473718
Epoch [200/1000], Loss: 0.0006229825
Epoch [300/1000], Loss: 0.0003415935
Epoch [400/1000], Loss: 0.0002980608
Epoch [500/1000], Loss: 0.0002818418
Epoch [600/1000], Loss: 0.0002672504
Epoch [700/1000], Loss: 0.0002543367
Epoch [800/1000], Loss: 0.0002437856
Epoch [900/1000], Loss: 0.0002345658
Epoch [1000/1000], Loss: 0.0002437943
predict = rnn(input_data)
predict_out = []
for i in predict:
predict_out.append(i)
fig2 = plt.figure(figsize=(8,5))
plt.plot(y,label='real price')
plt.plot(predict_out,label='predict price')
plt.title('close price')
plt.xlabel('time')
plt.ylabel('price')
plt.legend()
plt.show()
--------推荐专栏--------
🔥 手把手实现Image captioning
💯CNN模型压缩
💖模式识别与人工智能(程序与算法)
🔥FPGA—Verilog与Hls学习与实践
💯基于Pytorch的自然语言处理入门与实践
参考
邱锡鹏,神经网络与深度学习,机械工业出版社,https://nndl.github.io/, 2020.