1
0
mirror of https://github.com/microsoft/qlib.git synced 2026-07-13 15:56:57 +08:00

Merge pull request #329 from D-X-Y/main

Fix Various Bugs for contrib.pytorch_ models
This commit is contained in:
you-n-g
2021-03-12 12:30:08 +08:00
committed by GitHub
15 changed files with 119 additions and 99 deletions

2
.gitignore vendored
View File

@@ -36,3 +36,5 @@ tags
.vscode/ .vscode/
*.swp *.swp
./pretrain

View File

@@ -17,6 +17,7 @@ The numbers shown below demonstrate the performance of the entire `workflow` of
| ALSTM (Yao Qin, et al.) | Alpha360 | 0.0493±0.01 | 0.3778±0.06| 0.0585±0.00 | 0.4606±0.04 | 0.0513±0.03 | 0.6727±0.38| -0.1085±0.02 | | ALSTM (Yao Qin, et al.) | Alpha360 | 0.0493±0.01 | 0.3778±0.06| 0.0585±0.00 | 0.4606±0.04 | 0.0513±0.03 | 0.6727±0.38| -0.1085±0.02 |
| GATs (Petar Velickovic, et al.) | Alpha360 | 0.0475±0.00 | 0.3515±0.02| 0.0592±0.00 | 0.4585±0.01 | 0.0876±0.02 | 1.1513±0.27| -0.0795±0.02 | | GATs (Petar Velickovic, et al.) | Alpha360 | 0.0475±0.00 | 0.3515±0.02| 0.0592±0.00 | 0.4585±0.01 | 0.0876±0.02 | 1.1513±0.27| -0.0795±0.02 |
| DoubleEnsemble (Chuheng Zhang, et al.) | Alpha360 | 0.0407±0.00| 0.3053±0.00 | 0.0490±0.00 | 0.3840±0.00 | 0.0380±0.02 | 0.5000±0.21 | -0.0984±0.02 | | DoubleEnsemble (Chuheng Zhang, et al.) | Alpha360 | 0.0407±0.00| 0.3053±0.00 | 0.0490±0.00 | 0.3840±0.00 | 0.0380±0.02 | 0.5000±0.21 | -0.0984±0.02 |
## Alpha158 dataset ## Alpha158 dataset
| Model Name | Dataset | IC | ICIR | Rank IC | Rank ICIR | Annualized Return | Information Ratio | Max Drawdown | | Model Name | Dataset | IC | ICIR | Rank IC | Rank ICIR | Annualized Return | Information Ratio | Max Drawdown |
|---|---|---|---|---|---|---|---|---| |---|---|---|---|---|---|---|---|---|
@@ -25,7 +26,6 @@ The numbers shown below demonstrate the performance of the entire `workflow` of
| XGBoost (Tianqi Chen, et al.) | Alpha158 | 0.0481±0.00 | 0.3659±0.00| 0.0495±0.00 | 0.4033±0.00 | 0.1111±0.00 | 1.2915±0.00| -0.0893±0.00 | | XGBoost (Tianqi Chen, et al.) | Alpha158 | 0.0481±0.00 | 0.3659±0.00| 0.0495±0.00 | 0.4033±0.00 | 0.1111±0.00 | 1.2915±0.00| -0.0893±0.00 |
| LightGBM (Guolin Ke, et al.) | Alpha158 | 0.0475±0.00 | 0.3979±0.00| 0.0485±0.00 | 0.4123±0.00 | 0.1143±0.00 | 1.2744±0.00| -0.0800±0.00 | | LightGBM (Guolin Ke, et al.) | Alpha158 | 0.0475±0.00 | 0.3979±0.00| 0.0485±0.00 | 0.4123±0.00 | 0.1143±0.00 | 1.2744±0.00| -0.0800±0.00 |
| MLP | Alpha158 | 0.0358±0.00 | 0.2738±0.03| 0.0425±0.00 | 0.3221±0.01 | 0.0836±0.02 | 1.0323±0.25| -0.1127±0.02 | | MLP | Alpha158 | 0.0358±0.00 | 0.2738±0.03| 0.0425±0.00 | 0.3221±0.01 | 0.0836±0.02 | 1.0323±0.25| -0.1127±0.02 |
| TabNet with pretrain (Sercan O. Arikm et al) | Alpha158 | 0.0344±0.00|0.205±0.11|0.0398±0.00 |0.3479±0.01|0.0827±0.02|1.1141±0.32 |-0.0925±0.02 |
| TFT (Bryan Lim, et al.) | Alpha158 (with selected 20 features) | 0.0343±0.00 | 0.2071±0.02| 0.0107±0.00 | 0.0660±0.02 | 0.0623±0.02 | 0.5818±0.20| -0.1762±0.01 | | TFT (Bryan Lim, et al.) | Alpha158 (with selected 20 features) | 0.0343±0.00 | 0.2071±0.02| 0.0107±0.00 | 0.0660±0.02 | 0.0623±0.02 | 0.5818±0.20| -0.1762±0.01 |
| GRU (Kyunghyun Cho, et al.) | Alpha158 (with selected 20 features) | 0.0311±0.00 | 0.2418±0.04| 0.0425±0.00 | 0.3434±0.02 | 0.0330±0.02 | 0.4805±0.30| -0.1021±0.02 | | GRU (Kyunghyun Cho, et al.) | Alpha158 (with selected 20 features) | 0.0311±0.00 | 0.2418±0.04| 0.0425±0.00 | 0.3434±0.02 | 0.0330±0.02 | 0.4805±0.30| -0.1021±0.02 |
| LSTM (Sepp Hochreiter, et al.) | Alpha158 (with selected 20 features) | 0.0312±0.00 | 0.2394±0.04| 0.0418±0.00 | 0.3324±0.03 | 0.0298±0.02 | 0.4198±0.33| -0.1348±0.03 | | LSTM (Sepp Hochreiter, et al.) | Alpha158 (with selected 20 features) | 0.0312±0.00 | 0.2394±0.04| 0.0418±0.00 | 0.3324±0.03 | 0.0298±0.02 | 0.4198±0.33| -0.1348±0.03 |

