Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
PyTorch RNN training example
import torch
import torch.nn as nn
from torch.nn import functional as F
from torch.autograd import Variable
from torch import optim
import numpy as np
import math, random
# Generating a noisy multi-sin wave
def sine_2(X, signal_freq=60.):
return (np.sin(2 * np.pi * (X) / signal_freq) + np.sin(4 * np.pi * (X) / signal_freq)) / 2.0
def noisy(Y, noise_range=(-0.05, 0.05)):
noise = np.random.uniform(noise_range[0], noise_range[1], size=Y.shape)
return Y + noise
def sample(sample_size):
random_offset = random.randint(0, sample_size)
X = np.arange(sample_size)
Y = noisy(sine_2(X + random_offset))
return Y
# Define the model
class SimpleRNN(nn.Module):
def __init__(self, hidden_size):
super(SimpleRNN, self).__init__()
self.hidden_size = hidden_size
self.inp = nn.Linear(1, hidden_size)
self.rnn = nn.LSTM(hidden_size, hidden_size, 2, dropout=0.05)
self.out = nn.Linear(hidden_size, 1)
def step(self, input, hidden=None):
input = self.inp(input.view(1, -1)).unsqueeze(1)
output, hidden = self.rnn(input, hidden)
output = self.out(output.squeeze(1))
return output, hidden
def forward(self, inputs, hidden=None, force=True, steps=0):
if force or steps == 0: steps = len(inputs)
outputs = Variable(torch.zeros(steps, 1, 1))
for i in range(steps):
if force or i == 0:
input = inputs[i]
else:
input = output
output, hidden = self.step(input, hidden)
outputs[i] = output
return outputs, hidden
n_epochs = 100
n_iters = 50
hidden_size = 10
model = SimpleRNN(hidden_size)
criterion = nn.MSELoss()
optimizer = optim.SGD(model.parameters(), lr=0.01)
losses = np.zeros(n_epochs) # For plotting
for epoch in range(n_epochs):
for iter in range(n_iters):
_inputs = sample(50)
inputs = Variable(torch.from_numpy(_inputs[:-1]).float())
targets = Variable(torch.from_numpy(_inputs[1:]).float())
# Use teacher forcing 50% of the time
force = random.random() < 0.5
outputs, hidden = model(inputs, None, force)
optimizer.zero_grad()
loss = criterion(outputs, targets)
loss.backward()
optimizer.step()
losses[epoch] += loss.data[0]
if epoch > 0:
print(epoch, loss.data[0])
# Use some plotting library
# if epoch % 10 == 0:
# show_plot('inputs', _inputs, True)
# show_plot('outputs', outputs.data.view(-1), True)
# show_plot('losses', losses[:epoch] / n_iters)
# Generate a test
# outputs, hidden = model(inputs, False, 50)
# show_plot('generated', outputs.data.view(-1), True)
# Online training
hidden = None
while True:
inputs = get_latest_sample()
outputs, hidden = model(inputs, hidden)
optimizer.zero_grad()
loss = criterion(outputs, inputs)
loss.backward()
optimizer.step()
@marianophielipp

This comment has been minimized.

Copy link

marianophielipp commented Aug 29, 2018

---> 75 loss = criterion(outputs, targets)
RuntimeError: input and target shapes do not match: input [49 x 1 x 1], target [49] at /Users/soumith/code/builder/wheel/pytorch-src/aten/src/THNN/generic/MSECriterion.c:12

@marianophielipp

This comment has been minimized.

Copy link

marianophielipp commented Aug 29, 2018

loss = criterion(torch.squeeze(outputs), targets)
Pytorch version 0.4.1

@ishan00

This comment has been minimized.

Copy link

ishan00 commented Oct 9, 2018

Shouldn't it be outputs, hidden = model.forward(inputs, None, force) instead of outputs, hidden = model(inputs, None, force) at line 72. Also line 99

@pranav-vempati

This comment has been minimized.

Copy link

pranav-vempati commented Jan 3, 2019

@ishan00 SimpleRNN's forward() method is automatically invoked as SimpleRNN subclasses the nn.Module container. There is no need for an explicit call to forward(), only pass the inputs the model expects.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.