1
0
mirror of https://github.com/microsoft/qlib.git synced 2026-07-17 17:34:35 +08:00

Update to alstm

This commit is contained in:
meng-ustc
2020-11-26 15:22:34 +08:00
parent 667f69ef8f
commit a108f753d5
2 changed files with 8 additions and 34 deletions

View File

@@ -7,20 +7,14 @@ from pathlib import Path
import qlib import qlib
import pandas as pd import pandas as pd
from qlib.config import REG_CN from qlib.config import REG_CN
from qlib.contrib.model.pytorch_alstm import ALSTM
from qlib.contrib.data.handler import ALPHA360_Denoise
from qlib.contrib.strategy.strategy import TopkDropoutStrategy from qlib.contrib.strategy.strategy import TopkDropoutStrategy
from qlib.contrib.evaluate import ( from qlib.contrib.evaluate import (
backtest as normal_backtest, backtest as normal_backtest,
risk_analysis, risk_analysis,
) )
from qlib.utils import exists_qlib_data from qlib.utils import exists_qlib_data
# from qlib.model.learner import train_model
from qlib.utils import init_instance_by_config from qlib.utils import init_instance_by_config
import pickle
if __name__ == "__main__": if __name__ == "__main__":
# use default data # use default data
@@ -73,7 +67,7 @@ if __name__ == "__main__":
"metric": "IC", "metric": "IC",
"loss": "mse", "loss": "mse",
"seed": 0, "seed": 0,
"GPU": 0, "GPU": "0",
"rnn_type": "GRU", "rnn_type": "GRU",
}, },
}, },
@@ -97,7 +91,6 @@ if __name__ == "__main__":
# "record": ['SignalRecord', 'SigAnaRecord', 'PortAnaRecord'], # "record": ['SignalRecord', 'SigAnaRecord', 'PortAnaRecord'],
} }
# model = train_model(task)
model = init_instance_by_config(task["model"]) model = init_instance_by_config(task["model"])
dataset = init_instance_by_config(task["dataset"]) dataset = init_instance_by_config(task["dataset"])
model.fit(dataset) model.fit(dataset)

View File