View File

@@ -55,7 +55,7 @@ task:
kwargs: *data_handler_config kwargs: *data_handler_config
segments: segments:
pretrain: [2008-01-01, 2014-12-31] pretrain: [2008-01-01, 2014-12-31]
pretrain_validation: [2015-01-01, 2020-08-01] pretrain_validation: [2015-01-01, 2016-12-31]
train: [2008-01-01, 2014-12-31] train: [2008-01-01, 2014-12-31]
valid: [2015-01-01, 2016-12-31] valid: [2015-01-01, 2016-12-31]
test: [2017-01-01, 2020-08-01] test: [2017-01-01, 2020-08-01]

View File

@@ -78,7 +78,6 @@ class ALSTM(Model):
self.optimizer = optimizer.lower() self.optimizer = optimizer.lower()
self.loss = loss self.loss = loss
self.device = torch.device("cuda:%d" % (GPU) if torch.cuda.is_available() and GPU >= 0 else "cpu") self.device = torch.device("cuda:%d" % (GPU) if torch.cuda.is_available() and GPU >= 0 else "cpu")
self.use_gpu = torch.cuda.is_available()
self.seed = seed self.seed = seed
self.logger.info( self.logger.info(
@@ -94,7 +93,7 @@ class ALSTM(Model):
"\nearly_stop : {}" "\nearly_stop : {}"
"\noptimizer : {}" "\noptimizer : {}"
"\nloss_type : {}" "\nloss_type : {}"
"\nvisible_GPU : {}" "\ndevice : {}"
"\nuse_GPU : {}" "\nuse_GPU : {}"
"\nseed : {}".format( "\nseed : {}".format(
d_feat, d_feat,
@@ -108,7 +107,7 @@ class ALSTM(Model):
early_stop, early_stop,
optimizer.lower(), optimizer.lower(),
loss, loss,
GPU, self.device,
self.use_gpu, self.use_gpu,
seed, seed,
) )
@@ -137,6 +136,10 @@ class ALSTM(Model):
self.fitted = False self.fitted = False
self.ALSTM_model.to(self.device) self.ALSTM_model.to(self.device)
@property
def use_gpu(self):
return self.device != torch.device("cpu")
def mse(self, pred, label): def mse(self, pred, label):
loss = (pred - label) ** 2 loss = (pred - label) ** 2
return torch.mean(loss) return torch.mean(loss)
@@ -205,12 +208,13 @@ class ALSTM(Model):
feature = torch.from_numpy(x_values[indices[i : i + self.batch_size]]).float().to(self.device) feature = torch.from_numpy(x_values[indices[i : i + self.batch_size]]).float().to(self.device)
label = torch.from_numpy(y_values[indices[i : i + self.batch_size]]).float().to(self.device) label = torch.from_numpy(y_values[indices[i : i + self.batch_size]]).float().to(self.device)
pred = self.ALSTM_model(feature) with torch.no_grad():
loss = self.loss_fn(pred, label) pred = self.ALSTM_model(feature)
losses.append(loss.item()) loss = self.loss_fn(pred, label)
losses.append(loss.item())
score = self.metric_fn(pred, label) score = self.metric_fn(pred, label)
scores.append(score.item()) scores.append(score.item())
return np.mean(losses), np.mean(scores) return np.mean(losses), np.mean(scores)
@@ -292,10 +296,7 @@ class ALSTM(Model):
x_batch = torch.from_numpy(x_values[begin:end]).float().to(self.device) x_batch = torch.from_numpy(x_values[begin:end]).float().to(self.device)
with torch.no_grad(): with torch.no_grad():
if self.use_gpu: pred = self.ALSTM_model(x_batch).detach().cpu().numpy()
pred = self.ALSTM_model(x_batch).detach().cpu().numpy()
else:
pred = self.ALSTM_model(x_batch).detach().numpy()
preds.append(pred) preds.append(pred)

View File

@@ -81,7 +81,6 @@ class ALSTM(Model):
self.loss = loss self.loss = loss
self.device = torch.device("cuda:%d" % (GPU) if torch.cuda.is_available() and GPU >= 0 else "cpu") self.device = torch.device("cuda:%d" % (GPU) if torch.cuda.is_available() and GPU >= 0 else "cpu")
self.n_jobs = n_jobs self.n_jobs = n_jobs
self.use_gpu = torch.cuda.is_available()
self.seed = seed self.seed = seed
self.logger.info( self.logger.info(
@@ -97,7 +96,7 @@ class ALSTM(Model):
"\nearly_stop : {}" "\nearly_stop : {}"
"\noptimizer : {}" "\noptimizer : {}"
"\nloss_type : {}" "\nloss_type : {}"
"\nvisible_GPU : {}" "\ndevice : {}"
"\nn_jobs : {}" "\nn_jobs : {}"
"\nuse_GPU : {}" "\nuse_GPU : {}"
"\nseed : {}".format( "\nseed : {}".format(
@@ -112,7 +111,7 @@ class ALSTM(Model):
early_stop, early_stop,
optimizer.lower(), optimizer.lower(),
loss, loss,
GPU, self.device,
n_jobs, n_jobs,
self.use_gpu, self.use_gpu,
seed, seed,
@@ -142,6 +141,10 @@ class ALSTM(Model):
self.fitted = False self.fitted = False
self.ALSTM_model.to(self.device) self.ALSTM_model.to(self.device)
@property
def use_gpu(self):
return self.device != torch.device("cpu")
def mse(self, pred, label): def mse(self, pred, label):
loss = (pred - label) ** 2 loss = (pred - label) ** 2
return torch.mean(loss) return torch.mean(loss)
@@ -192,12 +195,13 @@ class ALSTM(Model):
# feature[torch.isnan(feature)] = 0 # feature[torch.isnan(feature)] = 0
label = data[:, -1, -1].to(self.device) label = data[:, -1, -1].to(self.device)
pred = self.ALSTM_model(feature.float()) with torch.no_grad():
loss = self.loss_fn(pred, label) pred = self.ALSTM_model(feature.float())
losses.append(loss.item()) loss = self.loss_fn(pred, label)
losses.append(loss.item())
score = self.metric_fn(pred, label) score = self.metric_fn(pred, label)
scores.append(score.item()) scores.append(score.item())
return np.mean(losses), np.mean(scores) return np.mean(losses), np.mean(scores)
@@ -277,10 +281,7 @@ class ALSTM(Model):
feature = data[:, :, 0:-1].to(self.device) feature = data[:, :, 0:-1].to(self.device)
with torch.no_grad(): with torch.no_grad():
if self.use_gpu: pred = self.ALSTM_model(feature.float()).detach().cpu().numpy()
pred = self.ALSTM_model(feature.float()).detach().cpu().numpy()
else:
pred = self.ALSTM_model(feature.float()).detach().numpy()
preds.append(pred) preds.append(pred)

View File

@@ -103,7 +103,7 @@ class GATs(Model):
"\nbase_model : {}" "\nbase_model : {}"
"\nwith_pretrain : {}" "\nwith_pretrain : {}"
"\nmodel_path : {}" "\nmodel_path : {}"
"\nvisible_GPU : {}" "\ndevice : {}"
"\nuse_GPU : {}" "\nuse_GPU : {}"
"\nseed : {}".format( "\nseed : {}".format(
d_feat, d_feat,
@@ -119,7 +119,7 @@ class GATs(Model):
base_model, base_model,
with_pretrain, with_pretrain,
model_path, model_path,
GPU, self.device,
self.use_gpu, self.use_gpu,
seed, seed,
) )
@@ -149,6 +149,10 @@ class GATs(Model):
self.fitted = False self.fitted = False
self.GAT_model.to(self.device) self.GAT_model.to(self.device)
@property
def use_gpu(self):
return self.device != torch.device("cpu")
def mse(self, pred, label): def mse(self, pred, label):
loss = (pred - label) ** 2 loss = (pred - label) ** 2
return torch.mean(loss) return torch.mean(loss)
@@ -326,10 +330,7 @@ class GATs(Model):
x_batch = torch.from_numpy(x_values[batch]).float().to(self.device) x_batch = torch.from_numpy(x_values[batch]).float().to(self.device)
with torch.no_grad(): with torch.no_grad():
if self.use_gpu: pred = self.GAT_model(x_batch).detach().cpu().numpy()
pred = self.GAT_model(x_batch).detach().cpu().numpy()
else:
pred = self.GAT_model(x_batch).detach().numpy()
preds.append(pred) preds.append(pred)

View File

@@ -107,7 +107,6 @@ class GATs(Model):
self.model_path = model_path self.model_path = model_path
self.device = torch.device("cuda:%d" % (GPU) if torch.cuda.is_available() and GPU >= 0 else "cpu") self.device = torch.device("cuda:%d" % (GPU) if torch.cuda.is_available() and GPU >= 0 else "cpu")
self.n_jobs = n_jobs self.n_jobs = n_jobs
self.use_gpu = torch.cuda.is_available()
self.seed = seed self.seed = seed
self.logger.info( self.logger.info(
@@ -171,6 +170,10 @@ class GATs(Model):
self.fitted = False self.fitted = False
self.GAT_model.to(self.device) self.GAT_model.to(self.device)
@property
def use_gpu(self):
return self.device != torch.device("cpu")
def mse(self, pred, label): def mse(self, pred, label):
loss = (pred - label) ** 2 loss = (pred - label) ** 2
return torch.mean(loss) return torch.mean(loss)
@@ -347,10 +350,7 @@ class GATs(Model):
feature = data[:, :, 0:-1].to(self.device) feature = data[:, :, 0:-1].to(self.device)
with torch.no_grad(): with torch.no_grad():
if self.use_gpu: pred = self.GAT_model(feature.float()).detach().cpu().numpy()
pred = self.GAT_model(feature.float()).detach().cpu().numpy()
else:
pred = self.GAT_model(feature.float()).detach().numpy()
preds.append(pred) preds.append(pred)

View File

@@ -78,7 +78,6 @@ class GRU(Model):
self.optimizer = optimizer.lower() self.optimizer = optimizer.lower()
self.loss = loss self.loss = loss
self.device = torch.device("cuda:%d" % (GPU) if torch.cuda.is_available() and GPU >= 0 else "cpu") self.device = torch.device("cuda:%d" % (GPU) if torch.cuda.is_available() and GPU >= 0 else "cpu")
self.use_gpu = torch.cuda.is_available()
self.seed = seed self.seed = seed
self.logger.info( self.logger.info(
@@ -137,6 +136,10 @@ class GRU(Model):
self.fitted = False self.fitted = False
self.gru_model.to(self.device) self.gru_model.to(self.device)
@property
def use_gpu(self):
return self.device != torch.device("cpu")
def mse(self, pred, label): def mse(self, pred, label):
loss = (pred - label) ** 2 loss = (pred - label) ** 2
return torch.mean(loss) return torch.mean(loss)
@@ -205,12 +208,13 @@ class GRU(Model):
feature = torch.from_numpy(x_values[indices[i : i + self.batch_size]]).float().to(self.device) feature = torch.from_numpy(x_values[indices[i : i + self.batch_size]]).float().to(self.device)
label = torch.from_numpy(y_values[indices[i : i + self.batch_size]]).float().to(self.device) label = torch.from_numpy(y_values[indices[i : i + self.batch_size]]).float().to(self.device)
pred = self.gru_model(feature) with torch.no_grad():
loss = self.loss_fn(pred, label) pred = self.gru_model(feature)
losses.append(loss.item()) loss = self.loss_fn(pred, label)
losses.append(loss.item())
score = self.metric_fn(pred, label) score = self.metric_fn(pred, label)
scores.append(score.item()) scores.append(score.item())
return np.mean(losses), np.mean(scores) return np.mean(losses), np.mean(scores)
@@ -292,10 +296,7 @@ class GRU(Model):
x_batch = torch.from_numpy(x_values[begin:end]).float().to(self.device) x_batch = torch.from_numpy(x_values[begin:end]).float().to(self.device)
with torch.no_grad(): with torch.no_grad():
if self.use_gpu: pred = self.gru_model(x_batch).detach().cpu().numpy()
pred = self.gru_model(x_batch).detach().cpu().numpy()
else:
pred = self.gru_model(x_batch).detach().numpy()
preds.append(pred) preds.append(pred)

View File

@@ -81,7 +81,6 @@ class GRU(Model):
self.loss = loss self.loss = loss
self.device = torch.device("cuda:%d" % (GPU) if torch.cuda.is_available() and GPU >= 0 else "cpu") self.device = torch.device("cuda:%d" % (GPU) if torch.cuda.is_available() and GPU >= 0 else "cpu")
self.n_jobs = n_jobs self.n_jobs = n_jobs
self.use_gpu = torch.cuda.is_available()
self.seed = seed self.seed = seed
self.logger.info( self.logger.info(
@@ -97,7 +96,7 @@ class GRU(Model):
"\nearly_stop : {}" "\nearly_stop : {}"
"\noptimizer : {}" "\noptimizer : {}"
"\nloss_type : {}" "\nloss_type : {}"
"\nvisible_GPU : {}" "\ndevice : {}"
"\nn_jobs : {}" "\nn_jobs : {}"
"\nuse_GPU : {}" "\nuse_GPU : {}"
"\nseed : {}".format( "\nseed : {}".format(
@@ -112,7 +111,7 @@ class GRU(Model):
early_stop, early_stop,
optimizer.lower(), optimizer.lower(),
loss, loss,
GPU, self.device,
n_jobs, n_jobs,
self.use_gpu, self.use_gpu,
seed, seed,
@@ -142,6 +141,10 @@ class GRU(Model):
self.fitted = False self.fitted = False
self.GRU_model.to(self.device) self.GRU_model.to(self.device)
@property
def use_gpu(self):
return self.device != torch.device("cpu")
def mse(self, pred, label): def mse(self, pred, label):
loss = (pred - label) ** 2 loss = (pred - label) ** 2
return torch.mean(loss) return torch.mean(loss)
@@ -192,12 +195,13 @@ class GRU(Model):
# feature[torch.isnan(feature)] = 0 # feature[torch.isnan(feature)] = 0
label = data[:, -1, -1].to(self.device) label = data[:, -1, -1].to(self.device)
pred = self.GRU_model(feature.float()) with torch.no_grad():
loss = self.loss_fn(pred, label) pred = self.GRU_model(feature.float())
losses.append(loss.item()) loss = self.loss_fn(pred, label)
losses.append(loss.item())
score = self.metric_fn(pred, label) score = self.metric_fn(pred, label)
scores.append(score.item()) scores.append(score.item())
return np.mean(losses), np.mean(scores) return np.mean(losses), np.mean(scores)
@@ -277,10 +281,7 @@ class GRU(Model):
feature = data[:, :, 0:-1].to(self.device) feature = data[:, :, 0:-1].to(self.device)
with torch.no_grad(): with torch.no_grad():
if self.use_gpu: pred = self.GRU_model(feature.float()).detach().cpu().numpy()
pred = self.GRU_model(feature.float()).detach().cpu().numpy()
else:
pred = self.GRU_model(feature.float()).detach().numpy()
preds.append(pred) preds.append(pred)

View File

@@ -77,7 +77,6 @@ class LSTM(Model):
self.optimizer = optimizer.lower() self.optimizer = optimizer.lower()
self.loss = loss self.loss = loss
self.device = torch.device("cuda:%d" % (GPU) if torch.cuda.is_available() and GPU >= 0 else "cpu") self.device = torch.device("cuda:%d" % (GPU) if torch.cuda.is_available() and GPU >= 0 else "cpu")
self.use_gpu = torch.cuda.is_available()
self.seed = seed self.seed = seed
self.logger.info( self.logger.info(
@@ -133,6 +132,10 @@ class LSTM(Model):
self.fitted = False self.fitted = False
self.lstm_model.to(self.device) self.lstm_model.to(self.device)
@property
def use_gpu(self):
return self.device != torch.device("cpu")
def mse(self, pred, label): def mse(self, pred, label):
loss = (pred - label) ** 2 loss = (pred - label) ** 2
return torch.mean(loss) return torch.mean(loss)
@@ -288,10 +291,7 @@ class LSTM(Model):
x_batch = torch.from_numpy(x_values[begin:end]).float().to(self.device) x_batch = torch.from_numpy(x_values[begin:end]).float().to(self.device)
with torch.no_grad(): with torch.no_grad():
if self.use_gpu: pred = self.lstm_model(x_batch).detach().cpu().numpy()
pred = self.lstm_model(x_batch).detach().cpu().numpy()
else:
pred = self.lstm_model(x_batch).detach().numpy()
preds.append(pred) preds.append(pred)

View File

@@ -80,7 +80,6 @@ class LSTM(Model):
self.loss = loss self.loss = loss
self.device = torch.device("cuda:%d" % (GPU) if torch.cuda.is_available() and GPU >= 0 else "cpu") self.device = torch.device("cuda:%d" % (GPU) if torch.cuda.is_available() and GPU >= 0 else "cpu")
self.n_jobs = n_jobs self.n_jobs = n_jobs
self.use_gpu = torch.cuda.is_available()
self.seed = seed self.seed = seed
self.logger.info( self.logger.info(
@@ -96,7 +95,7 @@ class LSTM(Model):
"\nearly_stop : {}" "\nearly_stop : {}"
"\noptimizer : {}" "\noptimizer : {}"
"\nloss_type : {}" "\nloss_type : {}"
"\nvisible_GPU : {}" "\ndevice : {}"
"\nn_jobs : {}" "\nn_jobs : {}"
"\nuse_GPU : {}" "\nuse_GPU : {}"
"\nseed : {}".format( "\nseed : {}".format(
@@ -111,7 +110,7 @@ class LSTM(Model):
early_stop, early_stop,
optimizer.lower(), optimizer.lower(),
loss, loss,
GPU, self.device,
n_jobs, n_jobs,
self.use_gpu, self.use_gpu,
seed, seed,
@@ -138,6 +137,10 @@ class LSTM(Model):
self.fitted = False self.fitted = False
self.LSTM_model.to(self.device) self.LSTM_model.to(self.device)
@property
def use_gpu(self):
return self.device != torch.device("cpu")
def mse(self, pred, label): def mse(self, pred, label):
loss = (pred - label) ** 2 loss = (pred - label) ** 2
return torch.mean(loss) return torch.mean(loss)
@@ -273,10 +276,7 @@ class LSTM(Model):
feature = data[:, :, 0:-1].to(self.device) feature = data[:, :, 0:-1].to(self.device)
with torch.no_grad(): with torch.no_grad():
if self.use_gpu: pred = self.LSTM_model(feature.float()).detach().cpu().numpy()
pred = self.LSTM_model(feature.float()).detach().cpu().numpy()
else:
pred = self.LSTM_model(feature.float()).detach().numpy()
preds.append(pred) preds.append(pred)

View File

@@ -82,7 +82,6 @@ class DNNModelPytorch(Model):
self.optimizer = optimizer.lower() self.optimizer = optimizer.lower()
self.loss_type = loss self.loss_type = loss
self.device = torch.device("cuda:%d" % (GPU) if torch.cuda.is_available() and GPU >= 0 else "cpu") self.device = torch.device("cuda:%d" % (GPU) if torch.cuda.is_available() and GPU >= 0 else "cpu")
self.use_GPU = torch.cuda.is_available()
self.seed = seed self.seed = seed
self.weight_decay = weight_decay self.weight_decay = weight_decay
@@ -100,7 +99,7 @@ class DNNModelPytorch(Model):
"\nloss_type : {}" "\nloss_type : {}"
"\neval_steps : {}" "\neval_steps : {}"
"\nseed : {}" "\nseed : {}"
"\nvisible_GPU : {}" "\ndevice : {}"
"\nuse_GPU : {}" "\nuse_GPU : {}"
"\nweight_decay : {}".format( "\nweight_decay : {}".format(
layers, layers,
@@ -115,8 +114,8 @@ class DNNModelPytorch(Model):
loss, loss,
eval_steps, eval_steps,
seed, seed,
GPU, self.device,
self.use_GPU, self.use_gpu,
weight_decay, weight_decay,
) )
) )
@@ -157,6 +156,10 @@ class DNNModelPytorch(Model):
self.fitted = False self.fitted = False
self.dnn_model.to(self.device) self.dnn_model.to(self.device)
@property
def use_gpu(self):
return self.device != torch.device("cpu")
def fit( def fit(
self, self,
dataset: DatasetH, dataset: DatasetH,
@@ -219,7 +222,8 @@ class DNNModelPytorch(Model):
# validation # validation
train_loss += loss.val train_loss += loss.val
if step and step % self.eval_steps == 0: # for evert `eval_steps` steps or at the last steps, we will evaluate the model.
if step % self.eval_steps == 0 or step + 1 == self.max_steps:
stop_steps += 1 stop_steps += 1
train_loss /= self.eval_steps train_loss /= self.eval_steps
@@ -252,9 +256,9 @@ class DNNModelPytorch(Model):
# update learning rate # update learning rate
self.scheduler.step(cur_loss_val) self.scheduler.step(cur_loss_val)
# restore the optimal parameters after training ?? # restore the optimal parameters after training
self.dnn_model.load_state_dict(torch.load(save_path)) self.dnn_model.load_state_dict(torch.load(save_path))
if self.use_GPU: if self.use_gpu:
torch.cuda.empty_cache() torch.cuda.empty_cache()
def get_loss(self, pred, w, target, loss_type): def get_loss(self, pred, w, target, loss_type):
@@ -276,10 +280,7 @@ class DNNModelPytorch(Model):
self.dnn_model.eval() self.dnn_model.eval()
with torch.no_grad(): with torch.no_grad():
if self.use_GPU: preds = self.dnn_model(x_test).detach().cpu().numpy()
preds = self.dnn_model(x_test).detach().cpu().numpy()
else:
preds = self.dnn_model(x_test).detach().numpy()
return pd.Series(np.squeeze(preds), index=x_test_pd.index) return pd.Series(np.squeeze(preds), index=x_test_pd.index)
def save(self, filename, **kwargs): def save(self, filename, **kwargs):

View File

@@ -241,7 +241,6 @@ class SFM(Model):
self.optimizer = optimizer.lower() self.optimizer = optimizer.lower()
self.loss = loss self.loss = loss
self.device = torch.device("cuda:%d" % (GPU) if torch.cuda.is_available() and GPU >= 0 else "cpu") self.device = torch.device("cuda:%d" % (GPU) if torch.cuda.is_available() and GPU >= 0 else "cpu")
self.use_gpu = torch.cuda.is_available()
self.seed = seed self.seed = seed
self.logger.info( self.logger.info(
@@ -260,7 +259,7 @@ class SFM(Model):
"\neval_steps : {}" "\neval_steps : {}"
"\noptimizer : {}" "\noptimizer : {}"
"\nloss_type : {}" "\nloss_type : {}"
"\nvisible_GPU : {}" "\ndevice : {}"
"\nuse_GPU : {}" "\nuse_GPU : {}"
"\nseed : {}".format( "\nseed : {}".format(
d_feat, d_feat,
@@ -277,7 +276,7 @@ class SFM(Model):
eval_steps, eval_steps,
optimizer.lower(), optimizer.lower(),
loss, loss,
GPU, self.device,
self.use_gpu, self.use_gpu,
seed, seed,
) )
@@ -309,6 +308,10 @@ class SFM(Model):
self.fitted = False self.fitted = False
self.sfm_model.to(self.device) self.sfm_model.to(self.device)
@property
def use_gpu(self):
return self.device != torch.device("cpu")
def test_epoch(self, data_x, data_y): def test_epoch(self, data_x, data_y):
# prepare training data # prepare training data

View File

@@ -55,7 +55,7 @@ class TabnetModel(Model):
ps=0.3, ps=0.3,
lr=0.01, lr=0.01,
pretrain=True, pretrain=True,
pretrain_file="./pretrain/best.model", pretrain_file=None,
): ):
""" """
TabNet model for Qlib TabNet model for Qlib
@@ -81,13 +81,13 @@ class TabnetModel(Model):
self.metric = metric self.metric = metric
self.early_stop = early_stop self.early_stop = early_stop
self.pretrain = pretrain self.pretrain = pretrain
self.pretrain_file = pretrain_file self.pretrain_file = get_or_create_path(pretrain_file)
self.logger.info( self.logger.info(
"TabNet:" "TabNet:"
"\nbatch_size : {}" "\nbatch_size : {}"
"\nvirtual bs : {}" "\nvirtual bs : {}"
"\nGPU : {}" "\ndevice : {}"
"\npretrain: {}".format(self.batch_size, vbs, GPU, pretrain) "\npretrain: {}".format(self.batch_size, vbs, self.device, self.pretrain)
) )
self.fitted = False self.fitted = False
np.random.seed(self.seed) np.random.seed(self.seed)
@@ -116,6 +116,10 @@ class TabnetModel(Model):
else: else:
raise NotImplementedError("optimizer {} is not supported!".format(optimizer)) raise NotImplementedError("optimizer {} is not supported!".format(optimizer))
@property
def use_gpu(self):
return self.device != torch.device("cpu")
def pretrain_fn(self, dataset=DatasetH, pretrain_file="./pretrain/best.model"): def pretrain_fn(self, dataset=DatasetH, pretrain_file="./pretrain/best.model"):
get_or_create_path(pretrain_file) get_or_create_path(pretrain_file)
@@ -182,7 +186,7 @@ class TabnetModel(Model):
stop_steps = 0 stop_steps = 0
train_loss = 0 train_loss = 0
best_score = np.inf best_score = -np.inf
best_epoch = 0 best_epoch = 0
evals_result["train"] = [] evals_result["train"] = []
evals_result["valid"] = [] evals_result["valid"] = []
@@ -201,7 +205,7 @@ class TabnetModel(Model):
evals_result["train"].append(train_score) evals_result["train"].append(train_score)
evals_result["valid"].append(val_score) evals_result["valid"].append(val_score)
if val_score < best_score: if val_score > best_score:
best_score = val_score best_score = val_score
stop_steps = 0 stop_steps = 0
best_epoch = epoch_idx best_epoch = epoch_idx
@@ -216,6 +220,9 @@ class TabnetModel(Model):
self.tabnet_model.load_state_dict(best_param) self.tabnet_model.load_state_dict(best_param)
torch.save(best_param, save_path) torch.save(best_param, save_path)
if self.use_gpu:
torch.cuda.empty_cache()
def predict(self, dataset): def predict(self, dataset):
if not self.fitted: if not self.fitted:
raise ValueError("model is not fitted yet!") raise ValueError("model is not fitted yet!")
@@ -264,12 +271,13 @@ class TabnetModel(Model):
feature = x_values[indices[i : i + self.batch_size]].float().to(self.device) feature = x_values[indices[i : i + self.batch_size]].float().to(self.device)
label = y_values[indices[i : i + self.batch_size]].float().to(self.device) label = y_values[indices[i : i + self.batch_size]].float().to(self.device)
priors = torch.ones(self.batch_size, self.d_feat).to(self.device) priors = torch.ones(self.batch_size, self.d_feat).to(self.device)
pred = self.tabnet_model(feature, priors) with torch.no_grad():
loss = self.loss_fn(pred, label) pred = self.tabnet_model(feature, priors)
losses.append(loss.item()) loss = self.loss_fn(pred, label)
losses.append(loss.item())
score = self.metric_fn(pred, label) score = self.metric_fn(pred, label)
scores.append(score.item()) scores.append(score.item())
return np.mean(losses), np.mean(scores) return np.mean(losses), np.mean(scores)
@@ -352,10 +360,11 @@ class TabnetModel(Model):
label = y_train_values.float().to(self.device) label = y_train_values.float().to(self.device)
S_mask = S_mask.to(self.device) S_mask = S_mask.to(self.device)
priors = 1 - S_mask priors = 1 - S_mask
(vec, sparse_loss) = self.tabnet_model(feature, priors) with torch.no_grad():
f = self.tabnet_decoder(vec) (vec, sparse_loss) = self.tabnet_model(feature, priors)
f = self.tabnet_decoder(vec)
loss = self.pretrain_loss_fn(label, f, S_mask) loss = self.pretrain_loss_fn(label, f, S_mask)
losses.append(loss.item()) losses.append(loss.item())
return np.mean(losses) return np.mean(losses)