| from nets.envs import SCI |
|
|
| import os |
| import numpy as np |
| import optuna |
| from optuna.trial import TrialState |
| import torch |
| import torch.nn as nn |
| import torch.nn.functional as F |
| import torch.optim as optim |
| import torch.utils.data |
| from torchmetrics import R2Score |
| import neptune.new as neptune |
| import neptune.new.integrations.optuna as outils |
| from optuna.visualization import plot_contour, plot_optimization_history,plot_parallel_coordinate |
|
|
| DEVICE = torch.device("cpu") |
| BATCHSIZE = 2 |
| DIR = os.getcwd() |
| EPOCHS = 10 |
| N_TRAIN_EXAMPLES = BATCHSIZE * 10 |
| N_VALID_EXAMPLES = BATCHSIZE * 10 |
|
|
| class Hyper(SCI): |
| """ Hyper parameter tunning class. Allows to generate best NN architecture for task. Inputs are column indexes. idx[-1] is targeted value. |
| |
| |
| """ |
| def __init__(self,idx:tuple=(1,3,7),*args, **kwargs): |
| super(Hyper,self).__init__() |
| self.loader = self.data_flow(idx=idx) |
| |
| |
| def define_model(self,trial): |
| |
| n_layers = trial.suggest_int("n_layers", 2, 6) |
| layers = [] |
|
|
| in_features = self.input_dim |
| |
| for i in range(n_layers): |
| out_features = trial.suggest_int("n_units_l{}".format(i), 4, 128) |
| activations = trial.suggest_categorical('activation',['ReLU','Tanh','SiLU','SELU','RReLU']) |
| |
| layers.append(nn.Linear(in_features, out_features)) |
| layers.append(getattr(nn,activations)()) |
| p = trial.suggest_float("dropout_l{}".format(i), 0.0, 0.2) |
| layers.append(nn.Dropout(p)) |
|
|
| in_features = out_features |
| layers.append(nn.Linear(in_features, 1)) |
|
|
| return nn.Sequential(*layers) |
| def objective(self,trial): |
| |
| model = self.define_model(trial).to(DEVICE) |
| mape = R2Score() |
| |
| optimizer_name = trial.suggest_categorical("optimizer", ["Adam", "RMSprop", "SGD",'AdamW','Adamax','Adagrad']) |
| lr = trial.suggest_float("lr", 1e-7, 1e-3, log=True) |
| optimizer = getattr(optim, optimizer_name)(model.parameters(), lr=lr) |
| |
| train_loader, valid_loader = self.loader,self.loader |
|
|
| |
| for epoch in range(EPOCHS): |
| model.train() |
| for batch_idx, (data, target) in enumerate(train_loader): |
| |
| if batch_idx * BATCHSIZE >= N_TRAIN_EXAMPLES: |
| break |
|
|
| data, target = data.view(data.size(0), -1).to(DEVICE), target.to(DEVICE) |
|
|
| optimizer.zero_grad() |
| output = model(data) |
| loss = F.mse_loss(output, target) |
| loss.backward() |
| optimizer.step() |
|
|
| |
| model.eval() |
| correct = 0 |
| pred=torch.tensor([]) |
| targs=torch.tensor([]) |
| with torch.no_grad(): |
| for batch_idx, (data, target) in enumerate(valid_loader): |
| |
| if batch_idx * BATCHSIZE >= N_VALID_EXAMPLES: |
| break |
| data, target = data.view(data.size(0), -1).to(DEVICE), target.to(DEVICE) |
| |
| output = model(data) |
| |
| |
| |
| pred = torch.cat((pred,output.squeeze())) |
| targs = torch.cat((targs,target)) |
| |
| |
| accuracy = mape(pred,targs) |
|
|
| trial.report(accuracy, epoch) |
|
|
| |
| if trial.should_prune(): |
| raise optuna.exceptions.TrialPruned() |
|
|
| return accuracy |
| |
| def start_study(self,n_trials:int=100,neptune_project:str=None,neptune_api:str=None): |
| """ Starts study. Optionally provide your neptune repo and token for report generation. |
| |
| Args: |
| n_trials (int, optional): Number of iterations. Defaults to 100. |
| neptune_project (str, optional): . Defaults to None. |
| neptune_api (str, optional):. Defaults to None. |
| |
| Returns: |
| dict: quick report of results |
| """ |
| |
| study = optuna.create_study(direction="maximize") |
| if neptune_project and neptune_api: |
| run = neptune.init_run( |
| project=neptune_project, |
| api_token=neptune_api, |
| ) |
| neptune_callback = outils.NeptuneCallback(run) |
| study.optimize(self.objective, n_trials=n_trials, timeout=600,callbacks=[neptune_callback]) |
| else: |
| study.optimize(self.objective, n_trials=n_trials, timeout=600) |
| |
| |
|
|
| pruned_trials = study.get_trials(deepcopy=False, states=[TrialState.PRUNED]) |
| complete_trials = study.get_trials(deepcopy=False, states=[TrialState.COMPLETE]) |
|
|
| print("Study statistics: ") |
| print(" Number of finished trials: ", len(study.trials)) |
| print(" Number of pruned trials: ", len(pruned_trials)) |
| print(" Number of complete trials: ", len(complete_trials)) |
|
|
| print("Best trial:") |
| self.trial = study.best_trial |
|
|
| print(" Value: ", self.trial.value) |
|
|
| print(" Params: ") |
| for key, value in self.trial.params.items(): |
| print(" {}: {}".format(key, value)) |
| |
| if neptune_api and neptune_project: |
| run.stop() |
| |
| return {" Number of finished trials: ":len(study.trials), |
| " Number of pruned trials: ": len(pruned_trials), |
| " Number of complete trials: ": len(complete_trials), |
| "Best trial score" : self.trial.value, |
| " Params: ": self.trial.params |
| },plot_contour(study, params=["lr", "n_layers"]),\ |
| plot_optimization_history(study),\ |
| plot_parallel_coordinate(study) |