@@ -9,10 +9,8 @@ import os
import numpy as np import numpy as np
import pandas as pd import pandas as pd
import copy import copy
from sklearn.metrics import roc_auc_score, mean_squared_error from ...utils import create_save_path
import logging from ...log import get_module_logger
from ...utils import unpack_archive_with_buffer, save_multiple_parts_file, create_save_path, drop_nan_by_y_index
from ...log import get_module_logger, TimeInspector
import torch import torch
import torch.nn as nn import torch.nn as nn
@@ -28,14 +26,10 @@ class ALSTM(Model):
Parameters Parameters
---------- ----------
input_dim : int d_feat : int
input dimension input dimension for each time step
output_dim : int metric: str
output dimension the evaluate metric used in early stop
layers : tuple
layer sizes
lr : float
learning rate
optimizer : str optimizer : str
optimizer name optimizer name
GPU : str GPU : str
@@ -116,14 +110,9 @@ class ALSTM(Model):
) )
) )
if loss not in {"mse", "binary"}:
raise NotImplementedError("loss {} is not supported!".format(loss))
self._scorer = mean_squared_error if loss == "mse" else roc_auc_score
self.alstm_model = ALSTMModel( self.alstm_model = ALSTMModel(
d_feat=self.d_feat, hidden_size=self.hidden_size, num_layers=self.num_layers, dropout=self.dropout d_feat=self.d_feat, hidden_size=self.hidden_size, num_layers=self.num_layers, dropout=self.dropout
) )
# def __init__(self, d_feat=6, hidden_size=64, num_layers=2, dropout=0.0, input_day=20, rnn_type="GRU"):
if optimizer.lower() == "adam": if optimizer.lower() == "adam":
self.train_optimizer = optim.Adam(self.alstm_model.parameters(), lr=self.lr) self.train_optimizer = optim.Adam(self.alstm_model.parameters(), lr=self.lr)
@@ -152,7 +141,6 @@ class ALSTM(Model):
raise ValueError("unknown loss `%s`" % self.loss) raise ValueError("unknown loss `%s`" % self.loss)
def metric_fn(self, pred, label): def metric_fn(self, pred, label):
mask = torch.isfinite(label) mask = torch.isfinite(label)
if self.metric == "IC": if self.metric == "IC":
return self.cal_ic(pred[mask], label[mask]) return self.cal_ic(pred[mask], label[mask])
@@ -197,7 +185,7 @@ class ALSTM(Model):
def test_epoch(self, data_x, data_y): def test_epoch(self, data_x, data_y):
# prepare training data # prepare testing data
x_values = data_x.values x_values = data_x.values
y_values = np.squeeze(data_y.values) y_values = np.squeeze(data_y.values)
@@ -207,7 +195,6 @@ class ALSTM(Model):
losses = [] losses = []
indices = np.arange(len(x_values)) indices = np.arange(len(x_values))
np.random.shuffle(indices)
for i in range(len(indices))[:: self.batch_size]: for i in range(len(indices))[:: self.batch_size]:
@@ -248,7 +235,6 @@ class ALSTM(Model):
if save_path == None: if save_path == None:
save_path = create_save_path(save_path) save_path = create_save_path(save_path)
stop_steps = 0 stop_steps = 0
train_loss = 0
best_score = -np.inf best_score = -np.inf
best_epoch = 0 best_epoch = 0
evals_result["train"] = [] evals_result["train"] = []
@@ -257,7 +243,6 @@ class ALSTM(Model):
# train # train
self.logger.info("training...") self.logger.info("training...")
self._fitted = True self._fitted = True
# return
for step in range(self.n_epochs): for step in range(self.n_epochs):
self.logger.info("Epoch%d:", step) self.logger.info("Epoch%d:", step)
@@ -334,11 +319,9 @@ class GRUModel(nn.Module):
dropout=dropout, dropout=dropout,
) )
self.fc_out = nn.Linear(hidden_size, 1) self.fc_out = nn.Linear(hidden_size, 1)
self.d_feat = d_feat self.d_feat = d_feat
def forward(self, x): def forward(self, x):
# x: [N, F*T]
x = x.reshape(len(x), self.d_feat, -1) # [N, F, T] x = x.reshape(len(x), self.d_feat, -1) # [N, F, T]
x = x.permute(0, 2, 1) # [N, T, F] x = x.permute(0, 2, 1) # [N, T, F]
out, _ = self.rnn(x) out, _ = self.rnn(x)
@@ -371,7 +354,6 @@ class ALSTMModel(nn.Module):
dropout=self.dropout, dropout=self.dropout,
) )
self.fc_out = nn.Linear(in_features=self.hid_size * 2, out_features=1) self.fc_out = nn.Linear(in_features=self.hid_size * 2, out_features=1)
# self.fc_out = nn.Linear(in_features=self.hid_size, out_features=1)
self.att_net = nn.Sequential() self.att_net = nn.Sequential()
self.att_net.add_module("att_fc_in", nn.Linear(in_features=self.hid_size, out_features=int(self.hid_size / 2))) self.att_net.add_module("att_fc_in", nn.Linear(in_features=self.hid_size, out_features=int(self.hid_size / 2)))
self.att_net.add_module("att_dropout", torch.nn.Dropout(self.dropout)) self.att_net.add_module("att_dropout", torch.nn.Dropout(self.dropout))
@@ -390,5 +372,4 @@ class ALSTMModel(nn.Module):
out = self.fc_out( out = self.fc_out(
torch.cat((rnn_out[:, -1, :], out_att), dim=1) torch.cat((rnn_out[:, -1, :], out_att), dim=1)
) # [batch, seq_len, num_directions * hidden_size] -> [batch, 1] ) # [batch, seq_len, num_directions * hidden_size] -> [batch, 1]
# out = self.fc_out(rnn_out[:, -1, :] + out_att)
return out[..., 0] return out[..., 0]