Download model/src/mrl_te_optimization/models/train_val.py from OneScience-Group/UTRGAN: direct link, hf CLI and curl.
- Browser
- Download file 12.3 kB
-
https://huggingface.co/OneScience-Group/UTRGAN/resolve/main/model/src/mrl_te_optimization/models/train_val.py
- Command line
-
hf download hf://OneScience-Group/UTRGAN/model/src/mrl_te_optimization/models/train_val.py
-
curl -L -o train_val.py https://huggingface.co/OneScience-Group/UTRGAN/resolve/main/model/src/mrl_te_optimization/models/train_val.py
12.3 kB
| import os | |
| import sys | |
| import time | |
| import numpy as np | |
| import pandas as pd | |
| import logging | |
| sys.path.append(os.path.dirname(os.path.dirname(__file__))) | |
| import utils | |
| import torch | |
| from scipy.stats import pearsonr | |
| from torch import optim | |
| from sklearn.metrics import r2_score, f1_score, roc_auc_score | |
| from models.ScheduleOptimizer import ScheduledOptim , find_lr | |
| from models.loss import Dynamic_Task_Priority as DTP | |
| def train(dataloader,model,optimizer,popen,epoch,lr=None, verbose=True): | |
| logger = logging.getLogger("VAE") | |
| loader_len = len(dataloader) # number of iteration | |
| device = 'cuda' if torch.cuda.is_available() else 'cpu' | |
| model = model.to(device) | |
| model.train() | |
| verbose_list=[] | |
| verbose_df = pd.DataFrame() | |
| for idx,data in enumerate(dataloader): | |
| X,Y = put_data_to_cuda(data,popen,require_grad=True) | |
| optimizer.zero_grad() | |
| out = model(X) | |
| loss_dict = model.compute_loss(out,X,Y,popen) | |
| loss = loss_dict['Total'] | |
| acc_dict = model.compute_acc(out,X,Y,popen) | |
| loss_dict.update(acc_dict) # adding the acc ditc into loss dict | |
| loss.backward() | |
| optimizer.step() | |
| # ====== update lr ======= | |
| if type(optimizer) == ScheduledOptim: | |
| lr = optimizer.update_learning_rate() # see model.optim.py | |
| loss_dict["lr"]=lr | |
| elif popen.optimizer == 'Adam': | |
| lr = optimizer.param_groups[0]['lr'] | |
| if popen.loss_schema != 'constant': | |
| popen.chimerla_weight = popen.loss_schedualer._update(loss_dict) | |
| for t in popen.tasks: | |
| loss_dict[popen.loss_schema+"_wt_"+t] = popen.chimerla_weight[t] | |
| with torch.no_grad(): | |
| loss_dict= utils.clean_value_dict(loss_dict) | |
| verbose_list.append(loss_dict) | |
| # ======== verbose ======== | |
| # record result 5 times for a epoch | |
| if verbose: | |
| if idx % int(loader_len/5) == 0: | |
| # plot that in loss dict | |
| loss_dict_keys = list(loss_dict.keys()) | |
| train_verbose = "{:5d} / {:5d} ({:s}%):" | |
| verbose_args = [idx,loader_len,str(int(idx/loader_len*100)).zfill(3)] | |
| for key in loss_dict_keys: | |
| train_verbose += "\t %s:{:.7f}"%key | |
| verbose_args.append(loss_dict[key]) | |
| # plot the cumulative mean total loss | |
| short_batch_df = pd.json_normalize(verbose_list) # this will be cumulative | |
| mean_total = short_batch_df.loc[:,'Total'].mean() | |
| train_verbose += "\t %s:{:.7f}"%"Mean_Total" | |
| verbose_args.append(mean_total) | |
| train_verbose = train_verbose.format(*verbose_args) | |
| logger.info(train_verbose) | |
| if popen.cuda_id != torch.device('cpu'): | |
| with torch.cuda.device(popen.cuda_id): | |
| torch.cuda.empty_cache() | |
| def validate(dataloader,model,popen,epoch): | |
| logger = logging.getLogger("VAE") | |
| device = 'cuda' if torch.cuda.is_available() else 'cpu' | |
| model = model.to(device) | |
| model.teacher_forcing = False # turn off teacher_forcing | |
| # ====== set up empty ===== | |
| verbose_list=[] | |
| Y_ls = [] | |
| pred_ls = [] | |
| metric_dict = {} | |
| # ======== evaluate ======= | |
| model.eval() | |
| with torch.no_grad(): | |
| for idx,data in enumerate(dataloader): | |
| X,Y = put_data_to_cuda(data,popen,require_grad=False) | |
| Y_ls.append(Y.cpu().numpy()) | |
| out = model(X) | |
| pred_ls.append(out.cpu().numpy()) | |
| loss_dict = model.compute_loss(out,X,Y,popen) | |
| loss = loss_dict['Total'] | |
| acc_dict = model.compute_acc(out,X,Y,popen) | |
| loss_dict.update(acc_dict) | |
| loss_dict = utils.clean_value_dict(loss_dict) # convert possible torch to single item | |
| verbose_list.append(loss_dict) | |
| if popen.cuda_id != torch.device('cpu'): | |
| with torch.cuda.device(popen.cuda_id): | |
| torch.cuda.empty_cache() | |
| # # average among batch | |
| # ======== verbose ======== | |
| Y_ay = np.concatenate(Y_ls,axis=0).flatten() | |
| pred_ay = np.concatenate(pred_ls,axis=0).flatten() | |
| if popen.model_type == 'RL_clf': | |
| metric_dict["F1"] = f1_score(Y_ay, pred_ay>0.5, average='binary') | |
| metric_dict["AUROC"] = roc_auc_score(Y_ay, pred_ay) | |
| else: | |
| metric_dict[f"r2"] = r2_score(Y_ay, pred_ay) | |
| metric_dict[f"pr"] = pearsonr(Y_ay, pred_ay)[0] | |
| verbose_df = pd.json_normalize(verbose_list) | |
| val_verbose = "" | |
| verbose_args = [] | |
| verbose_dict = {key:verbose_df[key].mean() for key in verbose_df.columns} | |
| verbose_dict.update(metric_dict) | |
| for key,values in verbose_dict.items(): | |
| val_verbose += "\t %s:{:.7f}"%key | |
| verbose_args.append(values) | |
| val_verbose = val_verbose.format(*verbose_args) | |
| logger.info(val_verbose) | |
| # what avg acc return : mean of RL_Acc , Recons_Acc, Motif_Acc | |
| acc_col = list(acc_dict.keys()) | |
| Avg_acc = np.mean(verbose_df.loc[:,acc_col].mean(axis=0)) | |
| # return these to save current performance | |
| return (verbose_df['Total'].mean(),Avg_acc) if 'RL_loss' not in verbose_df.keys() else (verbose_df['RL_loss'].mean(),verbose_df['RL_Acc'].mean()) | |
| def iter_train(loader_dict, model, optimizer, popen, epoch, verbose=True): | |
| logger = logging.getLogger("VAE") | |
| # loader_len = len(dataloader) # number of iteration | |
| all_len = [len(loader[0]) for loader in loader_dict.values()] | |
| max_len = np.max(all_len) | |
| n_task = len(popen.cycle_set) | |
| total_len = max_len*n_task | |
| all_train = {task : iter(loader[0]) for task,loader in loader_dict.items()} | |
| def try_next(all_train, task): | |
| try: | |
| data = next(all_train[task]) | |
| return data | |
| except StopIteration: | |
| all_train[task] = iter(loader_dict[task][0]) | |
| data = next(all_train[task]) | |
| return data | |
| device = 'cuda' if torch.cuda.is_available() else 'cpu' | |
| model = model.to(device) | |
| model.train() | |
| verbose_list=[] | |
| for idx in range(total_len): | |
| task = popen.cycle_set[idx%n_task] | |
| model.task = task | |
| data = try_next(all_train, task) | |
| X,Y = put_data_to_cuda(data,popen,require_grad=True) | |
| optimizer.zero_grad() | |
| out = model(X) | |
| loss_dict = model.compute_loss(out,X,Y,popen) | |
| loss = loss_dict['Total'] | |
| acc_dict = model.compute_acc(out,X,Y,popen) | |
| loss_dict.update(acc_dict) # adding the acc ditc into loss dict | |
| loss.backward() | |
| optimizer.step() | |
| # ====== update lr ======= | |
| if type(optimizer) == ScheduledOptim: | |
| lr = optimizer.update_learning_rate() # see model.optim.py | |
| loss_dict["lr"]=lr | |
| elif popen.optimizer == 'Adam': | |
| lr = optimizer.param_groups[0]['lr'] | |
| if popen.loss_schema != 'constant': | |
| popen.chimerla_weight = popen.loss_schedualer._update(loss_dict) | |
| for t in popen.tasks: | |
| loss_dict[popen.loss_schema+"_wt_"+t] = popen.chimerla_weight[t] | |
| with torch.no_grad(): | |
| loss_dict= utils.clean_value_dict(loss_dict) | |
| verbose_list.append(loss_dict) | |
| # ======== verbose ======== | |
| # record result 5 times for a epoch | |
| if verbose: | |
| if idx % int(total_len/5) == 0: | |
| # plot that in loss dict | |
| loss_dict_keys = list(loss_dict.keys()) | |
| train_verbose = "{:5d} / {:5d} ({:s}%):" | |
| verbose_args = [idx,total_len,str(int(idx/total_len*100)).zfill(3)] | |
| for key in loss_dict_keys: | |
| train_verbose += "\t %s:{:.7f}"%key | |
| verbose_args.append(loss_dict[key]) | |
| # plot the cumulative mean total loss | |
| short_batch_df = pd.json_normalize(verbose_list) # this will be cumulative | |
| mean_total = short_batch_df.loc[:,'Total'].mean() | |
| train_verbose += "\t %s:{:.7f}"%"Mean_Total" | |
| verbose_args.append(mean_total) | |
| train_verbose = train_verbose.format(*verbose_args) | |
| logger.info(train_verbose) | |
| if popen.cuda_id != torch.device('cpu'): | |
| with torch.cuda.device(popen.cuda_id): | |
| torch.cuda.empty_cache() | |
| def cycle_validate(loader_dict, model, optimizer, popen, epoch , which_set=1, return_=False): | |
| logger = logging.getLogger("VAE") | |
| device = 'cuda' if torch.cuda.is_available() else 'cpu' | |
| model = model.to(device) | |
| # ====== set up empty ===== | |
| # model.loss_dict_keys = ['RL_loss', 'Recons_loss', 'Motif_loss', 'Total', 'RL_Acc', 'Recons_Acc', 'Motif_Acc'] | |
| verbose_list=[] | |
| r2_dict = {} | |
| Y_n_pred = {} | |
| # ======== evaluate ======= | |
| for subset, dataloader in loader_dict.items(): | |
| # fix | |
| model.task = subset | |
| # # logger.info(" =======================| fix |======================= ") | |
| # model = utils.fix_parameter(model, popen.modual_to_fix[0]) | |
| # train(dataloader[0], model, optimizer, popen, epoch, verbose=True) | |
| Y_ls = [] | |
| pred_ls = [] | |
| with torch.no_grad(): | |
| model.eval() | |
| for idx,data in enumerate(dataloader[which_set]): | |
| X,Y = put_data_to_cuda(data,popen,require_grad=False) | |
| out = model(X) | |
| Y_ls.append(Y.detach().cpu().numpy()) | |
| pred_ls.append(out.detach().cpu().numpy()) | |
| loss_dict = model.compute_loss(out,X,Y,popen) | |
| loss_dict['%s_loss'%subset] = loss_dict['Total'] | |
| acc_dict = model.compute_acc(out,X,Y,popen) | |
| loss_dict.update(acc_dict) | |
| loss_dict = utils.clean_value_dict(loss_dict) # convert possible torch to single item | |
| verbose_list.append(loss_dict) | |
| if popen.cuda_id != torch.device('cpu'): | |
| with torch.cuda.device(popen.cuda_id): | |
| torch.cuda.empty_cache() | |
| Y_ay = np.concatenate(Y_ls,axis=0).flatten() | |
| pred_ay = np.concatenate(pred_ls,axis=0).flatten() | |
| if return_: | |
| Y_n_pred[subset] = (Y_ay, pred_ay) | |
| r2_dict[f"{subset}_r2"] = r2_score(Y_ay, pred_ay) | |
| r2_dict[f"{subset}_pr"] = pearsonr(Y_ay, pred_ay)[0] | |
| # # average among batch | |
| # ======== verbose ======== | |
| verbose_df = pd.json_normalize(verbose_list) | |
| val_verbose = "" | |
| verbose_args = [] | |
| verbose_dict = {key:verbose_df[key].mean() for key in verbose_df.columns} | |
| verbose_dict.update(r2_dict) | |
| for key,values in verbose_dict.items(): | |
| val_verbose += "\t %s:{:.7f}"%key | |
| verbose_args.append(values) | |
| val_verbose = val_verbose.format(*verbose_args) | |
| logger.info(val_verbose) | |
| # what avg acc return : mean of RL_Acc , Recons_Acc, Motif_Acc | |
| acc_col = list(acc_dict.keys()) | |
| Avg_acc = np.mean(verbose_df.loc[:,acc_col].mean(axis=0)) | |
| if return_: | |
| return verbose_dict, Y_n_pred | |
| else: | |
| return verbose_dict | |
| def put_data_to_cuda(data,popen,require_grad=True): | |
| X,y = data | |
| device = popen.cuda_id | |
| # for X is a list [seq, uAUG ....] | |
| if popen.other_input_columns is not None: | |
| X = [x_i.float().to(device) for x_i in X] | |
| if require_grad: | |
| for x_i in X: | |
| x_i.required_grad = True | |
| # X is not a list : seq | |
| else: | |
| X = X.float().to(device) | |
| if require_grad: | |
| X.required_grad = True # check !!! | |
| Y = y.float().to(device) | |
| # Y = Y if X.shape == Y.shape else None # for mask data | |
| return X,Y |