"""
View more, visit my tutorial page: https://morvanzhou.github.io/tutorials/
My Youtube Channel: https://www.youtube.com/user/MorvanZhou
Dependencies:
torch: 0.4
matplotlib
numpy
"""
from torchsummary import summary
from torchviz import make_dot
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
# 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.plot(steps, y_np, 'r-', label='target (cos)')
# plt.plot(steps, x_np, 'b-', label='input (sin)')
# plt.legend(loc='best')
# plt.show()
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)
)
self.out = nn.Linear(32, 1)
def forward(self, x, h_state): # 因为 hidden state 是连续的, 所以我们要一直传递这一个 state
# x (batch, time_step, input_size)
# h_state (n_layers, batch, hidden_size)
# r_out (batch, time_step, hidden_size) 1*10*32
# 在rnn分类中 是批量放入28条数据 每一条输出的h_n,h_c自动传入下一条,自动了27次,最后一次输出了
# 但在回归问题中 每个batch数据需要有之前的数据,所以上一个batch的h_state显式传给了下个batch
# 一个batch内的h_state是隐式传递的 batch间的h_state是显式传递的
r_out, h_state = self.rnn(x, h_state)
print(torch._shape_as_tensor(r_out)) #tensor([ 1, 10, 32])
outs = [] # save all predictions
for time_step in range(r_out.size(1)): # calculate output for each time step 从1到10(TIME_STEP)
outs.append(self.out(r_out[:, time_step, :]))
#r_out 为1*10*32,r_out[:, time_step, :]为1*1*32,过全连接得到1*1*1 TIME_STEP个append之后
# 相比上一个回归中的输出 这里outs存储的是每一个时间步的输出
# print(len(outs)) #为10
return torch.stack(outs, dim=1), h_state #从10*1*1变为1*10*1
# torch.Size([1, 10, 1]) time_step
# 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(1, figsize=(12, 5))
plt.ion() # continuously plot
for step in range(85):
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
x_np = np.sin(steps)
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 output
#print(prediction.size())
# !! next step is important !!
# !! 下一步十分重要 !!
h_state = h_state.data # 要把 h_state 重新包装一下才能放入下一个 iteration, 不然会报错
loss = loss_func(prediction, y) # calculate loss
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-')
plt.plot(steps, prediction.data.numpy().flatten(), 'b-')
plt.draw();
plt.pause(0.05)
#summary(rnn, input_size=(1,10,1)) # input_size=(channels, H, W)
# 可视化网络2
vis_graph = make_dot(prediction, params=dict(rnn.named_parameters()))
vis_graph.view()
plt.ioff()
plt.show()
RNN_Regression
最新推荐文章于 2023-11-07 14:57:06 发布