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)))
예제 #7
0
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)))