diff --git a/args_helper.py b/args_helper.py index f5b0a487..7a8e121a 100644 --- a/args_helper.py +++ b/args_helper.py @@ -206,9 +206,34 @@ def parse_arguments(self, jupyter_mode=False): "--round", type=str, default='naive', - help='rounding technique to use |naive|prob|pb|' + help='rounding technique to use |naive|prob|pb|majority|greedy|' # naive: threshold(0.5), prob: probabilistic rounding, pb: pseudo-boolean paper's choice (RoundDown) + # round scheme for test (use same scheme for train) ) + parser.add_argument( + "--round_train", + type=str, + default='naive', + help='rounding technique to use |naive|prob|pb|majority|greedy|' + # naive: threshold(0.5), prob: probabilistic rounding, pb: pseudo-boolean paper's choice (RoundDown) + # round scheme for test (use same scheme for train) + ) + ''' + parser.add_argument( + "--random_round_train", + action="store_true", + default=False, + help="randomized rounding for hc (at train)" + ) + ''' + parser.add_argument( + "--num_coin_flip_round", + type=int, + default=5, + help="Number of random coin flipping: 1 | 5 | 15 " + ) + + parser.add_argument( '--noise', action='store_true', @@ -251,19 +276,19 @@ def parse_arguments(self, jupyter_mode=False): type=int, help="rounding period for hypercube" ) - parser.add_argument( - "--num-round", - type=int, - default=1, - help='number of different models testing in rounding' - ) + # parser.add_argument( + # "--num-round", + # type=int, + # default=1, + # help='number of different models testing in rounding' + # ) # do we need it? - parser.add_argument( - "--num-test", - type=int, - default=1, - help='number of different models testing in prob rounding' - ) + # parser.add_argument( + # "--num-test", + # type=int, + # default=1, + # help='number of different models testing in prob rounding' + # ) parser.add_argument( "--save-model", action='store_true', @@ -837,6 +862,8 @@ def parse_arguments(self, jupyter_mode=False): default=False, help="Enable this to unprune weights if possible, before fine-tune" ) + + parser.add_argument( "--override-prune-rate", action="store_true", diff --git a/cifar_exec_GD.sh b/cifar_exec_GD.sh index b87c32b6..e3f7f56e 100644 --- a/cifar_exec_GD.sh +++ b/cifar_exec_GD.sh @@ -14,21 +14,44 @@ ### ResNet-20 #python main.py --config configs/ep/resnet20/resnet20_sc_ep.yml #python main.py --config configs/ep/resnet20/resnet20_sc_global_ep.yml -python main.py --config config_current_best.yml --run_idx 1 +#python main.py --config config_current_best.yml --run_idx 0 + +# Add finetune-loss +#python main.py --config config_current_best.yml --run_idx 1 ## testing adding finetune loss #python main.py --config config1.yml --run_idx 1 # #python main.py --config config2.yml --run_idx 2 - - - - #python main.py --config configs/hypercube/resnet20/resnet20_quantized_iter_hc_0_5_MAML_1.yml --run_idx 1 #python main.py --config configs/hypercube/resnet20/resnet20_quantized_iter_hc_0_5_MAML_1e-2.yml --run_idx 1 #python main.py --config configs/hypercube/resnet20/resnet20_quantized_iter_hc_0_5_MAML_1e-4.yml --run_idx 2 #python main.py --config configs/hypercube/resnet20/resnet20_quantized_iter_hc_0_5_MAML_0.yml --run_idx 3 + +# Random rounding (majority/greedy, num_coin_flips, train, test) +#python main.py --config config_rr1.yml --run_idx 1 +#python main.py --config config_rr2.yml --run_idx 2 + +## Dec.16 +#python main.py --config configs/hypercube/resnet20/random_rounding/target_sparsity_1_4_naive_rounding.yml # GPU 0 +#python main.py --config configs/hypercube/resnet20/random_rounding/target_sparsity_1_4_random_rounding_majority_5_test_only.yml # gpu 0 +#python main.py --config configs/hypercube/resnet20/random_rounding/target_sparsity_1_4_random_rounding_majority_15_test_only.yml # gpu 1 +#python main.py --config configs/hypercube/resnet20/random_rounding/target_sparsity_1_4_random_rounding_greedy_5_test_only.yml # gpu 2 +#python main.py --config configs/hypercube/resnet20/random_rounding/target_sparsity_1_4_random_rounding_greedy_15_test_only.yml # gpu 3 + +python main.py --config configs/hypercube/resnet20/random_rounding/target_sparsity_1_4_random_rounding_majority_5_train_only.yml # gpu 1 +#python main.py --config configs/hypercube/resnet20/random_rounding/target_sparsity_1_4_random_rounding_majority_15_train_only.yml # gpu 1 + +# python main.py --config configs/hypercube/resnet20/random_rounding/target_sparsity_1_4_random_rounding_majority_5_train_and_test.yml +# python main.py --config configs/hypercube/resnet20/random_rounding/target_sparsity_1_4_random_rounding_majority_15_train_and_test.yml +# python main.py --config configs/hypercube/resnet20/random_rounding/target_sparsity_1_4_random_rounding_greedy_5_train_and_test.yml +# python main.py --config configs/hypercube/resnet20/random_rounding/target_sparsity_1_4_random_rounding_greedy_15_train_and_test.yml + + + + + #python main.py --config config10.yml --run_idx 10 #> log_config$r 2>&1 :< best_train_acc: + best_train_acc = train_acc1 + best_model = cp_model + print('trial_idx: {}, best_train_acc: {}'.format(trial_idx, best_train_acc)) + acc1, acc5, acc10 = validate(data.val_loader, best_model, criterion, parser_args, writer, epoch) + cp_model = best_model + else: cp_model = round_model(model, parser_args.round, noise=parser_args.noise, ratio=parser_args.noise_ratio, rank=parser_args.gpu) acc1, acc5, acc10 = validate(data.val_loader, cp_model, criterion, parser_args, writer, epoch) - acc_avg += acc1 - acc_avg /= parser_args.num_test - acc1 = acc_avg print('Acc after rounding: {}'.format(acc1)) else: acc1, acc5, acc10 = validate(data.val_loader, model, criterion, parser_args, writer, epoch) diff --git a/utils/conv_type.py b/utils/conv_type.py index d58b67fc..8216f3c8 100644 --- a/utils/conv_type.py +++ b/utils/conv_type.py @@ -78,8 +78,25 @@ def forward(ctx, scores, bias_scores, k, scores_prune_threshold=-np.inf, bias_sc out = torch.gt(scores, torch.ones_like(scores)*scores_prune_threshold).float() bias_out = torch.gt(bias_scores, torch.ones_like(bias_scores)*bias_scores_prune_threshold).float() else: - out = torch.gt(scores, torch.ones_like(scores)*parser_args.quantize_threshold).float() - bias_out = torch.gt(bias_scores, torch.ones_like(bias_scores)*parser_args.quantize_threshold).float() + if parser_args.round_train == 'naive': + out = torch.gt(scores, torch.ones_like(scores)*parser_args.quantize_threshold).float() + bias_out = torch.gt(bias_scores, torch.ones_like(bias_scores)*parser_args.quantize_threshold).float() + elif parser_args.round_train == 'one_flip': + out = torch.bernoulli(torch.clamp(scores, 0, 1)) + bias_out = torch.bernoulli(torch.clamp(bias_scores, 0, 1)) + elif parser_args.round_train == 'majority': + # flip 5 coins and take dimension-wise majority voting + out = torch.zeros_like(scores) + bias_out = torch.zeros_like(bias_scores) + for flip_iter in range(parser_args.num_coin_flip_round): + out += torch.bernoulli(torch.clamp(scores, 0, 1)) + bias_out += torch.bernoulli(torch.clamp(bias_scores, 0, 1)) + out = torch.gt(out, torch.ones_like(out)*np.floor(parser_args.num_coin_flip_round/2)).float() + bias_out = torch.gt(bias_out, torch.ones_like(bias_out)*np.floor(parser_args.num_coin_flip_round/2)).float() + elif parser_args.round_train == 'greedy': + # compute loss of 5 coin flips and take the best one (how to compute loss?) + #-> need to do outside of this function (here, just randomly pick the subnetwork, and do the comparison at outside) + raise NotImplementedError else: print("INVALID PRUNING ALGO") diff --git a/utils/net_utils.py b/utils/net_utils.py index e3860523..e474cf46 100644 --- a/utils/net_utils.py +++ b/utils/net_utils.py @@ -248,14 +248,14 @@ def round_model(model, round_scheme, noise=False, ratio=0.0, rank=None): else: cp_model = copy.deepcopy(model) for name, params in cp_model.named_parameters(): - if ".score" in name: + if ".score" in name: # or (parser_args.bias and ".bias_score" in name): if noise: delta = torch.randn_like(params.data)*ratio params.data += delta if round_scheme == 'naive': params.data = torch.gt(params.data, torch.ones_like(params.data)*parser_args.quantize_threshold).int().float() - elif round_scheme == 'prob': + elif round_scheme in ['prob', 'greedy']: params.data = torch.clamp(params.data, 0.0, 1.0) params.data = torch.bernoulli(params.data).float() elif round_scheme == 'naive_prob': @@ -268,6 +268,16 @@ def round_model(model, round_scheme, noise=False, ratio=0.0, rank=None): params.data = torch.gt(params.data, torch.ones_like(params.data)*0.5).int().float() elif round_scheme == 'all_ones': params.data = torch.ones_like(params.data) + elif round_scheme == 'majority': + # just for debug + #params.data = torch.gt(params.data, torch.ones_like(params.data)*parser_args.quantize_threshold).int().float() + + #pdb.set_trace() + temp = torch.zeros_like(params.data) + for flip_iter in range(parser_args.num_coin_flip_round): + temp += torch.bernoulli(torch.clamp(params.data, 0.0, 1.0)) + temp = torch.gt(temp, torch.ones_like(temp)*np.floor(parser_args.num_coin_flip_round/2)).int().float() + params.data = temp else: print("INVALID ROUNDING") print("EXITING")