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