Function prediction of GRU

43 views Asked by At

I have a question about the code I found on the internet, I hope you can help me When I create a function to predict the values ​​that are in x_test, I get values ​​other than those obtained from : lstm_predictions = model(x_test.to(device)). thanks

import torch
import torchvision
import torchvision.transforms as transforms
import pandas as pd
import torch.optim as optim
import numpy as np
import torch.nn as nn 
import torch.nn.functional as F 
import matplotlib.pyplot as plt
import operator
from datetime import datetime
import yfinance as yf

def split_data(stock, lookback):
    data_raw = stock.to_numpy() 
    data = []
    
    # create all possible sequences of length seq_len
    for index in range(len(data_raw) - lookback): 
        data.append(data_raw[index: index + lookback])
    
    data = np.array(data)
    test_set_size = int(np.round(0.2*data.shape[0]))
    train_set_size = data.shape[0] - (test_set_size)
    
    x_train = data[:train_set_size,:-1,:]
    y_train = data[:train_set_size,-1,:]
    
    x_test = data[train_set_size:,:-1]
    y_test = data[train_set_size:,-1,:]
    
    return [x_train, y_train, x_test, y_test]

def string_to_time(date):
    
    date = datetime.strptime(date, '%Y-%m-%d')
    date = datetime.timestamp(date)
    return date 

def normalize(x, min, max):
    return (x - min)/(max - min)

def reverse_normalize(y, min, max):
    return y*(max - min) + min

def min_max_dic(dataset):
    dic = {}
    for col in dataset.columns:
        dic[col] = [dataset[col].min(), dataset[col].max()]
        dataset[col] = dataset[col].apply(lambda x: normalize(x, dic[col][0], dic[col][1]))
    return dic





class GRU(nn.Module):
    def __init__(self, input_size, hidden_dim, num_layers, output_dim):
        super(GRU, self).__init__()

        self.lstm = nn.GRU(input_size, hidden_dim, num_layers)
        self.linear = nn.Linear(hidden_dim, output_dim)

    def forward(self, x):
        output, _ = self.lstm(x)
        output = output[:,-1,:]
        output = self.linear(output)
        return output




device = 'cuda' if torch.cuda.is_available() else 'cpu'
#stocks dataset for Altaba Inc


stock_dataset = yf.download("SPY",auto_adjust=True).tail(3000)





min_max_dictionary = min_max_dic(stock_dataset)

stock_value = stock_dataset[['Close']]

x_train, y_train, x_test, y_test = split_data(stock_value, 20)

x_train = torch.from_numpy(x_train).float()
y_train = torch.from_numpy(y_train).float()
x_test = torch.from_numpy(x_test).float()
y_test = torch.from_numpy(y_test).float()

input_size = 1
hidden_dim = 64
num_layers = 3
output_dim = 1
epochs = 400

model = GRU(input_size, hidden_dim, num_layers, output_dim).to(device)
loss_func = nn.MSELoss(reduction='mean').to(device)
optimizer = optim.Adam(model.parameters(), lr=0.001)


train_loss = []
min_loss = np.Inf

for epoch in range(epochs):
    #zero out gradients
    optimizer.zero_grad()

    pred = model(x_train.to(device))
    loss = loss_func(pred, y_train.to(device))
    train_loss.append(loss.item())
    print('Epoch {},    Loss: {:.10f}\n'.format(epoch, loss.item()))
    
    #keep track of lowest loss and save as best model
    if loss.item() < min_loss:
        print('     New Minimum Loss: {:.10f} ----> {:.10f}\n'.format(min_loss, loss.item()))
        min_loss = loss.item()
        torch.save(model.state_dict(), 'best_model.pt')

    #back propogate
    loss.backward()
    optimizer.step()
    
    
    
best_model = GRU(input_size, hidden_dim, num_layers, output_dim).to(device)
best_model.load_state_dict(torch.load('best_model.pt'))
    
lstm_predictions = model(x_test.to(device))
test_loss = loss_func(lstm_predictions, y_test.to(device))
lstm_predictions = lstm_predictions.squeeze().tolist()


min = min_max_dictionary['Close'][0]
max = min_max_dictionary['Close'][1]

lstm_predictions = [reverse_normalize(x, min, max) for x in np.array(lstm_predictions)]

stock_value = [reverse_normalize(x, min, max) for x in np.array(stock_value)]

plt.figure(figsize=(12, 6))
plt.plot([i for i in range(x_train.size(0))], stock_value[:x_train.size(0)], color='b', label='trained values')

#plot test range and predictions by the GRU
time_values_actual = list(range(x_train.size(0), len(stock_value)))
time_values_pred = list(range(x_train.size(0), x_train.size(0) + y_test.size(0)))
plt.xlabel('Time')
plt.ylabel('Stock Values')
plt.plot(time_values_actual, stock_value[-len(time_values_actual):], color='r', label='actual values')
plt.plot(time_values_pred[3:], lstm_predictions[3:], color='g', linewidth=2, label='predicted values')

plt.show()

The function I use to manually predict is:

for i in range(plot_range):
    a= stock_value[-(19+i):]
    
    a=a.head(19)
    print(a)
    with torch.no_grad():
        b = best_model(torch.tensor(a.values).reshape((-1,19,1)).float())
    #b=reverse_normalize(b.squeeze().tolist(), min, max)
    predictions.append(b)

I expected both predictions to be similar but they were different

0

There are 0 answers