Initial commit
This commit is contained in:
106
501_why_torch_dynamic_graph.py
Normal file
106
501_why_torch_dynamic_graph.py
Normal file
@ -0,0 +1,106 @@
|
||||
"""
|
||||
Know more, visit 莫烦Python: https://morvanzhou.github.io/tutorials/
|
||||
My Youtube Channel: https://www.youtube.com/user/MorvanZhou
|
||||
|
||||
Dependencies:
|
||||
torch: 0.1.11
|
||||
matplotlib
|
||||
numpy
|
||||
"""
|
||||
import torch
|
||||
from torch import nn
|
||||
from torch.autograd import Variable
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
torch.manual_seed(1) # reproducible
|
||||
|
||||
# Hyper Parameters
|
||||
BATCH_SIZE = 64
|
||||
TIME_STEP = 5 # rnn time step / image height
|
||||
INPUT_SIZE = 1 # rnn input size / image width
|
||||
LR = 0.02 # learning rate
|
||||
DOWNLOAD_MNIST = False # set to True if haven't download the data
|
||||
|
||||
|
||||
class RNN(nn.Module):
|
||||
def __init__(self):
|
||||
super(RNN, self).__init__()
|
||||
|
||||
self.rnn = nn.RNN(
|
||||
input_size=1,
|
||||
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):
|
||||
# x (batch, time_step, input_size)
|
||||
# h_state (n_layers, batch, hidden_size)
|
||||
# r_out (batch, time_step, output_size)
|
||||
r_out, h_state = self.rnn(x, h_state)
|
||||
|
||||
outs = [] # this is where you can find torch is dynamic
|
||||
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
|
||||
|
||||
|
||||
rnn = RNN()
|
||||
print(rnn)
|
||||
|
||||
optimizer = torch.optim.Adam(rnn.parameters(), lr=LR) # optimize all cnn parameters
|
||||
loss_func = nn.MSELoss() # the target label is not one-hotted
|
||||
|
||||
h_state = None # for initial hidden state
|
||||
|
||||
plt.figure(1, figsize=(12, 5))
|
||||
plt.ion() # continuously plot
|
||||
plt.show()
|
||||
|
||||
######################## Below is different #########################
|
||||
|
||||
################ static time steps ##########
|
||||
# for step in range(60):
|
||||
# start, end = step * np.pi, (step+1)*np.pi # time steps
|
||||
# # use sin predicts cos
|
||||
# steps = np.linspace(start, end, 10, dtype=np.float32)
|
||||
|
||||
################ dynamic time steps #########
|
||||
step = 0
|
||||
for i in range(60):
|
||||
dynamic_steps = np.random.randint(1, 4) # has random time steps
|
||||
start, end = step * np.pi, (step + dynamic_steps) * np.pi # different time steps length
|
||||
step += dynamic_steps
|
||||
|
||||
# use sin predicts cos
|
||||
steps = np.linspace(start, end, 10 * dynamic_steps, dtype=np.float32)
|
||||
|
||||
####################### Above is different ###########################
|
||||
|
||||
print(len(steps)) # print how many time step feed to RNN
|
||||
|
||||
x_np = np.sin(steps) # float32 for converting torch FloatTensor
|
||||
y_np = np.cos(steps)
|
||||
|
||||
x = Variable(torch.from_numpy(x_np[np.newaxis, :, np.newaxis])) # shape (batch, time_step, input_size)
|
||||
y = Variable(torch.from_numpy(y_np[np.newaxis, :, np.newaxis]))
|
||||
|
||||
prediction, h_state = rnn(x, h_state) # rnn output
|
||||
# !! next step is important !!
|
||||
h_state = Variable(h_state.data) # repack the hidden state, break the connection from last iteration
|
||||
|
||||
loss = loss_func(prediction, y) # cross entropy 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)
|
||||
|
||||
plt.ioff()
|
||||
plt.show()
|
||||
Reference in New Issue
Block a user