use data loader, add evaluation on epoch

This commit is contained in:
Yinon Polak
2023-03-06 16:16:45 +02:00
parent 751b205618
commit b1ac2bf515
5 changed files with 167 additions and 91 deletions

View File

@@ -1,6 +1,5 @@
import logging
from typing import Dict
from typing import Any, Dict, Tuple
import numpy.typing as npt
@@ -8,28 +7,29 @@ import numpy as np
import pandas as pd
import torch
from pandas import DataFrame
from torch.nn import functional as F
from freqtrade.freqai.base_models.BasePytorchModel import BasePytorchModel
from freqtrade.freqai.base_models.PytorchModelTrainer import PytorchModelTrainer
from freqtrade.freqai.data_kitchen import FreqaiDataKitchen
from freqtrade.freqai.prediction_models.PytorchMLPModel import MLP
from freqtrade.freqai.base_models.BasePyTorchModel import BasePyTorchModel
from freqtrade.freqai.base_models.PyTorchModelTrainer import PyTorchModelTrainer
from freqtrade.freqai.prediction_models.PyTorchMLPModel import PyTorchMLPModel
logger = logging.getLogger(__name__)
class PytorchClassifierMultiTarget(BasePytorchModel):
class PyTorchClassifierMultiTarget(BasePyTorchModel):
def __init__(self, **kwargs):
super().__init__(**kwargs)
# todo move to config
self.n_hidden = 1024
self.labels = ['0.0', '1.0', '2.0']
self.n_hidden = 1024
self.max_iters = 100
self.batch_size = 64
self.learning_rate = 3e-4
self.eval_iters = 10
def fit(self, data_dictionary: Dict, dk: FreqaiDataKitchen, **kwargs) -> Any:
"""
@@ -38,17 +38,27 @@ class PytorchClassifierMultiTarget(BasePytorchModel):
all the training and test data/labels.
"""
n_features = data_dictionary['train_features'].shape[-1]
tensor_dictionary = self.convert_data_to_tensors(data_dictionary)
model = MLP(
model = PyTorchMLPModel(
input_dim=n_features,
hidden_dim=self.n_hidden,
output_dim=len(self.labels)
)
model.to(self.device)
optimizer = torch.optim.AdamW(model.parameters(), lr=self.learning_rate)
criterion = torch.nn.CrossEntropyLoss()
init_model = self.get_init_model(dk.pair)
trainer = PytorchModelTrainer(model, optimizer, init_model=init_model)
trainer.fit(tensor_dictionary, self.max_iters, self.batch_size)
trainer = PyTorchModelTrainer(
model=model,
optimizer=optimizer,
criterion=criterion,
device=self.device,
batch_size=self.batch_size,
max_iters=self.max_iters,
eval_iters=self.eval_iters,
init_model=init_model
)
trainer.fit(data_dictionary)
return trainer
def predict(
@@ -73,9 +83,9 @@ class PytorchClassifierMultiTarget(BasePytorchModel):
self.data_cleaning_predict(dk)
dk.data_dictionary["prediction_features"] = torch.tensor(
dk.data_dictionary["prediction_features"].values
).to(self.device)
).float().to(self.device)
logits, _ = self.model.model(dk.data_dictionary["prediction_features"])
logits = self.model.model(dk.data_dictionary["prediction_features"])
probs = F.softmax(logits, dim=-1)
label_ints = torch.argmax(probs, dim=-1)
@@ -83,15 +93,3 @@ class PytorchClassifierMultiTarget(BasePytorchModel):
pred_df = DataFrame(label_ints, columns=dk.label_list).astype(float).astype(str)
pred_df = pd.concat([pred_df, pred_df_prob], axis=1)
return (pred_df, dk.do_predict)
def convert_data_to_tensors(self, data_dictionary: Dict) -> Dict:
tensor_dictionary = {}
for split in ['train', 'test']:
tensor_dictionary[f'{split}_features'] = torch.tensor(
data_dictionary[f'{split}_features'].values
).to(self.device)
tensor_dictionary[f'{split}_labels'] = torch.tensor(
data_dictionary[f'{split}_labels'].astype(float).values
).long().to(self.device)
return tensor_dictionary

View File

@@ -3,29 +3,23 @@ import logging
import torch
import torch.nn as nn
from torch.nn import functional as F
logger = logging.getLogger(__name__)
class MLP(nn.Module):
def __init__(self, input_dim, hidden_dim, output_dim):
super(MLP, self).__init__()
class PyTorchMLPModel(nn.Module):
def __init__(self, input_dim: int, hidden_dim: int, output_dim: int):
super(PyTorchMLPModel, self).__init__()
self.input_layer = nn.Linear(input_dim, hidden_dim)
self.hidden_layer = nn.Linear(hidden_dim, hidden_dim)
self.output_layer = nn.Linear(hidden_dim, output_dim)
self.relu = nn.ReLU()
self.dropout = nn.Dropout(p=0.2)
def forward(self, x, targets=None):
def forward(self, x: torch.tensor) -> torch.tensor:
x = self.relu(self.input_layer(x))
x = self.dropout(x)
x = self.relu(self.hidden_layer(x))
x = self.dropout(x)
logits = self.output_layer(x)
if targets is None:
return logits, None
loss = F.cross_entropy(logits, targets.squeeze())
return logits, loss
return logits