def main(): # During some time steps... # 1. Compute theta_hat by f_TRUE (1) # 2. Compute theta_hat by f_EST (2) # 3. Compute loss between (1) and (2) # 4. Optimize parameters of f_EST print('start exp: {} and {}'.format(args.model_dir, args.data_type)) # Simulation parameters and intial values const['del_t'] = float(1 / args.freq) # sampling time for dynamics T = args.freq * args.simT # number of operation for dynamics # Target trajectory if 'sine' in args.data_type and 'Hz' in args.data_type: target_traj = sin_target_traj( args.freq, args.simT, sine_type=args.data_type) elif 'random_walk' in args.data_type: target_traj = random_walk(T, args.data_type) elif 'sine_freq_variation' == args.data_type: freq_from = 0.5 freq_to = 10. sys_freq = args.freq simT = args.simT sine_type = 'sine_1Hz_10deg_0offset' target_traj = sin_freq_variation(freq_from, freq_to, sys_freq, simT, sine_type) elif 'sine_freq_variation_with_step' == args.data_type: freq_from = 0.5 freq_to = 10. sys_freq = args.freq simT = args.simT sine_type = 'sine_1Hz_10deg_0offset' target_traj = sin_freq_variation_with_step(freq_from, freq_to, sys_freq, simT, sine_type) elif 'step' in args.data_type: target_traj = step_target_traj(T, args.data_type) else: raise Exception('I dont know your targets') # initiate values t_OBS_vals = [ torch.FloatTensor([target_traj[0]]), torch.FloatTensor([target_traj[1]]), torch.FloatTensor([target_traj[2]]), torch.FloatTensor([target_traj[3]]) ] f1_EST_vals = [torch.zeros(1)] F_EST = torch.zeros(1) # NOTE 0 if f_est=0, 1 if f_est is oracle, 2 if f_est is MLP friction_type = args.ftype # for plotting time_stamp = [] target_history = [] obs_history = [] est_history = [] f1_obs_history = [] f1_est_history = [] F_est_history = [] # Define PID controller Kp = args.Kp Kd = args.Kd * Kp Ki = args.Ki * Kp pid_cont = PIDController(p=Kp, i=Ki, d=Kd, del_t=const['del_t'] * 10) # Define models TODO for now we ignore f2. f1_OBS_fn = RealFriction(const) f1_EST_fn = Friction_EST(args.hdim) # Define loss_fn, optimizer optimizer = torch.optim.Adam(f1_EST_fn.parameters(), lr=args.lr) loss_fn = nn.MSELoss() for t in range(4, T): # current target target = target_traj[t] # detach nodes for simplicity f1 = f1_EST_vals[-1].detach() # compute input force (F) at t-2 if t % 10 == 3: const['T_d'] = pid_cont.compute_torque(target, t_OBS_vals[-1]) F_EST = compute_input_force(const, t_OBS_vals[-1], f1) # compute frictions (f) at t-2 t_dot_OBS = (t_OBS_vals[-2] - t_OBS_vals[-3]) / const['del_t'] f1_OBS = f1_OBS_fn(t_OBS_vals[-2], t_OBS_vals[-3], F_EST) if friction_type == 0: f1_EST = torch.zeros(1) elif friction_type == 1: f1_EST = f1_OBS_fn(t_OBS_vals[-2], t_OBS_vals[-3], F_EST) elif friction_type == 2: f1_EST = f1_EST_fn(torch.cat([t_OBS_vals[-2], t_dot_OBS, F_EST])) else: raise NotImplementedError() # compute theta_hat (t) at t t_OBS = compute_theta_hat(const, t_OBS_vals[-1], t_OBS_vals[-2], t_OBS_vals[-3], F_EST, f1_OBS) t_EST = compute_theta_hat(const, t_OBS_vals[-1], t_OBS_vals[-2], t_OBS_vals[-3], F_EST, f1_EST) # Optimization # print(t, t_OBS, f1_OBS, F_EST, t_dot_OBS, target) if friction_type == 2: loss = loss_fn(t_EST, t_OBS) optimizer.zero_grad() loss.backward() optimizer.step() # print('loss={} at t={}'.format(loss.item(), t)) # store values to containers t_OBS_vals[-4] = t_OBS_vals[-3] t_OBS_vals[-3] = t_OBS_vals[-2] t_OBS_vals[-2] = t_OBS_vals[-1] t_OBS_vals[-1] = t_OBS f1_EST_vals[-1] = f1_EST # store history for plotting time_stamp.append(float(t / args.freq)) target_history.append(float(target.numpy())) obs_history.append(float(t_OBS.numpy())) est_history.append(float(t_EST.detach().numpy())) f1_obs_history.append(float(f1_OBS.detach().numpy())) f1_est_history.append(float(f1_EST.detach().numpy())) F_est_history.append(float(F_EST.detach().numpy())) # for debugging if np.isnan(t_OBS.numpy()): break # store hyper-parameters and settings params_dir = os.path.join(args.model_dir, args.data_type) if not os.path.exists(params_dir): os.makedirs(params_dir) params = OrderedDict(vars(args)) const_ord = OrderedDict(cast_dict_to_float(const)) with open(os.path.join(params_dir, 'params.json'), 'w') as f: json.dump(params, f) with open(os.path.join(params_dir, 'const.json'), 'w') as f: json.dump(const_ord, f) # store values for post-visualization if friction_type == 0: training_log_dir = os.path.join(params_dir, 'f_est=0', 'training') elif friction_type == 1: training_log_dir = os.path.join(params_dir, 'oracle', 'training') elif friction_type == 2: training_log_dir = os.path.join(params_dir, 'MLP', 'training') if not os.path.exists(training_log_dir): os.makedirs(training_log_dir) store_logs(time_stamp, target_history, obs_history, est_history, f1_obs_history, f1_est_history, F_est_history, training_log_dir) # save trained model if friction_type == 2: model_name = os.path.join(params_dir, 'MLP', 'f1_model') torch.save(f1_EST_fn.state_dict(), model_name) # visualize plot_theta(time_stamp, target_history, obs_history, est_history, training_log_dir)
def main(self): if self.uncertainty_sampling_method == 'mc_dropout': uncertainty_sampler = UncertaintySamplingMCDropout() self.args.weak_supervision_strategy = 'semi_supervised_active_learning' elif self.uncertainty_sampling_method == 'augmentations_based': uncertainty_sampler = UncertaintySamplingAugmentationBased() self.args.weak_supervision_strategy = 'semi_supervised_active_learning' elif self.uncertainty_sampling_method == 'entropy_based': uncertainty_sampler = UncertaintySamplingEntropyBased( verbose=True, uncertainty_sampling_method='entropy_based') self.args.weak_supervision_strategy = 'semi_supervised_active_learning' else: uncertainty_sampler = None self.args.weak_supervision_strategy = "random_sampling" dataset_cls = self.datasets[self.args.dataset]( root=self.args.root, add_labeled=self.args.add_labeled, advanced_transforms=True, merged=self.args.merged, remove_classes=self.args.remove_classes, oversampling=self.args.oversampling, unlabeled_subset_ratio=self.args.unlabeled_subset, expand_labeled=self.args.fixmatch_k_img, expand_unlabeled=self.args.fixmatch_k_img * self.args.fixmatch_mu, unlabeled_augmentations=True if self.uncertainty_sampling_method == 'augmentations_based' else False, seed=self.args.seed, start_labeled=self.args.start_labeled) base_dataset, labeled_dataset, unlabeled_dataset, labeled_indices, unlabeled_indices, test_dataset = \ dataset_cls.get_dataset() train_loader, unlabeled_loader, val_loader = create_loaders( self.args, labeled_dataset, unlabeled_dataset, test_dataset, labeled_indices, unlabeled_indices, self.kwargs, dataset_cls.unlabeled_subset_num) labeled_dataset_fix, unlabeled_dataset_fix = dataset_cls.get_datasets_fixmatch( base_dataset, labeled_indices, unlabeled_indices) self.args.lr = 0.0003 model, optimizer, _ = create_model_optimizer_scheduler( self.args, dataset_cls) if self.init == 'pretrained': model = load_pretrained(model) elif self.init == 'autoencoder': model, optimizer, _ = create_model_optimizer_autoencoder( self.args, dataset_cls) elif self.init == 'simclr': model, optimizer, _, _ = create_model_optimizer_simclr( self.args, dataset_cls) labeled_loader_fix = DataLoader(dataset=labeled_dataset_fix, batch_size=self.args.batch_size, shuffle=True, **self.kwargs) unlabeled_loader_fix = DataLoader(dataset=unlabeled_dataset_fix, batch_size=self.args.batch_size, shuffle=True, **self.kwargs) criterion_labeled = get_loss(self.args, dataset_cls.labeled_class_samples, reduction='none') criterion_unlabeled = get_loss(self.args, dataset_cls.labeled_class_samples, reduction='none') criterions = { 'labeled': criterion_labeled, 'unlabeled': criterion_unlabeled } model.zero_grad() best_recall, best_report, last_best_epochs = 0, None, 0 best_model = deepcopy(model) metrics_per_cycle = pd.DataFrame([]) metrics_per_epoch = pd.DataFrame([]) num_class_per_cycle = pd.DataFrame([]) self.args.start_epoch = 0 current_labeled = dataset_cls.start_labeled for epoch in range(self.args.start_epoch, self.args.fixmatch_epochs): train_loader_fix = zip(labeled_loader_fix, unlabeled_loader_fix) train_loss = self.train(train_loader_fix, model, optimizer, epoch, len(labeled_loader_fix), criterions, base_dataset.classes, last_best_epochs) val_loss, val_report = self.validate(val_loader, model, last_best_epochs, criterions) is_best = val_report['macro avg']['recall'] > best_recall last_best_epochs = 0 if is_best else last_best_epochs + 1 val_report = pd.concat([val_report, train_loss, val_loss], axis=1) metrics_per_epoch = pd.concat([metrics_per_epoch, val_report]) if epoch > self.args.labeled_warmup_epochs and last_best_epochs > self.args.add_labeled_epochs: metrics_per_cycle = pd.concat([metrics_per_cycle, best_report]) train_loader, unlabeled_loader, val_loader, labeled_indices, unlabeled_indices = \ perform_sampling(self.args, uncertainty_sampler, None, epoch, model, train_loader, unlabeled_loader, dataset_cls, labeled_indices, unlabeled_indices, labeled_dataset, unlabeled_dataset, test_dataset, self.kwargs, current_labeled, model) labeled_dataset_fix, unlabeled_dataset_fix = dataset_cls.get_datasets_fixmatch( base_dataset, labeled_indices, unlabeled_indices) labeled_loader_fix = DataLoader( dataset=labeled_dataset_fix, batch_size=self.args.batch_size, shuffle=True, **self.kwargs) unlabeled_loader_fix = DataLoader( dataset=unlabeled_dataset_fix, batch_size=self.args.batch_size, shuffle=True, **self.kwargs) current_labeled += self.args.add_labeled last_best_epochs = 0 if self.args.reset_model: if self.init == 'pretrained': model = load_pretrained(model) elif self.init == 'autoencoder': model, optimizer, _ = create_model_optimizer_autoencoder( self.args, dataset_cls) elif self.init == 'simclr': model, optimizer, _, self.args = create_model_optimizer_simclr( self.args, dataset_cls) if self.args.novel_class_detection: num_classes = [ np.sum( np.array(base_dataset.targets)[labeled_indices] == i) for i in range(len(base_dataset.classes)) ] num_class_per_cycle = pd.concat([ num_class_per_cycle, pd.DataFrame.from_dict( { cls: num_classes[i] for i, cls in enumerate(base_dataset.classes) }, orient='index').T ]) criterion_labeled = get_loss(self.args, dataset_cls.labeled_class_samples, reduction='none') criterion_unlabeled = get_loss( self.args, dataset_cls.labeled_class_samples, reduction='none') criterions = { 'labeled': criterion_labeled, 'unlabeled': criterion_unlabeled } else: best_recall = val_report['macro avg'][ 'recall'] if is_best else best_recall best_report = val_report if is_best else best_report best_model = deepcopy(model) if is_best else best_model save_checkpoint( self.args, { 'epoch': epoch + 1, 'state_dict': model.state_dict(), 'optimizer': optimizer.state_dict(), 'best_prec1': best_recall, }, is_best) if current_labeled > self.args.stop_labeled: break if self.args.store_logs: store_logs(self.args, metrics_per_cycle) store_logs(self.args, metrics_per_epoch, log_type='epoch_wise') store_logs(self.args, num_class_per_cycle, log_type='novel_class') return best_recall
def main(self): dataset_class = self.datasets[self.args.dataset]( root=self.args.root, add_labeled=self.args.add_labeled, advanced_transforms=True, merged=self.args.merged, remove_classes=self.args.remove_classes, oversampling=self.args.oversampling, unlabeled_subset_ratio=self.args.unlabeled_subset, seed=self.args.seed, start_labeled=self.args.start_labeled) _, labeled_dataset, unlabeled_dataset, labeled_indices, unlabeled_indices, test_dataset = \ dataset_class.get_dataset() labeled_loader, unlabeled_loader, val_loader = create_loaders( self.args, labeled_dataset, unlabeled_dataset, test_dataset, labeled_indices, unlabeled_indices, self.kwargs, dataset_class.unlabeled_subset_num) base_dataset = dataset_class.get_base_dataset_autoencoder() base_loader = create_base_loader(base_dataset, self.kwargs, self.args.batch_size) reconstruction_loss_log = [] bce_loss = nn.BCELoss().cuda() l1_loss = nn.L1Loss() l2_loss = nn.MSELoss() ssim_loss = SSIM(size_average=True, data_range=1.0, nonnegative_ssim=True) criterions_reconstruction = { 'bce': bce_loss, 'l1': l1_loss, 'l2': l2_loss, 'ssim': ssim_loss } criterion_cl = get_loss(self.args, dataset_class.labeled_class_samples, reduction='none') model, optimizer, self.args = create_model_optimizer_autoencoder( self.args, dataset_class) best_loss = np.inf metrics_per_cycle = pd.DataFrame([]) metrics_per_epoch = pd.DataFrame([]) num_class_per_cycle = pd.DataFrame([]) best_recall, best_report, last_best_epochs = 0, None, 0 best_model = deepcopy(model) self.args.start_epoch = 0 self.args.weak_supervision_strategy = "random_sampling" current_labeled = dataset_class.start_labeled for epoch in range(self.args.start_epoch, self.args.epochs): cl_train_loss, losses_avg_reconstruction, losses_reconstruction = \ self.train(labeled_loader, model, criterion_cl, optimizer, last_best_epochs, epoch, criterions_reconstruction, base_loader) val_loss, val_report = self.validate(val_loader, model, last_best_epochs, criterion_cl) reconstruction_loss_log.append(losses_avg_reconstruction.tolist()) best_loss = min(best_loss, losses_reconstruction.avg) is_best = val_report['macro avg']['recall'] > best_recall last_best_epochs = 0 if is_best else last_best_epochs + 1 val_report = pd.concat([val_report, cl_train_loss, val_loss], axis=1) metrics_per_epoch = pd.concat([metrics_per_epoch, val_report]) if epoch > self.args.labeled_warmup_epochs and last_best_epochs > self.args.add_labeled_epochs: metrics_per_cycle = pd.concat([metrics_per_cycle, best_report]) labeled_loader, unlabeled_loader, val_loader, labeled_indices, unlabeled_indices = \ perform_sampling(self.args, None, None, epoch, model, labeled_loader, unlabeled_loader, dataset_class, labeled_indices, unlabeled_indices, labeled_dataset, unlabeled_dataset, test_dataset, self.kwargs, current_labeled, model) current_labeled += self.args.add_labeled last_best_epochs = 0 if self.args.reset_model: model, optimizer, self.args = create_model_optimizer_autoencoder( self.args, dataset_class) if self.args.novel_class_detection: num_classes = [ np.sum( np.array(base_dataset.targets)[labeled_indices] == i) for i in range(len(base_dataset.classes)) ] num_class_per_cycle = pd.concat([ num_class_per_cycle, pd.DataFrame.from_dict( { cls: num_classes[i] for i, cls in enumerate(base_dataset.classes) }, orient='index').T ]) criterion_cl = get_loss(self.args, dataset_class.labeled_class_samples, reduction='none') else: best_recall = val_report['macro avg'][ 'recall'] if is_best else best_recall best_report = val_report if is_best else best_report best_model = deepcopy(model) if is_best else best_model if current_labeled > self.args.stop_labeled: break save_checkpoint( self.args, { 'epoch': epoch + 1, 'state_dict': model.state_dict(), 'best_prec1': best_recall, }, is_best) if self.args.store_logs: store_logs(self.args, pd.DataFrame(reconstruction_loss_log, columns=['bce', 'l1', 'l2', 'ssim']), log_type='ae_loss') store_logs(self.args, metrics_per_cycle) store_logs(self.args, metrics_per_epoch, log_type='epoch_wise') store_logs(self.args, num_class_per_cycle, log_type='novel_class') self.model = model return model
def evaluate(const, params, ftype): print('Start evaluation exp: {} and {} and {}'.format( args.model_dir, args.data_type, args.ftype)) # Total running steps T = params['freq'] * params['simT'] # Target trajectory for evaluation if 'sine' in args.eval_type and 'Hz' in args.eval_type: target_traj = sin_target_traj(params['freq'], params['simT'], sine_type=args.eval_type) elif 'random_walk' in args.eval_type: target_traj = random_walk(T, args.eval_type) elif 'sine_freq_variation' == args.eval_type: freq_from = 0.5 freq_to = 10. sys_freq = params['freq'] simT = params['simT'] sine_type = 'sine_1Hz_10deg_0offset' target_traj = sin_freq_variation(freq_from, freq_to, sys_freq, simT, sine_type) elif 'sine_freq_variation_with_step' == args.eval_type: freq_from = 0.5 freq_to = 10. sys_freq = params['freq'] simT = params['simT'] sine_type = 'sine_1Hz_10deg_0offset' target_traj = sin_freq_variation_with_step(freq_from, freq_to, sys_freq, simT, sine_type) elif 'step' in args.eval_type: target_traj = step_target_traj(T, args.eval_type) else: raise Exception('I dont know your targets') # initiate values if 'step' in args.eval_type: t_OBS_vals = [ torch.FloatTensor([0]), torch.FloatTensor([0]), torch.FloatTensor([0]), torch.FloatTensor([0]) ] else: t_OBS_vals = [ torch.FloatTensor([target_traj[0]]), torch.FloatTensor([target_traj[1]]), torch.FloatTensor([target_traj[2]]), torch.FloatTensor([target_traj[3]]) ] f1_EST_vals = [torch.zeros(1)] F_EST = torch.zeros(1) # for plotting time_stamp = [] target_history = [] obs_history = [] est_history = [] f1_obs_history = [] f1_est_history = [] F_est_history = [] # Define PID controller Kp = params['Kp'] Kd = params['Kd'] * Kp Ki = params['Ki'] * Kp pid_cont = PIDController(p=Kp, i=Ki, d=Kd, del_t=const['del_t'] * 10) # Define models TODO for now we ignore f2. f1_OBS_fn = RealFriction(const) f1_EST_fn = Friction_EST(params['hdim']) if ftype == 2: state_dict_path = os.path.join(args.model_dir, args.data_type, 'MLP', 'f1_model') state_dict = torch.load(state_dict_path) f1_EST_fn.load_state_dict(state_dict) for t in range(4, T): # current target target = target_traj[t] # detach nodes for simplicity f1 = f1_EST_vals[-1].detach() # compute input force (F) at t-2 if t % 10 == 3: const['T_d'] = pid_cont.compute_torque(target, t_OBS_vals[-1]) F_EST = compute_input_force(const, t_OBS_vals[-1], f1) # compute frictions (f) at t-2 t_dot_OBS = (t_OBS_vals[-2] - t_OBS_vals[-3]) / const['del_t'] f1_OBS = f1_OBS_fn(t_OBS_vals[-2], t_OBS_vals[-3], F_EST) if ftype == 0: f1_EST = torch.zeros(1) elif ftype == 1: f1_EST = f1_OBS_fn(t_OBS_vals[-2], t_OBS_vals[-3], F_EST) elif ftype == 2: f1_EST = f1_EST_fn(torch.cat([t_OBS_vals[-2], t_dot_OBS, F_EST])) else: raise NotImplementedError() # compute theta_hat (t) at t t_OBS = compute_theta_hat(const, t_OBS_vals[-1], t_OBS_vals[-2], t_OBS_vals[-3], F_EST, f1_OBS) t_EST = compute_theta_hat(const, t_OBS_vals[-1], t_OBS_vals[-2], t_OBS_vals[-3], F_EST, f1_EST) # store values to containers t_OBS_vals[-4] = t_OBS_vals[-3] t_OBS_vals[-3] = t_OBS_vals[-2] t_OBS_vals[-2] = t_OBS_vals[-1] t_OBS_vals[-1] = t_OBS f1_EST_vals[-1] = f1_EST # store history for plotting time_stamp.append(float(t / params['freq'])) target_history.append(float(target.numpy())) obs_history.append(float(t_OBS.numpy())) est_history.append(float(t_EST.detach().numpy())) f1_obs_history.append(float(f1_OBS.detach().numpy())) f1_est_history.append(float(f1_EST.detach().numpy())) F_est_history.append(float(F_EST.detach().numpy())) # for debugging # if np.isnan(t_OBS.numpy()): # break # store values for post-visualization params_dir = os.path.join(args.model_dir, args.data_type) if ftype == 0: eval_log_dir = os.path.join(params_dir, 'f_est=0', 'evaluation', args.eval_type) elif ftype == 1: eval_log_dir = os.path.join(params_dir, 'oracle', 'evaluation', args.eval_type) elif ftype == 2: eval_log_dir = os.path.join(params_dir, 'MLP', 'evaluation', args.eval_type) if not os.path.exists(eval_log_dir): os.makedirs(eval_log_dir) store_logs(time_stamp, target_history, obs_history, est_history, f1_obs_history, f1_est_history, F_est_history, eval_log_dir) # visualize plot_theta(time_stamp, target_history, obs_history, est_history, eval_log_dir)
def train_validate_classifier(self): if self.uncertainty_sampling_method == 'mc_dropout': uncertainty_sampler = UncertaintySamplingMCDropout() self.args.weak_supervision_strategy = 'semi_supervised_active_learning' elif self.uncertainty_sampling_method == 'augmentations_based': uncertainty_sampler = UncertaintySamplingAugmentationBased() self.args.weak_supervision_strategy = 'semi_supervised_active_learning' elif self.uncertainty_sampling_method == 'entropy_based': uncertainty_sampler = UncertaintySamplingEntropyBased( verbose=True, uncertainty_sampling_method='entropy_based') self.args.weak_supervision_strategy = 'semi_supervised_active_learning' else: uncertainty_sampler = None self.args.weak_supervision_strategy = "random_sampling" dataset_class = self.datasets[self.args.dataset]( root=self.args.root, add_labeled=self.args.add_labeled, advanced_transforms=True, merged=self.args.merged, remove_classes=self.args.remove_classes, oversampling=self.args.oversampling, unlabeled_subset_ratio=self.args.unlabeled_subset, unlabeled_augmentations=True if self.uncertainty_sampling_method == 'augmentations_based' else False, seed=self.args.seed, k_medoids=self.args.k_medoids, k_medoids_model=self.model, k_medoids_n_clusters=self.args.k_medoids_n_clusters, start_labeled=self.args.start_labeled) base_dataset, labeled_dataset, unlabeled_dataset, labeled_indices, unlabeled_indices, test_dataset = \ dataset_class.get_dataset() train_loader, unlabeled_loader, val_loader = create_loaders( self.args, labeled_dataset, unlabeled_dataset, test_dataset, labeled_indices, unlabeled_indices, self.kwargs, dataset_class.unlabeled_subset_num) model = self.model criterion = get_loss(self.args, dataset_class.labeled_class_samples, reduction='none') optimizer = torch.optim.Adam(model.parameters()) metrics_per_cycle = pd.DataFrame([]) metrics_per_epoch = pd.DataFrame([]) num_class_per_cycle = pd.DataFrame([]) best_recall, best_report, last_best_epochs = 0, None, 0 best_model = deepcopy(model) self.args.start_epoch = 0 current_labeled = dataset_class.start_labeled for epoch in range(self.args.start_epoch, self.args.epochs): train_loss = self.train_classifier(train_loader, model, criterion, optimizer, last_best_epochs, epoch) val_loss, val_report = self.validate_classifier( val_loader, model, last_best_epochs, criterion) is_best = val_report['macro avg']['recall'] > best_recall last_best_epochs = 0 if is_best else last_best_epochs + 1 val_report = pd.concat([val_report, train_loss, val_loss], axis=1) metrics_per_epoch = pd.concat([metrics_per_epoch, val_report]) if epoch > self.args.labeled_warmup_epochs and last_best_epochs > self.args.add_labeled_epochs: metrics_per_cycle = pd.concat([metrics_per_cycle, best_report]) train_loader, unlabeled_loader, val_loader, labeled_indices, unlabeled_indices = \ perform_sampling(self.args, uncertainty_sampler, None, epoch, model, train_loader, unlabeled_loader, dataset_class, labeled_indices, unlabeled_indices, labeled_dataset, unlabeled_dataset, test_dataset, self.kwargs, current_labeled, model) current_labeled += self.args.add_labeled last_best_epochs = 0 if self.args.reset_model: model, optimizer, _, self.args = create_model_optimizer_simclr( self.args, dataset_class) optimizer = torch.optim.Adam(model.parameters()) if self.args.novel_class_detection: num_classes = [ np.sum( np.array(base_dataset.targets)[labeled_indices] == i) for i in range(len(base_dataset.classes)) ] num_class_per_cycle = pd.concat([ num_class_per_cycle, pd.DataFrame.from_dict( { cls: num_classes[i] for i, cls in enumerate(base_dataset.classes) }, orient='index').T ]) criterion = get_loss(self.args, dataset_class.labeled_class_samples, reduction='none') else: best_recall = val_report['macro avg'][ 'recall'] if is_best else best_recall best_report = val_report if is_best else best_report best_model = deepcopy(model) if is_best else best_model if current_labeled > self.args.stop_labeled: break if self.args.store_logs: store_logs(self.args, metrics_per_cycle) store_logs(self.args, metrics_per_epoch, log_type='epoch_wise') store_logs(self.args, num_class_per_cycle, log_type='novel_class') return best_recall
def main(self): dataset_cl = self.datasets[self.args.dataset](root=self.args.root, add_labeled=self.args.add_labeled, advanced_transforms=True, merged=self.args.merged, remove_classes=self.args.remove_classes, oversampling=self.args.oversampling, unlabeled_subset_ratio=self.args.unlabeled_subset, seed=self.args.seed, start_labeled=self.args.start_labeled) base_dataset, labeled_dataset, unlabeled_dataset, labeled_indices, unlabeled_indices, test_dataset = \ dataset_cl.get_dataset() train_loader, unlabeled_loader, val_loader = create_loaders(self.args, labeled_dataset, unlabeled_dataset, test_dataset, labeled_indices, unlabeled_indices, self.kwargs, dataset_cl.unlabeled_subset_num) model_backbone, optimizer_backbone, _ = create_model_optimizer_scheduler(self.args, dataset_cl) model_module = LossNet().cuda() optimizer_module = torch.optim.Adam(model_module.parameters()) models = {'backbone': model_backbone, 'module': model_module} optimizers = {'backbone': optimizer_backbone, 'module': optimizer_module} criterion_backbone = get_loss(self.args, dataset_cl.labeled_class_samples, reduction='none') criterions = {'backbone': criterion_backbone, 'module': loss_module_objective_func} uncertainty_sampler = UncertaintySamplingEntropyBased(verbose=True, uncertainty_sampling_method=self.args. uncertainty_sampling_method) current_labeled = dataset_cl.start_labeled metrics_per_cycle = pd.DataFrame([]) metrics_per_epoch = pd.DataFrame([]) num_class_per_cycle = pd.DataFrame([]) print_args(self.args) best_recall, best_report, last_best_epochs = 0, None, 0 best_model = deepcopy(models['backbone']) for epoch in range(self.args.start_epoch, self.args.epochs): train_loss = self.train(train_loader, models, optimizers, criterions, epoch, last_best_epochs) val_loss, val_report = self.validate(val_loader, models, criterions, last_best_epochs) is_best = val_report['macro avg']['recall'] > best_recall last_best_epochs = 0 if is_best else last_best_epochs + 1 val_report = pd.concat([val_report, train_loss, val_loss], axis=1) metrics_per_epoch = pd.concat([metrics_per_epoch, val_report]) if epoch > self.args.labeled_warmup_epochs and last_best_epochs > self.args.add_labeled_epochs: metrics_per_cycle = pd.concat([metrics_per_cycle, best_report]) train_loader, unlabeled_loader, val_loader, labeled_indices, unlabeled_indices = \ perform_sampling(self.args, uncertainty_sampler, None, epoch, models, train_loader, unlabeled_loader, dataset_cl, labeled_indices, unlabeled_indices, labeled_dataset, unlabeled_dataset, test_dataset, self.kwargs, current_labeled, None) current_labeled += self.args.add_labeled last_best_epochs = 0 if self.args.reset_model: model_backbone, optimizer_backbone, scheduler_backbone = \ create_model_optimizer_scheduler(self.args, dataset_cl) model_module, optimizer_module = create_model_optimizer_loss_net() models = {'backbone': model_backbone, 'module': model_module} optimizers = {'backbone': optimizer_backbone, 'module': optimizer_module} if self.args.novel_class_detection: num_classes = [np.sum(np.array(base_dataset.targets)[labeled_indices] == i) for i in range(len(base_dataset.classes))] num_class_per_cycle = pd.concat([num_class_per_cycle, pd.DataFrame.from_dict({cls: num_classes[i] for i, cls in enumerate(base_dataset.classes)}, orient='index').T]) criterion_backbone = get_loss(self.args, dataset_cl.labeled_class_samples, reduction='none') criterions = {'backbone': criterion_backbone, 'module': loss_module_objective_func} else: best_recall = val_report['macro avg']['recall'] if is_best else best_recall best_report = val_report if is_best else best_report best_model = deepcopy(models['backbone']) if is_best else best_model if current_labeled > self.args.stop_labeled: break save_checkpoint(self.args, { 'epoch': epoch + 1, 'state_dict': model_backbone.state_dict(), 'best_prec1': best_recall, }, is_best) if self.args.store_logs: store_logs(self.args, metrics_per_cycle) store_logs(self.args, metrics_per_epoch, log_type='epoch_wise') store_logs(self.args, num_class_per_cycle, log_type='novel_class') return best_recall
def train(self): dataset_class = self.datasets[self.args.dataset]( root=self.args.root, add_labeled=self.args.add_labeled, advanced_transforms=False, merged=self.args.merged, remove_classes=self.args.remove_classes, oversampling=self.args.oversampling, unlabeled_subset_ratio=self.args.unlabeled_subset, seed=self.args.seed, start_labeled=self.args.start_labeled) base_dataset = dataset_class.get_base_dataset_autoencoder() train_loader = create_base_loader(base_dataset, self.kwargs, self.args.batch_size) training_loss_log = [] l1_loss = nn.L1Loss() l2_loss = nn.MSELoss() ssim_loss = SSIM(size_average=True, data_range=1.0, nonnegative_ssim=True) criterions = {'l1': l1_loss, 'l2': l2_loss, 'ssim': ssim_loss} model, optimizer, self.args = create_model_optimizer_autoencoder( self.args, dataset_class) best_loss = np.inf for epoch in range(self.args.start_epoch, self.args.autoencoder_train_epochs): model.train() batch_time = AverageMeter() losses = AverageMeter() losses_sum = np.zeros(len(criterions.keys())) end = time.time() for i, (data_x, data_y) in enumerate(train_loader): data_x = data_x.cuda(non_blocking=True) output = model(data_x) losses_alt = np.array([ v(output, data_x).cpu().detach().data.item() for v in criterions.values() ]) losses_alt[-1] = 1 - losses_alt[-1] losses_sum = losses_sum + losses_alt loss = criterions['l2']( output, data_x) + (1 - criterions['ssim'](output, data_x)) losses.update(loss.data.item(), data_x.size(0)) optimizer.zero_grad() loss.backward() optimizer.step() batch_time.update(time.time() - end) end = time.time() if i % self.args.print_freq == 0: print('Epoch: [{0}][{1}/{2}]\t' 'Time {batch_time.val:.3f} ({batch_time.avg:.3f})\t' 'Loss {loss.val:.4f} ({loss.avg:.4f})\t'.format( epoch, i, len(train_loader), batch_time=batch_time, loss=losses)) losses_avg = losses_sum / len(train_loader) training_loss_log.append(losses_avg.tolist()) is_best = best_loss > losses.avg best_loss = min(best_loss, losses.avg) save_checkpoint( self.args, { 'epoch': epoch + 1, 'state_dict': model.state_dict(), 'best_prec1': best_loss, }, is_best) if self.args.store_logs and not self.args.resume: store_logs(self.args, pd.DataFrame(training_loss_log, columns=['l1', 'l2', 'ssim']), log_type='ae_loss') self.model = model return model