RNN:保留上一个输入的学习状态,输出不仅与当前输入有关,还与学习状态有关
import torch
from torch import nn
import numpy as np
import matplotlib.pyplot as plt
# torch.manual_seed(1) # reproducible
# Hyper Parameters
TIME_STEP = 10 # rnn time step;时间点
INPUT_SIZE = 1 # rnn input size;每个时间点输入数据数量
LR = 0.02 # learning rate
# show data,这里的数据仅仅是用来画图展示sin和cos图像的,与RNN的输入数据无关
# steps = np.linspace(0, np.pi * 2, 100, dtype=np.float32) # float32 for converting torch FloatTensor
# x_np = np.sin(steps)
# y_np = np.cos(steps)
# plt.figure(num='图像一')
# plt.plot(steps, y_np, 'r-', label='target (cos)')
# plt.plot(steps, x_np, 'b-', label='input (sin)')
# plt.legend(loc='best')
#同时显示两个图像需要使用figure
#构建网络
class RNN(nn.Module):
def __init__(self):
super(RNN, self).__init__()
self.rnn = nn.RNN(
input_size=INPUT_SIZE,
hidden_size=32, # rnn hidden unit
num_layers=1, # number of rnn layer
batch_first=True, # input & output will has batch size as 1s dimension. e.g. (batch, time_step, input_size)
)
#batch_first 默认为Flase,即在RNN中batch_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, hidden_size)
r_out, h_state = self.rnn(x, h_state)
#print(r_out[0].size()) #torch.Size([10,32])
#每一个batch是一个10*32的矩阵
###############
#这里的r_out是rnn出来的输出,size为(1,10,32)
#需要把每一个time_step的r_out送到self.out中全连接
outs = [] # save all predictions
for time_step in range(r_out.size(1)): # calculate output for each time step
outs.append(self.out(r_out[:, time_step, :]))
return torch.stack(outs, dim=1), h_state
#将outs在新的维度上叠加,并且把这个新的维度作为第2维
# instead, for simplicity, you can replace above codes by follows
# r_out = r_out.view(-1, 32)
# outs = self.out(r_out)
# outs = outs.view(-1, TIME_STEP, 1)
# return outs, h_state
# or even simpler, since nn.Linear can accept inputs of any dimension
# and returns outputs with same dimension except for the last
# outs = self.out(r_out)
# return outs
#############
rnn = RNN()
print(rnn)
optimizer = torch.optim.Adam(rnn.parameters(), lr=LR) # optimize all cnn parameters
loss_func = nn.MSELoss()
h_state = None # for initial hidden state
plt.figure(num='图像二', figsize=(12, 5))
plt.ion() # continuously plot
for step in range(100):
start, end = step * np.pi, (step + 1) * np.pi # time range
# use sin predicts cos
steps = np.linspace(start, end, TIME_STEP, dtype=np.float32,
endpoint=False) # float32 for converting torch FloatTensor
#从0-100pi,每个pi间隔取10个点,共1000个数据点
#计算函数值
x_np = np.sin(steps)
y_np = np.cos(steps)
#将函数值包装成RNN输入数据的size(batch, time_step, input_size)
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])
#print(y.size())
prediction, h_state = rnn(x, h_state) # rnn output
#print(prediction)
#这里的prediction是经过全连接之后的输出,size为[1,10,1]
# !! next step is important !!
h_state = h_state.data # repack the hidden state, break the connection from last iteration
loss = loss_func(prediction, y) # calculate loss;训练X数据,预测Y值
optimizer.zero_grad() # clear gradients for this training step
loss.backward() # backpropagation, compute gradients
optimizer.step() # apply gradients
# plotting
plt.plot(steps, y_np.flatten(), 'r-') #y的真实值
plt.plot(steps, prediction.data.numpy().flatten(), 'b-') #y的预测值
plt.draw();
plt.pause(0.05)
plt.ioff()
plt.show()
原程序来自:
https://github.com/MorvanZhou/PyTorch-Tutorial