Hi everyone,
I’d like to predict if stock price increse or not with time series stock features ,which I think is a 2 class classfication task.
But i found that no matter how i change my hyper param,the loss won’t decrease and the accuracy won’t increase. Plz help me figure out where is my problem.
Here is my code
And dataset like this
import torch
import torch.nn as nn
import torch.nn.functional as F
import pandas as pd
import numpy as np
import os
from sklearn.preprocessing import MinMaxScaler
DATA_DIR = '~/Train/Train_data'
METAL = 'LMECopper3M' #LMECopper3M,LMELead3M,LMENickle3M,LMETin3M,LMEZinc3M,LMEAluminium3M
PERIOD = '60d' #1d,20d,60d
VAL_LENGTH = 100
TIME_STEP = 100
HIDDEN_SIZE = 10
NUM_LAYERS = 2
TRAIN_EPOCH = 100
LR = 0.3
#train
def dataset():
files = os.listdir(DATA_DIR)
for file in files:
if file.startswith(METAL):
feature_all = pd.read_csv(os.path.join(DATA_DIR,file)).fillna(value=0)
if file.startswith('Label_' + METAL[:-2]) and file.endswith(PERIOD + '.csv'):
label_all = pd.read_csv(os.path.join(DATA_DIR,file))
feature = feature_all.iloc[:,2:].values
label = label_all.iloc[:,2].values
#feature scaling
sc = MinMaxScaler(feature_range = (0, 1))
feature = sc.fit_transform(feature)
#60 timesteps
feature_timesteps = []
label_timesteps = []
for i in range(TIME_STEP,len(feature_all)):
feature_timesteps.append(feature[i-TIME_STEP:i])
label_timesteps.append(label[i])
feature_timesteps,label_timesteps = torch.from_numpy(np.array(feature_timesteps)).transpose(1,2),torch.from_numpy(np.array(label_timesteps))
return feature_timesteps,label_timesteps
#model
class LSTM(nn.Module):
def __init__(self,input_size=60,hidden_size=100,num_layers=2,feature_dim=5,batch_first=True,class_dim=2):
super(LSTM,self).__init__()
self.lstm = nn.LSTM(input_size,hidden_size,num_layers,batch_first)
#self.fc = nn.Linear(feature_dim*hidden_size,class_dim)
self.fc = nn.Linear(hidden_size,class_dim)
def forward(self,train_dataset,hidden_state):
lstm_out,hidden_state = self.lstm(train_dataset,hidden_state)
hidden_size = hidden_state[-1].size(-1)
feature_dim = train_dataset[-1].size(0)
#lstm_out = lstm_out.reshape(-1,feature_dim*hidden_size)
lstm_out = self.fc(lstm_out[:,-1,:])
return lstm_out,hidden_state
def train(model,feature_timesteps,label_timesteps,optimizer,criterion,device):
model.train()
#hidden_state = (torch.zeros(2,5,100).to(device),torch.zeros(2,5,100).to(device))
hidden_state = None
for epoch in range(TRAIN_EPOCH):
optimizer.zero_grad()
feature_timesteps,label_timesteps = feature_timesteps.to(device).float(),label_timesteps.to(device).long()
out,hidden_state = model(feature_timesteps,hidden_state)
loss = criterion(out,label_timesteps)
loss.backward(retain_graph=True)
optimizer.step()
print('epoch {}, loss {}'.format(epoch,loss.item()))
##accuracy
correct = torch.zeros(1).squeeze().to(device)
total = torch.zeros(1).squeeze().cuda()
pred = torch.argmax(out,1)
correct += (pred == label_timesteps).sum().float()
total += len(label_timesteps)
print('Accuracy: %f'%((correct/total).cpu().detach().data.numpy()))
#for name, parms in model.named_parameters():
# print('-->name:', name, '-->grad_requirs:', parms.requires_grad, '--weight', torch.mean(parms.data), ' -->grad_value:', torch.mean(parms.grad))
def main():
feature_timesteps,label_timesteps = dataset()
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = LSTM(input_size=TIME_STEP,hidden_size=HIDDEN_SIZE,num_layers=NUM_LAYERS)
model.to(device)
optimizer = torch.optim.Adam(model.parameters(), lr=LR,weight_decay=5e-4)
criterion = nn.CrossEntropyLoss()
train(model,feature_timesteps,label_timesteps,optimizer,criterion,device)
if __name__ == '__main__':
main()