Hi all. I am newbie at ML. Trying to predict noisy sin function. Dataset is just x, y coordinates. I split data into SEQUNCE_LENGTH sequences and trying to learn with GRU, but something is totally wrong. Maybe some parameters are wrong, or forward pass should be implemented some other way. I don’t know what to try.
Here is original inpit, loss function and predicted result.
Code:
import numpy as np
import torch
import torch.nn as nn
import matplotlib.pyplot as plt
INPUT_SIZE = 1
SEQUENCE_SIZE = 200
BATCH_SIZE = 1
HIDDEN_SIZE = 30
NUM_LAYERS = 2
N_EPOCHS = 20
class MyRNN(nn.Module):
def __init__(self):
super(MyRNN, self).__init__()
self.hidden_size = HIDDEN_SIZE
self.l1 = nn.GRU(INPUT_SIZE, HIDDEN_SIZE, NUM_LAYERS)
self.l2 = nn.Linear(HIDDEN_SIZE, 1)
self.hidden = None
def forward(self, inputs):
out, hidden = self.l1(inputs, self.hidden)
self.hidden = hidden.detach() # reuse hidden
out = self.l2(out.squeeze(1))
return out, hidden
x, y = np.loadtxt('series.txt', np.float32, '#', ',', unpack=True)
sequence = []
target = []
model = MyRNN()
criterion = torch.nn.MSELoss()
optimizer = torch.optim.SGD(model.parameters(), lr=0.0001, momentum=0.5)
lossValues = [] # for plotting
model.train()
for epoch in range(N_EPOCHS):
for idx, xCoord in enumerate(x):
if idx % SEQUENCE_SIZE == 0 and idx != 0:
# perform learning on a sequence of SEQUENCE_SIZE elements
xTensor = torch.tensor(sequence, dtype=torch.float32, requires_grad=True)
xTensor = xTensor.unsqueeze(dim=1) # batch size = 1
xTensor = xTensor.unsqueeze(dim=1) # input size = 1
yTensor = torch.tensor(target, dtype=torch.float32)
# reset buffers
sequence = []
target = []
# forward pass
optimizer.zero_grad()
out, hidden = model(xTensor)
loss = criterion(out.squeeze(dim=1), yTensor)
loss.backward()
optimizer.step()
lossValues.append(loss.item())
print(loss.item())
sequence.append(xCoord) # buffer x values
target.append(y[idx]) # buffer y values
# plot after training
model.eval()
sequence = []
xTensor = torch.tensor(x, dtype=torch.float32)
xTensor = xTensor.unsqueeze(dim=1)
xTensor = xTensor.unsqueeze(dim=1)
out, hidden = model(xTensor)
out = out.squeeze(dim=1)
plt.plot(out.detach().numpy())
plt.show()
# plt.plot(lossValues)
# plt.show()