Help me with RNN time sequence please

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()