Konkret verwende ich 5-Minuten-Daten aus 24 Jahren mit 19 Merkmale, unterteilt in Blöcke von einer Woche pro Prognose (unter Verwendung von 7 verschiedenen Aktien)
Das Problem, mit dem ich konfrontiert bin, ist die Tatsache, dass das LSTM-Modell, egal was passiert, Werte um eins vorherzusagen scheint spezifischer Wert, um den Verlust immer zu minimieren, der nicht sehr stark abnimmt.
Ich bereite die Eingaben und Ziele in Torch.tensors mit [batch_size, sequence_len, Features] vor (was in meinem Fall [32, 2016, 19]), normalisieren Sie sie zwischen 0 und 1 und geben Sie sie an mein LSTM-Modell weiter, das wie folgt aufgebaut ist:
Code: Select all
class MultiInputOutputLSTM(nn.Module):
def __init__(self, input_size, hidden_size, num_layers, output_size, dropout, lr, batch_size):
super(MultiInputOutputLSTM, self).__init__()
self.input_size = input_size
self.hidden_size = hidden_size
self.num_layers = num_layers
self.dropout = dropout
self.batch_size = batch_size
self.loss_list = []
self.accuracy = 0
self.predictions_list = [0]
self.lstm = nn.LSTM(input_size = self.input_size, hidden_size = self.hidden_size, num_layers = self.num_layers, dropout = self.dropout, batch_first=True)
self.fc = nn.Linear(hidden_size, output_size, bias=True)
self.sigmoid = nn.Sigmoid()
self.criterion = nn.BCEWithLogitsLoss()
self.optimizer = torch.optim.RMSprop(self.parameters(), lr = lr, alpha=0.9, weight_decay=1e-4, momentum=0.5)
self.scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(self.optimizer, 'min')
def forward(self, x):
h0 = torch.zeros(self.num_layers, self.batch_size, self.hidden_size)
c0 = torch.zeros(self.num_layers, self.batch_size, self.hidden_size)
lstm_out, _ = self.lstm(x, (h0, c0))
output = self.fc(lstm_out[:, -1, :])
return output
def train_step(self ,x, y):
self.train()
predictions_1 = torch.round(self.forward(x))
predictions = self.forward(x)
if (predictions_1.detach().cpu().numpy()[0] == y.detach().cpu().numpy()[0]).all():
self.accuracy += 1
self.predictions_list.append(predictions.detach().cpu().numpy()[0][0])
penalty = torch.mean((predictions-0.5)**2)
loss = self.criterion(predictions, y) + penalty
self.scheduler.step(loss)
self.optimizer.zero_grad()
self.loss_list.append(loss.item())
mean_loss = sum(self.loss_list)/len(self.loss_list)
loss.backward()
torch.nn.utils.clip_grad_norm_(self.parameters(), max_norm=6)
self.optimizer.step()
return loss.item(), mean_loss, self.accuracy, predictions.detach().cpu().numpy()[0], y.detach().cpu().numpy()[0]
def test_step(self, inputs, targets):
self.eval()
with torch.no_grad():
outputs = torch.round(self.forward(inputs))
outputs = outputs.detach().cpu().numpy()[0]
targets = targets.detach().cpu().numpy()[0]
if (outputs == targets).all():
accuracy = 1
else:
accuracy = 0
return accuracy, outputs, targets
Die Hyperparameter sind:
Code: Select all
input_size = 19
hidden_size = 3
num_layers = 5
output_size = 2
lr = 0.001
num_epochs = 5
batch_size = 32
dropout = 0.3
Die Zug-Test-Aufteilung beträgt 85-15 %.
Hier ist eine Liste dessen, was ich versucht habe:
Lernrate senken oder erhöhen (von 0,00001 auf 0,1), Ausgabegröße (mit mehr und weniger). Prognosen), Batch_size (von 1 bis 256), num_layers (1-5), Input_size (mit 1, 2, 3... 19 Features), Dropout (0 bis 0,5) und num_epochs (von 1 bis 100).
Ich habe den Adam-Optimierer ausprobiert, dann den SDG- und dann den RMSProp-Optimierer, wobei ich Alpha, Momentum und Weight_Decay geändert habe.
Ich habe auch BCELoss (mit der Sigmoid-Aktivierungsschicht in self.forward()), L1Loss, MSELoss, CrossEntropyLoss ausprobiert, bevor ich mich auf einen Verlust einstellte, der Werte zu nahe bei 0,5 bestraft (das hilft nicht viel, aber hier Punkt, ich werde alles versuchen.
Der mittlere Verlust sinkt von 0,924 auf 0,889.
Die Genauigkeit ist, wie Sie sich vorstellen können, sehr niedrig (von 5,56 % auf 11,67 %): Der einzige Grund, warum er nicht Null ist, ist reines Glück.
Ich versuche auch, das vorherzusagen Unterschied zwischen dem letzten Element der Schlussspalte des Datenrahmens und den zukünftigen nächsten beiden Werten, aber ... mit den gleichen Problemen.
Code: Select all
Ticker - Df - Loss - Mean Loss - Predictions - Targets - Epoch
AAPL 1/120 0.808 0.808 [0.5642182 0.11684255] [1. 1.] 1/50
AAPL 2/120 0.828 0.818 [0.5629723 0.12899561] [1. 1.] 1/50
AAPL 3/120 0.834 0.823 [0.5472506 0.13749745] [1. 1.] 1/50
AAPL 4/120 0.839 0.827 [0.52973044 0.13656825] [0. 0.] 1/50
AAPL 5/120 0.821 0.826 [0.52082217 0.13681749] [0. 0.] 1/50
AAPL 6/120 0.804 0.822 [0.5117941 0.14727135] [1. 1.] 1/50
AAPL 7/120 0.779 0.816 [0.49826628 0.1547919 ] [0. 0.] 1/50
AAPL 8/120 0.845 0.820 [0.49666688 0.1573844 ] [0. 0.] 1/50
…
AAPL 1/120 0.762 0.751 [0.4200741 0.24348469] [1. 1.] 50/50
AAPL 2/120 0.787 0.751 [0.43581426 0.23458275] [1. 1.] 50/50
AAPL 3/120 0.797 0.751 [0.43012726 0.23912352] [1. 1.] 50/50
AAPL 4/120 0.805 0.751 [0.43174705 0.23598525] [0. 0.] 50/50
AAPL 5/120 0.794 0.751 [0.41290796 0.24462458] [0. 0.] 50/50
AAPL 6/120 0.777 0.751 [0.42214283 0.2398287 ] [1. 1.] 50/50
AAPL 7/120 0.747 0.751 [0.42418063 0.24077193] [0. 0.] 50/50
AAPL 8/120 0.822 0.751 [0.44875318 0.23495609] [0. 0.] 50/50
...