def update_one_fold(data_container, model, attack, x_train, y_train, x_eval, y_eval): dim = data_container.dim_data num_classes = data_container.num_classes dc = CustomDataContainer(x_train, y_train, x_eval, y_eval, name='IRIS_FOLD', data_type=data_container.data_type, num_classes=num_classes, dim_data=dim) dc(normalize=True) mc = ModelContainerPT(model, dc) mc.load(MODEL_FILE) accuracy = mc.evaluate(x_eval, y_eval) print(f'Accuracy on clean samples: {accuracy}') ad = ApplicabilityDomainContainer(mc, hidden_model=model.hidden_model, k2=K2, reliability=RELIABILITY, sample_ratio=SAMPLE_RATIO, kappa=KAPPA, confidence=CONFIDENCE) adv, pred_adv, x_clean, y_true = attack.generate(use_testset=False, x=x_eval) accuracy = mc.evaluate(adv, y_true) print(f'Accuracy on adv. examples: {accuracy}') max_scores = np.zeros(2, dtype=np.float32) # Search parameters for Stage 2 zeta = RELIABILITY k2 = K2 # find best k2 k2, max_score = search_param(ad, update_k2, def_stage2, K_RANGE, 1, zeta, adv, pred_adv, x_clean, y_true) logger.debug('Found best k2: %i with score: %i', k2, max_score) # find best zeta zeta, max_scores[0] = search_param(ad, update_zeta, def_stage2, Z_RANGE, 0.1, k2, adv, pred_adv, x_clean, y_true) logger.debug('Found best zeta: %f with score: %i', zeta, max_scores[0]) # Search parameters for Stage 3 kappa = KAPPA gamma = CONFIDENCE # find kappa # kappa, max_score = search_param( # ad, update_kappa, def_stage3, KAPPA_RANGE, 1, gamma, # adv, pred_adv, x_clean, y_true) # logger.debug('Found best kappa: %i with score: %i', kappa, max_score) # find parameter gamma gamma, max_scores[1] = search_param(ad, update_gamma, def_stage3, GAMMA_RANGE, 0.1, kappa, adv, pred_adv, x_clean, y_true) logger.debug('Found best gamma: %f with score: %i', gamma, max_scores[1]) return k2, zeta, kappa, gamma, np.sum(max_scores)
def setUpClass(cls): master_seed(SEED) logger.info('Starting %s data container...', NAME) cls.dc = DataContainer(DATASET_LIST[NAME], get_data_path()) cls.dc(shuffle=True) model = MnistCnnV2() logger.info('Using model: %s', model.__class__.__name__) cls.mc = ModelContainerPT(model, cls.dc) filename = get_pt_model_filename(MnistCnnV2.__name__, NAME, MAX_EPOCHS) file_path = os.path.join('save', filename) if not os.path.exists(file_path): cls.mc.fit(max_epochs=MAX_EPOCHS, batch_size=BATCH_SIZE) cls.mc.save(filename, overwrite=True) else: logger.info('Use saved parameters from %s', filename) cls.mc.load(file_path) accuracy = cls.mc.evaluate(cls.dc.x_test, cls.dc.y_test) logger.info('Accuracy on test set: %f', accuracy) hidden_model = model.hidden_model logger.info('sample_ratio: %f', SAMPLE_RATIO) cls.ad = ApplicabilityDomainContainer( cls.mc, hidden_model=hidden_model, k2=9, reliability=1.6, sample_ratio=SAMPLE_RATIO, kappa=10, confidence=0.9, ) cls.ad.fit() # shuffle the test set x_test = cls.dc.x_test y_test = cls.dc.y_test shuffled_indices = np.random.permutation(len(x_test))[:NUM_ADV] cls.x = x_test[shuffled_indices] cls.y = y_test[shuffled_indices] logger.info('# of test set: %d', len(cls.x))
def experiment(data_name, params): # select data dc = get_data_container( data_name, use_shuffle=True, use_normalize=True, ) # train the model classifier = ExtraTreeClassifier( criterion='gini', splitter='random', ) mc = ModelContainerTree(classifier, dc) mc.fit() # train Applicability Domain ad = ApplicabilityDomainContainer( mc, mc.hidden_model, **params) ad.fit() # no more than 1000 samples are required x = dc.x_test y = dc.y_test if len(x) > 1000: x = x[:1000] y = y[:1000] accuracy = mc.evaluate(x, y) logger.info('Accuracy on clean: %f', accuracy) blocked_indices = ad.detect(x) logger.info('Blocked %d/%d samples on clean', len(blocked_indices), len(y)) num_blk_clean = len(blocked_indices) # generate adversarial examples art_classifier = SklearnClassifier(classifier) try: attack = DecisionTreeAttack(art_classifier) adv = attack.generate(x) except IndexError as error: # Output expected IndexErrors. logger.error(error) return num_blk_clean, -1 accuracy = mc.evaluate(adv, y) logger.info('Accuracy on DecisionTreeAttack: %f', accuracy) blocked_indices = ad.detect(adv) logger.info('Blocked %d/%d samples on DecisionTreeAttack', len(blocked_indices), len(adv)) num_blk_adv = len(blocked_indices) return num_blk_clean, num_blk_adv
def setUpClass(cls): master_seed(SEED) logger.info('Starting %s data container...', NAME) cls.dc = DataContainer(DATASET_LIST[NAME], get_data_path()) cls.dc(shuffle=True) model = CifarCnn() logger.info('Using model: %s', model.__class__.__name__) cls.mc = ModelContainerPT(model, cls.dc) file_path = os.path.join('save', FILE_NAME) if not os.path.exists(file_path): raise Exception('Where is the pretrained file?!') else: logger.info('Use saved parameters from %s', FILE_NAME) cls.mc.load(file_path) accuracy = cls.mc.evaluate(cls.dc.x_test, cls.dc.y_test) logger.info('Accuracy on test set: %f', accuracy) hidden_model = model.hidden_model logger.info('sample_ratio: %f', SAMPLE_RATIO) cls.ad = ApplicabilityDomainContainer( cls.mc, hidden_model=hidden_model, k2=9, reliability=1.6, sample_ratio=SAMPLE_RATIO, kappa=10, confidence=0.7, ) cls.ad.fit() # shuffle the test set x_test = cls.dc.x_test y_test = cls.dc.y_test shuffled_indices = np.random.permutation(len(x_test))[:NUM_ADV] cls.x = x_test[shuffled_indices] cls.y = y_test[shuffled_indices] logger.info('# of test set: %d', len(cls.x))
def setUpClass(cls): master_seed(SEED) logger.info('Starting %s data container...', NAME) cls.dc = DataContainer(DATASET_LIST[NAME], get_data_path()) # ordered by labels, it requires shuffle! cls.dc(shuffle=True, normalize=True) num_features = cls.dc.dim_data[0] num_classes = cls.dc.num_classes model = BCNN(num_features, num_classes) logger.info('Using model: %s', model.__class__.__name__) cls.mc = ModelContainerPT(model, cls.dc) filename = get_pt_model_filename(BCNN.__name__, NAME, MAX_EPOCHS) file_path = os.path.join('save', filename) if not os.path.exists(file_path): cls.mc.fit(max_epochs=MAX_EPOCHS, batch_size=BATCH_SIZE) cls.mc.save(filename, overwrite=True) else: logger.info('Use saved parameters from %s', filename) cls.mc.load(file_path) accuracy = cls.mc.evaluate(cls.dc.x_test, cls.dc.y_test) logger.info('Accuracy on test set: %f', accuracy) hidden_model = model.hidden_model cls.ad = ApplicabilityDomainContainer( cls.mc, hidden_model=hidden_model, k2=6, reliability=1.6, sample_ratio=SAMPLE_RATIO, kappa=10, confidence=0.9, ) cls.ad.fit()
def main(): dc = DataContainer(DATASET_LIST[NAME], get_data_path()) dc() model = MnistCnnV2() mc = ModelContainerPT(model, dc) mc.load(MODEL_FILE) accuracy = mc.evaluate(dc.x_test, dc.y_test) print(f'Accuracy on test set: {accuracy}') carlini_attack = attacks.CarliniL2V2Container( mc, learning_rate=0.01, binary_search_steps=9, max_iter=1000, confidence=0.0, initial_const=0.01, c_range=(0, 1e10), batch_size=BATCH_SIZE, clip_values=(0.0, 1.0), ) # adv, y_adv, x_clean, y_clean = carlini_attack.generate(count=1000) # carlini_attack.save_attack( # 'MnistCnnV2_MNIST_Carlini', # adv, # y_adv, # x_clean, # y_clean, # True, # ) # use pre-trained adversarial examples adv, y_adv, x_clean, y_clean = carlini_attack.load_adv_examples( CARLINI_FILE) accuracy = mc.evaluate(adv, y_clean) print(f'Accuracy on adv. examples: {accuracy}') bim_attack = attacks.BIMContainer( mc, eps=0.3, eps_step=0.1, max_iter=100, targeted=False, ) k2, zeta, kappa, gamma = cross_validation(dc, model, bim_attack) # use pre-defined parameters # k2, zeta, kappa, gamma, score = K2, RELIABILITY, KAPPA, CONFIDENCE, 0 ad = ApplicabilityDomainContainer( mc, hidden_model=model.hidden_model, k2=k2, reliability=zeta, sample_ratio=SAMPLE_RATIO, kappa=kappa, confidence=gamma, ) print(ad.params) ad.fit() blocked_indices, x_passed = ad.detect(adv, y_adv, return_passed_x=True) print('After update parameters, blocked {}/{} samples from adv. examples'. format(len(blocked_indices), len(adv)))
def main(): parser = ap.ArgumentParser() parser.add_argument('-d', '--dataset', type=str, required=True, help='Name of the dataset') parser.add_argument( '-p', '--param', type=str, required=True, help='a JSON config file which contains the parameters for the attacks' ) parser.add_argument('-s', '--seed', type=int, default=4096, help='the seed for random number generator') parser.add_argument('-v', '--verbose', action='store_true', default=False, help='set logger level to debug') parser.add_argument('-l', '--savelog', action='store_true', default=False, help='save logging file') parser.add_argument('-F', '--fgsm', action='store_true', default=False, help='Apply FGSM attack') parser.add_argument('-B', '--bim', action='store_true', default=False, help='Apply BIM attack') parser.add_argument('-D', '--deepfool', action='store_true', default=False, help='Apply DeepFool attack') parser.add_argument('-C', '--carlini', action='store_true', default=False, help='Apply Carlini L2 attack') args = parser.parse_args() data_name = args.dataset param_file = args.param seed = args.seed verbose = args.verbose save_log = args.savelog # set logging config. Run this before logging anything! set_logging(LOG_NAME, data_name, verbose, save_log) # Which attack should apply? attack_list = [] if args.fgsm: attack_list.append('FGSM') if args.bim: attack_list.append('BIM') if args.deepfool: attack_list.append('DeepFool') if args.carlini: attack_list.append('Carlini') # Quit, if there is nothing to do. if len(attack_list) == 0: logger.warning('Neither received any filter nor any attack. Exit') sys.exit(0) if data_name in ('BankNote', 'HTRU2', 'Iris', 'WheatSeed'): model_name = 'IrisNN' if data_name == 'BreastCancerWisconsin': model_name = 'BCNN' y_file = os.path.join('save', f'{model_name}_{data_name}_{attack_list[0]}_y.npy') attack_files = [ os.path.join('save', f'{model_name}_{data_name}_{attack_list[0]}_x.npy') ] for attack_name in attack_list: attack_files.append( os.path.join('save', f'{model_name}_{data_name}_{attack_name}_adv.npy')) # the 1st file this the clean inputs attack_list = ['clean'] + attack_list # load parameters for Applicability Domain with open(param_file) as param_json: params = json.load(param_json) # show parameters print(f'[{LOG_NAME}] Running tree model...') logger.info('Start at :%s', get_time_str()) logger.info('RECEIVED PARAMETERS:') logger.info('model :%s', model_name) logger.info('dataset :%s', data_name) logger.info('param file :%s', param_file) logger.info('seed :%d', seed) logger.info('verbose :%r', verbose) logger.info('save_log :%r', save_log) logger.info('attacks :%s', ', '.join(attack_list)) logger.debug('params :%s', str(params)) # check files for file_name in [y_file] + attack_files: if not os.path.exists(file_name): logger.error('%s does not exist!', file_name) raise FileNotFoundError('{} does not exist!'.format(file_name)) # reset seed master_seed(seed) # select data dc = get_data_container( data_name, use_shuffle=True, use_normalize=True, ) # train the model classifier = ExtraTreeClassifier( criterion='gini', splitter='random', ) mc = ModelContainerTree(classifier, dc) mc.fit() x = np.load(attack_files[0], allow_pickle=False) art_classifier = SklearnClassifier(classifier) attack = DecisionTreeAttack(art_classifier) adv = attack.generate(x) ad = ApplicabilityDomainContainer(mc, mc.hidden_model, **params) ad.fit() # generate adversarial examples y = np.load(y_file, allow_pickle=False) accuracy = mc.evaluate(adv, y) logger.info('Accuracy on DecisionTreeAttack set: %f', accuracy) blocked_indices = ad.detect(adv) logger.info('Blocked %d/%d samples on DecisionTreeAttack', len(blocked_indices), len(adv)) # traverse other attacks for i in range(len(attack_list)): adv_file = attack_files[i] adv_name = attack_list[i] logger.debug('Load %s...', adv_file) adv = np.load(adv_file, allow_pickle=False) accuracy = mc.evaluate(adv, y) logger.info('Accuracy on %s set: %f', adv_name, accuracy) blocked_indices = ad.detect(adv, return_passed_x=False) logger.info('Blocked %d/%d samples on %s', len(blocked_indices), len(adv), adv_name)
def experiment(index, data_container, max_epochs, adv_file, res_file): # STEP 1: select data and model dname = data_container.name num_classes = data_container.num_classes num_features = data_container.dim_data[0] model = IrisNN(num_features=num_features, hidden_nodes=num_features * 4, num_classes=num_classes) distill_model = IrisNN(num_features=num_features, hidden_nodes=num_features * 4, num_classes=num_classes) # STEP 2: train models mc = ModelContainerPT(model, data_container) mc.fit(max_epochs=max_epochs, batch_size=BATCH_SIZE) accuracy = mc.evaluate(data_container.x_test, data_container.y_test) logger.info('Accuracy on test set: %f', accuracy) adv_res = [accuracy] # STEP 3: generate adversarial examples # no more than 1000 samples are required x = data_container.x_test y = data_container.y_test # The test set has fixed size, 1000. if len(x) > 1000: x = x[:1000] y = y[:1000] accuracy = mc.evaluate(x, y) adv_res.append(accuracy) advs = np.zeros((len(ATTACK_LIST), x.shape[0], x.shape[1]), dtype=np.float32) pred_advs = -np.ones((len(ATTACK_LIST), len(y)), dtype=np.int32) # assign -1 as initial value pred_clean = mc.predict(x) advs[0] = x pred_advs[0] = pred_clean att_param_json = open(os.path.join(DIR_PATH, 'AttackParams.json')) att_params = json.load(att_param_json) for i, att_name in enumerate(ATTACK_LIST): # Clean set is only used in evaluation phase. if att_name == 'Clean': continue logger.debug('[%d]Running %s attack...', i, att_name) kwargs = att_params[att_name] logger.debug('%s params: %s', att_name, str(kwargs)) Attack = get_attack(att_name) attack = Attack(mc, **kwargs) adv, pred_adv, x_clean, pred_clean_ = attack.generate( use_testset=False, x=x) assert np.all(pred_clean == pred_clean_) assert np.all(x == x_clean) logger.info('created %d adv examples using %s from %s', len(advs[i]), att_name, dname) not_match = pred_adv != pred_clean success_rate = len(not_match[not_match == True]) / len(pred_clean) accuracy = mc.evaluate(adv, y) advs[i] = adv pred_advs[i] = pred_adv logger.info('Success rate of %s: %f', att_name, success_rate) logger.info('Accuracy on %s: %f', att_name, accuracy) adv_res.append(accuracy) adv_file.write(','.join([str(r) for r in adv_res]) + '\n') # STEP 4: train defences blocked_res = np.zeros(len(TITLE_RESULTS), dtype=np.int32) blocked_res[0] = index for def_name in DEFENCE_LIST: logger.debug('Running %s...', def_name) if def_name == 'AdvTraining': attack = BIMContainer(mc, eps=0.3, eps_step=0.1, max_iter=100, targeted=False) defence = AdversarialTraining(mc, [attack]) defence.fit(max_epochs=max_epochs, batch_size=BATCH_SIZE, ratio=ADV_TRAIN_RATIO) block_attack(0, advs, defence, def_name, blocked_res) elif def_name == 'Destillation': # A single temperature is used for all sets temp = 20 defence = DistillationContainer(mc, distill_model, temperature=temp, pretrained=False) defence.fit(max_epochs=max_epochs, batch_size=BATCH_SIZE) block_attack(1, advs, defence, def_name, blocked_res) elif def_name == 'Squeezing': defence = FeatureSqueezing( mc, SQUEEZER_FILTER_LIST, bit_depth=SQUEEZER_DEPTH, sigma=SQUEEZER_SIGMA, pretrained=True, ) defence.fit(max_epochs=max_epochs, batch_size=BATCH_SIZE) block_attack(2, advs, defence, def_name, blocked_res) elif def_name == 'AD': ad_param_file = open(AD_PARAM_FILE) # BreastCancer uses a different set of parameters if dname == 'BreastCancerWisconsin': param_file = os.path.join(DIR_PATH, 'AdParamsBC.json') ad_param_file = open(param_file) ad_params = json.load(ad_param_file) logger.debug('AD params: %s', str(ad_params)) defence = ApplicabilityDomainContainer( mc, hidden_model=model.hidden_model, **ad_params) defence.fit() block_attack(3, advs, defence, def_name, blocked_res) res_file.write(','.join([str(r) for r in blocked_res]) + '\n')
def main(): parser = ap.ArgumentParser() parser.add_argument( '-a', '--adv', type=str, required=True, help= 'file name for adv. examples. The name should in "<model>_<dataset>_<attack>_adv.npy" format' ) parser.add_argument( '-p', '--param', type=str, required=True, help='a JSON config file which contains the parameters for the attacks' ) parser.add_argument( '-m', '--model', type=str, required=True, help= 'a file which contains a pretrained model. The filename should in "<model>_<dataset>_e<max epochs>[_<date>].pt" format' ) parser.add_argument('-s', '--seed', type=int, default=4096, help='the seed for random number generator') parser.add_argument('-v', '--verbose', action='store_true', default=False, help='set logger level to debug') parser.add_argument('-l', '--savelog', action='store_true', default=False, help='save logging file') args = parser.parse_args() adv_file = args.adv param_file = args.param model_file = args.model seed = args.seed verbose = args.verbose save_log = args.savelog check_clean = True # build filenames from the root file postfix = ['adv', 'pred', 'x', 'y'] data_files = [adv_file.replace('_adv', '_' + s) for s in postfix] model_name, dname = parse_model_filename(adv_file) # set logging config. Run this before logging anything! set_logging('defence_ad', dname, verbose, save_log) # check adv. examples and parameter config files for f in data_files[:2] + [param_file]: if not os.path.exists(f): logger.warning('%s does not exist. Exit.', f) sys.exit(0) # check clean samples for f in data_files[-2:]: if not os.path.exists(f): logger.warning( 'Cannot load files for clean samples. Skip checking clean set.' ) check_clean = False with open(param_file) as param_json: params = json.load(param_json) # show parameters print( '[defend_ad] Running applicability domain on {}...'.format(model_name)) logger.info('Start at : %s', get_time_str()) logger.info('RECEIVED PARAMETERS:') logger.info('model file :%s', model_file) logger.info('adv file :%s', adv_file) logger.info('model :%s', model_name) logger.info('dataset :%s', dname) logger.info('param file :%s', param_file) logger.info('seed :%d', seed) logger.info('verbose :%r', verbose) logger.info('save_log :%r', save_log) logger.info('check_clean :%r', check_clean) logger.debug('params : %s', str(params)) # reset seed master_seed(seed) # set DataContainer and ModelContainer dc = get_data_container(dname) Model = get_model(model_name) # there models require extra keyword arguments if dname in ('BankNote', 'HTRU2', 'Iris', 'WheatSeed'): num_classes = dc.num_classes num_features = dc.dim_data[0] kwargs = { 'num_features': num_features, 'hidden_nodes': num_features * 4, 'num_classes': num_classes, } model = Model(**kwargs) else: model = Model() logger.info('Use %s model', model.__class__.__name__) mc = ModelContainerPT(model, dc) mc.load(model_file) accuracy = mc.evaluate(dc.x_test, dc.y_test) logger.info('Accuracy on test set: %f', accuracy) # preform defence ad = ApplicabilityDomainContainer(mc, hidden_model=model.hidden_model, **params) ad.fit() result_prefix = [model_file] \ + [adv_file] \ + [params['k2']] \ + [params['reliability']] \ + [params['sample_ratio']] \ + [params['confidence']] \ + [params['kappa']] \ + [params['disable_s2']] # check clean if check_clean: x = np.load(data_files[2], allow_pickle=False) y = np.load(data_files[3], allow_pickle=False) x_passed, blk_idx, blocked_counts = detect(ad, 'clean samples', x, y) result = result_prefix + ['clean'] + blocked_counts result_clean = '[result]' + ','.join([str(r) for r in result]) # check adversarial examples adv = np.load(data_files[0], allow_pickle=False) pred = np.load(data_files[1], allow_pickle=False) adv_passed, adv_blk_idx, blocked_counts = detect(ad, 'adv. examples', adv, pred) result = result_prefix + ['adv'] + blocked_counts result = '[result]' + ','.join([str(r) for r in result]) if check_clean: logger.info(result_clean) logger.info(result)
def main(): parser = ap.ArgumentParser() parser.add_argument( '-m', '--model', type=str, required=True, help='a file which contains a pretrained model. The filename should in "<model>_<dataset>_e<max epochs>[_<date>].pt" format') parser.add_argument( '-p', '--param', type=str, required=True, help='a JSON config file which contains the parameters for the cross validation') parser.add_argument( '-a', '--adv', type=str, help='file name of adv. examples for testing. If it\'s none, the program will ignore testing. The name should in "<model>_<dataset>_<attack>_adv.npy" format') parser.add_argument( '-s', '--seed', type=int, default=4096, help='the seed for random number generator') parser.add_argument( '-v', '--verbose', action='store_true', default=False, help='set logger level to debug') parser.add_argument( '-l', '--savelog', action='store_true', default=False, help='save logging file') parser.add_argument( '-i', '--ignore', action='store_true', default=False, help='Ignore saving the results. Only returns the results from terminal.') parser.add_argument( '-w', '--overwrite', action='store_true', default=False, help='overwrite the existing file') args = parser.parse_args() model_file = args.model param_file = args.param adv_file = args.adv seed = args.seed verbose = args.verbose save_log = args.savelog does_ignore = args.ignore overwrite = args.overwrite model_name, data_name = parse_model_filename(model_file) # set logging config. Run this before logging anything! set_logging('cross_validation', data_name, verbose, save_log) # check files for file_path in [model_file, param_file]: if not os.path.exists(file_path): logger.warning('%s does not exist. Exit.', file_path) sys.exit(0) if adv_file is not None and not os.path.exists(adv_file): logger.warning('%s does not exist. Exit.', adv_file) sys.exit(0) # read parameters with open(param_file) as param_json: params = json.load(param_json) # show parameters print('[cv] Running cross validation on {} with {}...'.format( model_file, data_name)) logger.info('Start at : %s', get_time_str()) logger.info('RECEIVED PARAMETERS:') logger.info('model file :%s', model_file) logger.info('adv file :%s', adv_file) logger.info('model :%s', model_name) logger.info('dataset :%s', data_name) logger.info('param file :%s', param_file) logger.info('seed :%d', seed) logger.info('verbose :%r', verbose) logger.info('save_log :%r', save_log) logger.info('Ignore saving :%r', does_ignore) logger.info('overwrite :%r', overwrite) logger.debug('params :%s', str(params)) # load parameters k_range = params['k_range'] z_range = params['z_range'] kappa_range = params['kappa_range'] gamma_range = params['gamma_range'] epsilon = params['epsilon'] num_folds = params['num_folds'] batch_size = params['batch_size'] sample_ratio = params['sample_ratio'] logger.info('k_range :%s', str(k_range)) logger.info('z_range :%s', str(z_range)) logger.info('kappa_range :%s', str(kappa_range)) logger.info('gamma_range :%s', str(gamma_range)) logger.info('epsilon :%.1f', epsilon) logger.info('num_folds :%d', num_folds) logger.info('batch_size :%d', batch_size) logger.info('sample_ratio :%.1f', sample_ratio) # reset seed master_seed(seed) dc = DataContainer(DATASET_LIST[data_name], get_data_path()) dc(shuffle=True, normalize=True, size_train=0.8) logger.info('Sample size: %d', len(dc)) Model = get_model(model_name) # there models require extra keyword arguments if data_name in ('BankNote', 'HTRU2', 'Iris', 'WheatSeed'): num_classes = dc.num_classes num_features = dc.dim_data[0] kwargs = { 'num_features': num_features, 'hidden_nodes': num_features*4, 'num_classes': num_classes, } model = Model(**kwargs) else: model = Model() logger.info('Use %s model', model.__class__.__name__) mc = ModelContainerPT(model, dc) mc.load(model_file) accuracy = mc.evaluate(dc.x_test, dc.y_test) logger.info('Accuracy on test set: %f', accuracy) ad = ApplicabilityDomainContainer( mc, hidden_model=model.hidden_model, sample_ratio=sample_ratio) cross_validation = CrossValidation( ad, num_folds=num_folds, k_range=k_range, z_range=z_range, kappa_range=kappa_range, gamma_range=gamma_range, epsilon=epsilon, ) bim_attack = BIMContainer( mc, eps=0.3, eps_step=0.1, max_iter=100, targeted=False, ) cross_validation.fit(bim_attack) # test optimal parameters if adv_file is not None: postfix = ['adv', 'pred', 'x', 'y'] data_files = [adv_file.replace('_adv', '_' + s) for s in postfix] adv = np.load(data_files[0], allow_pickle=False) pred_adv = np.load(data_files[1], allow_pickle=False) x = np.load(data_files[2], allow_pickle=False) pred = np.load(data_files[3], allow_pickle=False) # fetch optimal parameters ad = ApplicabilityDomainContainer( mc, hidden_model=model.hidden_model, k2=cross_validation.k2, reliability=cross_validation.reliability, sample_ratio=sample_ratio, kappa=cross_validation.kappa, confidence=cross_validation.confidence, ) logger.info('Params: %s', str(ad.params)) ad.fit() blocked_indices = ad.detect(x, pred, return_passed_x=False) logger.info('Blocked %d/%d on clean data', len(blocked_indices), len(x)) blocked_indices = ad.detect(adv, pred_adv, return_passed_x=False) logger.info('Blocked %d/%d on adv. examples.', len(blocked_indices), len(adv)) # save results if not does_ignore: file_name = name_handler( model_name + '_' + data_name, 'csv', overwrite=overwrite) cross_validation.save(file_name)
def experiment(index, dname, mname, max_epochs, adv_file, res_file): # STEP 1: select data dc = get_data_container(dname, use_shuffle=True, use_normalize=True) Model = get_model(mname) model = Model() distill_model = Model() logger.info('Selected %s model', model.__class__.__name__) # STEP 2: train models mc = ModelContainerPT(model, dc) mc.fit(max_epochs=max_epochs, batch_size=BATCH_SIZE) accuracy = mc.evaluate(dc.x_test, dc.y_test) logger.info('Accuracy on test set: %f', accuracy) adv_res = [accuracy] # STEP 3: generate adversarial examples # no more than 1000 samples are required n = 1000 if len(dc.x_test) >= 1000 else len(dc.x_test) # idx = np.random.choice(len(dc.x_test), n, replace=False) # x = dc.x_test[idx] # y = dc.y_test[idx] x = dc.x_test[:n] y = dc.y_test[:n] accuracy = mc.evaluate(x, y) adv_res.append(accuracy) advs = np.zeros( tuple([len(ATTACK_LIST)] + list(x.shape)), dtype=np.float32) pred_advs = -np.ones( (len(ATTACK_LIST), n), dtype=np.int32) # assign -1 as initial value pred_clean = mc.predict(x) advs[0] = x pred_advs[0] = pred_clean att_param_json = open(os.path.join(DIR_PATH, 'AttackParams.json')) att_params = json.load(att_param_json) for i, att_name in enumerate(ATTACK_LIST): # Clean set is only used in evaluation phase. if att_name == 'Clean': continue logger.debug('[%d]Running %s attack...', i, att_name) kwargs = att_params[att_name] logger.debug('%s params: %s', att_name, str(kwargs)) Attack = get_attack(att_name) attack = Attack(mc, **kwargs) adv, pred_adv, x_clean, pred_clean_ = attack.generate( use_testset=False, x=x) assert np.all(pred_clean == pred_clean_) assert np.all(x == x_clean) logger.info('created %d adv examples using %s from %s', len(advs[i]), att_name, dname) not_match = pred_adv != pred_clean success_rate = len(not_match[not_match == True]) / len(pred_clean) accuracy = mc.evaluate(adv, y) advs[i] = adv pred_advs[i] = pred_adv logger.info('Success rate of %s: %f', att_name, success_rate) logger.info('Accuracy on %s: %f', att_name, accuracy) adv_res.append(accuracy) adv_file.write(','.join([str(r) for r in adv_res]) + '\n') # STEP 4: train defences blocked_res = np.zeros(len(TITLE_RESULTS), dtype=np.int32) blocked_res[0] = index for def_name in DEFENCE_LIST: logger.debug('Running %s...', def_name) if def_name == 'AdvTraining': attack = BIMContainer( mc, eps=0.3, eps_step=0.1, max_iter=100, targeted=False) defence = AdversarialTraining(mc, [attack]) defence.fit(max_epochs=max_epochs, batch_size=BATCH_SIZE, ratio=ADV_TRAIN_RATIO) block_attack(0, advs, defence, def_name, blocked_res) elif def_name == 'Destillation': defence = DistillationContainer( mc, distill_model, temperature=DISTILL_TEMP, pretrained=False) defence.fit(max_epochs=max_epochs, batch_size=BATCH_SIZE) block_attack(1, advs, defence, def_name, blocked_res) elif def_name == 'Squeezing': defence = FeatureSqueezing( mc, SQUEEZER_FILTER_LIST, bit_depth=SQUEEZER_DEPTH, sigma=SQUEEZER_SIGMA, kernel_size=SQUEEZER_KERNEL, pretrained=True, ) defence.fit(max_epochs=max_epochs, batch_size=BATCH_SIZE) block_attack(2, advs, defence, def_name, blocked_res) elif def_name == 'AD': ad_param_file = open(AD_PARAM_FILE) ad_params = json.load(ad_param_file) logger.debug('AD params: %s', str(ad_params)) defence = ApplicabilityDomainContainer( mc, hidden_model=model.hidden_model, **ad_params) defence.fit() block_attack(3, advs, defence, def_name, blocked_res) res_file.write(','.join([str(r) for r in blocked_res]) + '\n')
def main(): dc = DataContainer(DATASET_LIST[NAME], get_data_path()) dc(shuffle=True, normalize=True, size_train=0.8) print('Sample size: {}'.format(len(dc))) num_classes = dc.num_classes num_features = dc.dim_data[0] model = IrisNN(num_features=num_features, hidden_nodes=num_features * 4, num_classes=num_classes) mc = ModelContainerPT(model, dc) # mc.fit(max_epochs=MAX_EPOCHS, batch_size=BATCH_SIZE, early_stop=False) # filename = get_pt_model_filename('IrisNN', NAME, MAX_EPOCHS) # mc.save(filename, overwrite=True) mc.load(MODEL_FILE) accuracy = mc.evaluate(dc.x_test, dc.y_test) print(f'Accuracy on test set: {accuracy}') carlini_attack = attacks.CarliniL2V2Container( mc, learning_rate=0.01, binary_search_steps=9, max_iter=1000, confidence=0.0, initial_const=0.01, c_range=(0, 1e4), batch_size=BATCH_SIZE, clip_values=(0.0, 1.0), ) # we need more than 30 adv. examples # x_all = dc.x_all # y_all = dc.x_all # indices = np.random.permutation(np.arange(len(dc)))[:100] # x = x_all[indices] # y = y_all[indices] # adv, pred_adv, x_clean, pred_clean = carlini_attack.generate(use_testset=False, x=x) # carlini_attack.save_attack( # 'IrisNN_Iris_Carlini', # adv, pred_adv, # x_clean, pred_clean, # True, # ) # use pre-trained adversarial examples adv, y_adv, x_clean, pred_clean = carlini_attack.load_adv_examples( CARLINI_FILE) accuracy = mc.evaluate(adv, pred_clean) print(f'Accuracy on adv. examples: {accuracy}') bim_attack = attacks.BIMContainer( mc, eps=0.3, eps_step=0.1, max_iter=100, targeted=False, ) k2, zeta, kappa, gamma = cross_validation(dc, model, bim_attack) ad = ApplicabilityDomainContainer( mc, hidden_model=model.hidden_model, k2=k2, reliability=zeta, sample_ratio=SAMPLE_RATIO, kappa=kappa, confidence=gamma, ) print(ad.params) ad.fit() blocked_indices, x_passed = ad.detect(adv, y_adv, return_passed_x=True) print('After update parameters, blocked {}/{} samples from adv. examples'. format(len(blocked_indices), len(adv)))