def load_models(dataset):
    archs = []
    model_path_list = []
    if dataset == "CIFAR-10" or dataset == "CIFAR-100":
        for arch in ["resnet-110","WRN-28-10","WRN-34-10","resnext-8x64d","resnext-16x64d"]:
            test_model_path = "{}/train_pytorch_model/real_image_model/{}-pretrained/{}/checkpoint.pth.tar".format(
                PY_ROOT, dataset, arch)
            if os.path.exists(test_model_path):
                archs.append(arch)
                model_path_list.append(test_model_path)
            else:
                log.info(test_model_path + " does not exist!")
    elif dataset == "TinyImageNet":
        # for arch in ["vgg11_bn","resnet18","vgg16_bn","resnext64_4","densenet121"]:
        for arch in MODELS_TEST_STANDARD[dataset]:
            test_model_path = "{}/train_pytorch_model/real_image_model/{}@{}@*.pth.tar".format(
                PY_ROOT, dataset, arch)
            test_model_path = list(glob.glob(test_model_path))[0]
            if os.path.exists(test_model_path):
                archs.append(arch)
                model_path_list.append(test_model_path)
            else:
                log.info(test_model_path + "does not exist!")
    else:
        for arch in ["inceptionv3","inceptionv4", "inceptionresnetv2","resnet101", "resnet152"]:
            test_model_list_path = "{}/train_pytorch_model/real_image_model/{}-pretrained/checkpoints/{}*.pth".format(
                PY_ROOT, dataset, arch)
            test_model_path = list(glob.glob(test_model_list_path))
            if len(test_model_path) == 0:  # this arch does not exists in args.dataset
                continue
            archs.append(arch)
            model_path_list.append(test_model_path[0])
    models = []
    print("begin construct model")
    if dataset == "TinyImageNet":
        for idx, arch in enumerate(archs):
            model = MetaLearnerModelBuilder.construct_tiny_imagenet_model(arch, dataset)
            model_path = model_path_list[idx]
            model.load_state_dict(torch.load(model_path, map_location=lambda storage, location: storage)["state_dict"])
            model.cuda()
            model.eval()
            models.append(model)
    else:
        for arch in archs:
            model = StandardModel(dataset, arch, no_grad=True)
            model.cuda()
            model.eval()
            models.append(model)
    print("end construct model")
    return models
Ejemplo n.º 2
0
def main(args, arch):
    model = StandardModel(args["dataset"], arch, False)
    model.cuda()
    model.eval()
    # attack related settings
    if args["attack_method"] == "zoo" or args[
            "attack_method"] == "autozoom_bilin":
        if args["img_resize"] is None:
            args["img_resize"] = model.input_size[-1]
            log.info(
                "Argument img_resize is not set and not using autoencoder, set to image original size:{}"
                .format(args["img_resize"]))

    codec = None
    if args["attack_method"] == "zoo_ae" or args[
            "attack_method"] == "autozoom_ae":
        codec = Codec(model.input_size[-1],
                      IN_CHANNELS[args["dataset"]],
                      args["compress_mode"],
                      args["resize"],
                      use_tanh=args["use_tanh"])
        codec.load_codec(args["codec_path"])
        codec.cuda()
        decoder = codec.decoder
        args["img_resize"] = decoder.input_shape[1]
        log.info(
            "Loading autoencoder: {}, set the attack image size to:{}".format(
                args["codec_path"], args["img_resize"]))

    # setup attack
    if args["attack_method"] == "zoo":
        blackbox_attack = ZOO(model, args["dataset"], args)
    elif args["attack_method"] == "zoo_ae":
        blackbox_attack = ZOO_AE(model, args["dataset"], args, decoder)
    elif args["attack_method"] == "autozoom_bilin":
        blackbox_attack = AutoZOOM_BiLIN(model, args["dataset"], args)
    elif args["attack_method"] == "autozoom_ae":
        blackbox_attack = AutoZOOM_AE(model, args["dataset"], args, decoder)
    target_str = "untargeted" if args[
        "attack_type"] != "targeted" else "targeted_{}".format(
            args["target_type"])
    save_result_path = args[
        "exp_dir"] + "/data_{}@arch_{}@attack_{}@{}_result.json".format(
            args["dataset"], arch, args["attack_method"], target_str)
    attack_framework = AutoZoomAttackFramework(args)
    attack_framework.attack_dataset_images(args, blackbox_attack, arch, model,
                                           codec, save_result_path)
    model.cpu()
Ejemplo n.º 3
0
def test_attack(threshold, arch, dataset, test_loader):
    target_model = StandardModel(dataset, arch, no_grad=False)
    if torch.cuda.is_available():
        target_model = target_model.cuda()
    target_model.eval()
    attack = LinfPGDAttack(target_model, loss_fn=nn.CrossEntropyLoss(reduction="sum"), eps=threshold, nb_iter=30,
                           eps_iter=0.01, rand_init=True, clip_min=0.0, clip_max=1.0, targeted=False)
    all_count = 0
    success_count = 0
    all_adv_images = []
    all_true_labels = []
    for idx, (img, true_label) in enumerate(test_loader):
        img = img.cuda()
        true_label = true_label.cuda().long()

        adv_image = attack.perturb(img, true_label) # (3, 224, 224), float
        if adv_image is None:
            continue
        adv_label = target_model.forward(adv_image).max(1)[1].detach().cpu().numpy().astype(np.int32)
        # adv_image = np.transpose(adv_image, (0, 2, 3, 1)) # N,C,H,W -> (N, H, W, 3), float
        all_count += len(img)
        true_label_np = true_label.detach().cpu().numpy().astype(np.int32)
        success_count+= len(np.where(true_label_np != adv_label)[0])
        all_adv_images.append(adv_image.cpu().detach().numpy())
        all_true_labels.append(true_label_np)
    attack_success_rate = success_count / float(all_count)
    log.info("Before train. Attack success rate is {:.3f}".format(attack_success_rate))
    return target_model, np.concatenate(all_adv_images,0), np.concatenate(all_true_labels, 0)  # N,224,224,3
Ejemplo n.º 4
0
def main(args, arch):
    model = StandardModel(args.dataset, arch, args.solver != "fake_zero")
    model.cuda()
    model.eval()
    if args.init_size is None:
        args.init_size = model.input_size[-1]
        log.info(
            "Argument init_size is not set and not using autoencoder, set to image original size:{}"
            .format(args.init_size))

    target_str = "untargeted" if not args.targeted else "targeted_{}".format(
        args.target_type)
    save_result_path = args.exp_dir + "/data_{}@arch_{}@solver_{}@{}_result.json".format(
        args.dataset, arch, args.solver, target_str)
    if os.path.exists(save_result_path):
        model.cpu()
        return
    attack_framework = ZooAttackFramework(args)
    attack_framework.attack_dataset_images(args, arch, model, save_result_path)
    model.cpu()
Ejemplo n.º 5
0
def main():
    model = StandardModel(args.dataset,
                          args.arch,
                          no_grad=False,
                          load_pretrained=False)
    model.cuda()
    model.train()
    device = torch.device("cuda")
    optimizer = optim.SGD(model.parameters(),
                          lr=args.lr,
                          momentum=args.momentum,
                          weight_decay=args.weight_decay)
    model_path = '{}/train_pytorch_model/adversarial_train/TRADES/{}@{}@epoch_{}@batch_{}.pth.tar'.format(
        PY_ROOT, args.dataset, args.arch, args.epochs, args.batch_size)
    os.makedirs(os.path.dirname(model_path), exist_ok=True)
    print("After trained, the model will save to {}".format(model_path))
    for epoch in range(1, args.epochs + 1):
        # adjust learning rate for SGD
        adjust_learning_rate(optimizer, epoch)

        # adversarial training
        train(args, model, device, train_loader, optimizer, epoch)

        # evaluation on natural examples
        print(
            '================================================================')
        eval_train(model, device, train_loader)
        eval_test(model, device, test_loader)
        print(
            '================================================================')

        # save checkpoint
        if epoch % args.save_freq == 0:
            state = {
                'state_dict': model.state_dict(),
                'epoch': epoch,
                'optimizer': optimizer.state_dict()
            }
            torch.save(state, os.path.join(model_dir, model_path))
def generate(datasetname, batch_size):
    save_dir_path = "{}/data_adv_defense/guided_denoiser".format(PY_ROOT)
    os.makedirs(save_dir_path, exist_ok=True)
    set_log_file(save_dir_path + "/generate_{}.log".format(datasetname))
    data_loader = DataLoaderMaker.get_img_label_data_loader(datasetname, batch_size, is_train=True)
    attackers = []
    for model_name in MODELS_TRAIN_STANDARD[datasetname] + MODELS_TEST_STANDARD[datasetname]:
        model = StandardModel(datasetname, model_name, no_grad=False)
        model = model.cuda().eval()
        linf_PGD_attack =LinfPGDAttack(model, loss_fn=nn.CrossEntropyLoss(reduction="sum"), eps=0.031372, nb_iter=30,
                      eps_iter=0.01, rand_init=True, clip_min=0.0, clip_max=1.0, targeted=False)
        l2_PGD_attack = L2PGDAttack(model, loss_fn=nn.CrossEntropyLoss(reduction="sum"),eps=4.6,
                                    nb_iter=30,clip_min=0.0, clip_max=1.0, targeted=False)
        FGSM_attack = FGSM(model, loss_fn=nn.CrossEntropyLoss(reduction="sum"))
        momentum_attack = MomentumIterativeAttack(model, loss_fn=nn.CrossEntropyLoss(reduction="sum"), eps=0.031372, nb_iter=30,
                      eps_iter=0.01, clip_min=0.0, clip_max=1.0, targeted=False)
        attackers.append(linf_PGD_attack)
        attackers.append(l2_PGD_attack)
        attackers.append(FGSM_attack)
        attackers.append(momentum_attack)
        log.info("Create model {} done!".format(model_name))

    generate_and_save_adv_examples(datasetname, data_loader, attackers, save_dir_path)
Ejemplo n.º 7
0
                    PY_ROOT, args.dataset, arch)
                test_model_list_path = list(glob.glob(test_model_list_path))
                if len(test_model_list_path
                       ) == 0:  # this arch does not exists in args.dataset
                    continue
                archs.append(arch)
    else:
        assert args.arch is not None
        archs = [args.arch]
    args.arch = ", ".join(archs)
    log.info('Command line is: {}'.format(' '.join(sys.argv)))
    log.info("Log file is written in {}".format(log_file_path))
    log.info('Called with args:')
    print_args(args)
    surrogate_model = StandardModel(args.dataset, args.surrogate_arch, False)
    surrogate_model.cuda()
    surrogate_model.eval()

    attacker = SwitchNeg(args.dataset, args.batch_size, args.targeted,
                         args.target_type, args.epsilon, args.norm, 0.0, 1.0,
                         args.max_queries)
    for arch in archs:
        if args.attack_defense:
            save_result_path = args.exp_dir + "/{}_{}_result.json".format(
                arch, args.defense_model)
        else:
            save_result_path = args.exp_dir + "/{}_result.json".format(arch)
        if os.path.exists(save_result_path):
            continue
        log.info("Begin attack {} on {}, result will be saved to {}".format(
            arch, args.dataset, save_result_path))
Ejemplo n.º 8
0
    f.write(socket.gethostname() + ":" + args.results_folder + "\n")


def onehot(ind, num_classes):
    vector = np.zeros([num_classes])
    vector[ind] = 1
    return vector.astype(np.float32)


logger.info("build dataloader")
train_loader = DataLoaderMaker.get_img_label_data_loader(
    args.dataset, args.batch_size, True)
val_loader = DataLoaderMaker.get_img_label_data_loader(args.dataset,
                                                       args.batch_size, False)
model = StandardModel(args.dataset, args.arch, no_grad=False)
model.cuda()
model.train()


def anneal_lr(epoch):
    if epoch < 100:
        return 1.
    elif epoch < 150:
        return 0.1
    else:
        return 0.01


pgd_kwargs = {
    "eps": 16. / 255.,
    "eps_iter": 4. / 255.,
    def attack_all_images(self, args, arch, tmp_dump_path, result_dump_path):
        # subset_pos用于回调函数汇报汇总统计结果

        model = StandardModel(args.dataset, arch, no_grad=True)
        model.cuda()
        model.eval()
        # 带有缩减功能的,攻击成功的图片自动删除掉
        for data_idx, data_tuple in enumerate(self.dataset_loader):
            if os.path.exists(tmp_dump_path):
                with open(tmp_dump_path, "r") as file_obj:
                    json_content = json.load(file_obj)
                    resume_batch_idx = int(json_content["batch_idx"])  # resume
                    for key in [
                            'query_all', 'correct_all', 'not_done_all',
                            'success_all', 'success_query_all'
                    ]:
                        if key in json_content:
                            setattr(
                                self, key,
                                torch.from_numpy(np.asarray(
                                    json_content[key])).float())
                    if data_idx < resume_batch_idx:  # resume
                        continue

            if args.dataset == "ImageNet":
                if model.input_size[-1] >= 299:
                    images, true_labels = data_tuple[1], data_tuple[2]
                else:
                    images, true_labels = data_tuple[0], data_tuple[2]
            else:
                images, true_labels = data_tuple[0], data_tuple[1]
            if images.size(-1) != model.input_size[-1]:
                images = F.interpolate(images,
                                       size=model.input_size[-1],
                                       mode='bilinear',
                                       align_corners=True)
            # skip_batch_index_list = np.nonzero(np.asarray(chunk_skip_indexes[data_idx]))[0].tolist()
            selected = torch.arange(
                data_idx * args.batch_size,
                min((data_idx + 1) * args.batch_size,
                    self.total_images))  # 选择这个batch的所有图片的index
            img_idx_to_batch_idx = ImageIdxToOrigBatchIdx(args.batch_size)
            images, true_labels = images.cuda(), true_labels.cuda()
            first_finetune = True
            finetune_queue = FinetuneQueue(args.batch_size, args.meta_seq_len,
                                           img_idx_to_batch_idx)
            prior_size = model.input_size[
                -1] if not args.tiling else args.tile_size
            assert args.tiling == (args.dataset == "ImageNet")
            if args.tiling:
                upsampler = Upsample(size=(model.input_size[-2],
                                           model.input_size[-1]))
            else:
                upsampler = lambda x: x
            with torch.no_grad():
                logit = model(images)
            pred = logit.argmax(dim=1)
            query = torch.zeros(images.size(0)).cuda()
            correct = pred.eq(true_labels).float()  # shape = (batch_size,)
            not_done = correct.clone()  # shape = (batch_size,)

            if args.targeted:
                if args.target_type == 'random':
                    target_labels = torch.randint(
                        low=0,
                        high=CLASS_NUM[args.dataset],
                        size=true_labels.size()).long().cuda()
                    invalid_target_index = target_labels.eq(true_labels)
                    while invalid_target_index.sum().item() > 0:
                        target_labels[invalid_target_index] = torch.randint(
                            low=0,
                            high=logit.shape[1],
                            size=target_labels[invalid_target_index].shape
                        ).long().cuda()
                        invalid_target_index = target_labels.eq(true_labels)
                elif args.target_type == 'least_likely':
                    target_labels = logit.argmin(dim=1)
                elif args.target_type == "increment":
                    target_labels = torch.fmod(true_labels + 1,
                                               CLASS_NUM[args.dataset])
                else:
                    raise NotImplementedError('Unknown target_type: {}'.format(
                        args.target_type))
            else:
                target_labels = None
            prior = torch.zeros(images.size(0), IN_CHANNELS[args.dataset],
                                prior_size, prior_size).cuda()
            prior_step = self.gd_prior_step if args.norm == 'l2' else self.eg_prior_step
            image_step = self.l2_image_step if args.norm == 'l2' else self.linf_step
            proj_step = self.l2_proj_step if args.norm == 'l2' else self.linf_proj_step  # 调用proj_maker返回的是一个函数
            criterion = self.cw_loss if args.data_loss == "cw" else self.xent_loss
            adv_images = images.clone()
            for step_index in range(1, args.max_queries + 1):
                # Create noise for exporation, estimate the gradient, and take a PGD step
                dim = prior.nelement() / images.size(
                    0)  # nelement() --> total number of elements
                exp_noise = args.exploration * torch.randn_like(prior) / (
                    dim**0.5
                )  # parameterizes the exploration to be done around the prior
                exp_noise = exp_noise.cuda()
                q1 = upsampler(
                    prior + exp_noise
                )  # 这就是Finite Difference算法, prior相当于论文里的v,这个prior也会更新,把梯度累积上去
                q2 = upsampler(
                    prior -
                    exp_noise)  # prior 相当于累积的更新量,用这个更新量,再去修改image,就会变得非常准
                # Loss points for finite difference estimator
                q1_images = adv_images + args.fd_eta * q1 / self.norm(q1)
                q2_images = adv_images + args.fd_eta * q2 / self.norm(q2)
                predict_by_target_model = False
                if (step_index <= args.warm_up_steps or
                    (step_index - args.warm_up_steps) % args.meta_predict_steps
                        == 0):
                    log.info("predict from target model")
                    predict_by_target_model = True
                    with torch.no_grad():
                        q1_logits = model(q1_images)
                        q2_logits = model(q2_images)
                        q1_logits = q1_logits / torch.norm(
                            q1_logits, p=2, dim=-1,
                            keepdim=True)  # 加入normalize
                        q2_logits = q2_logits / torch.norm(
                            q2_logits, p=2, dim=-1, keepdim=True)

                    finetune_queue.append(q1_images.detach(),
                                          q2_images.detach(),
                                          q1_logits.detach(),
                                          q2_logits.detach())

                    if step_index >= args.warm_up_steps:
                        q1_images_seq, q2_images_seq, q1_logits_seq, q2_logits_seq = finetune_queue.stack_history_track(
                        )
                        finetune_times = args.finetune_times if first_finetune else random.randint(
                            3, 5)  # FIXME
                        log.info("begin finetune for {} times".format(
                            finetune_times))
                        self.meta_finetuner.finetune(
                            q1_images_seq, q2_images_seq, q1_logits_seq,
                            q2_logits_seq, finetune_times, first_finetune,
                            img_idx_to_batch_idx)
                        first_finetune = False
                else:
                    with torch.no_grad():
                        q1_logits, q2_logits = self.meta_finetuner.predict(
                            q1_images, q2_images, img_idx_to_batch_idx)
                        q1_logits = q1_logits / torch.norm(
                            q1_logits, p=2, dim=-1, keepdim=True)
                        q2_logits = q2_logits / torch.norm(
                            q2_logits, p=2, dim=-1, keepdim=True)

                l1 = criterion(q1_logits, true_labels, target_labels)
                l2 = criterion(q2_logits, true_labels, target_labels)
                # Finite differences estimate of directional derivative
                est_deriv = (l1 - l2) / (args.fd_eta * args.exploration
                                         )  # 方向导数 , l1和l2是loss
                # 2-query gradient estimate
                est_grad = est_deriv.view(-1, 1, 1,
                                          1) * exp_noise  # B, C, H, W,
                # Update the prior with the estimated gradient
                prior = prior_step(
                    prior, est_grad,
                    args.online_lr)  # 注意,修正的是prior,这就是bandit算法的精髓
                grad = upsampler(prior)  # prior相当于梯度
                ## Update the image:
                adv_images = image_step(
                    adv_images,
                    grad * correct.view(-1, 1, 1, 1),  # 注意correct也是删减过的
                    args.image_lr)  # prior放大后相当于累积的更新量,可以用来更新
                adv_images = proj_step(images, args.epsilon, adv_images)
                adv_images = torch.clamp(adv_images, 0, 1)

                with torch.no_grad():
                    adv_logit = model(adv_images)  #
                adv_pred = adv_logit.argmax(dim=1)
                adv_prob = F.softmax(adv_logit, dim=1)
                adv_loss = criterion(adv_logit, true_labels, target_labels)
                ## Continue query count
                if predict_by_target_model:
                    query = query + 2 * not_done
                if args.targeted:
                    not_done = not_done * (
                        1 - adv_pred.eq(target_labels).float()
                    ).float()  # not_done初始化为 correct, shape = (batch_size,)
                else:
                    not_done = not_done * adv_pred.eq(
                        true_labels).float()  # 只要是跟原始label相等的,就还需要query,还没有成功
                success = (1 - not_done) * correct
                success_query = success * query
                not_done_loss = adv_loss * not_done
                not_done_prob = adv_prob[torch.arange(adv_images.size(0)),
                                         true_labels] * not_done

                log.info('Attacking image {} - {} / {}, step {}'.format(
                    data_idx * args.batch_size,
                    (data_idx + 1) * args.batch_size, self.total_images,
                    step_index))
                log.info('       not_done: {:.4f}'.format(
                    len(
                        np.where(not_done.detach().cpu().numpy().astype(
                            np.int32) == 1)[0]) / float(args.batch_size)))
                log.info('      fd_scalar: {:.9f}'.format(
                    (l1 - l2).mean().item()))
                if success.sum().item() > 0:
                    log.info('     mean_query: {:.4f}'.format(
                        success_query[success.byte()].mean().item()))
                    log.info('   median_query: {:.4f}'.format(
                        success_query[success.byte()].median().item()))
                if not_done.sum().item() > 0:
                    log.info('  not_done_loss: {:.4f}'.format(
                        not_done_loss[not_done.byte()].mean().item()))
                    log.info('  not_done_prob: {:.4f}'.format(
                        not_done_prob[not_done.byte()].mean().item()))

                not_done_np = not_done.detach().cpu().numpy().astype(np.int32)
                done_img_idx_list = np.where(not_done_np == 0)[0].tolist()
                delete_all = False
                if done_img_idx_list:
                    for skip_index in done_img_idx_list:  # 两次循环,第一次循环先汇报出去,第二次循环删除
                        batch_idx = img_idx_to_batch_idx[skip_index]
                        pos = selected[batch_idx].item()
                        # 先汇报被删减的值self.query_all
                        for key in [
                                'query', 'correct', 'not_done', 'success',
                                'success_query', 'not_done_loss',
                                'not_done_prob'
                        ]:
                            value_all = getattr(self, key + "_all")
                            value = eval(key)[skip_index].item()
                            value_all[pos] = value

                    images, adv_images, prior, query, true_labels, target_labels, correct, not_done = \
                        self.delete_tensor_by_index_list(done_img_idx_list, images, adv_images, prior, query,
                                                         true_labels, target_labels, correct, not_done)
                    img_idx_to_batch_idx.del_by_index_list(done_img_idx_list)
                    delete_all = images is None

                if delete_all:
                    break

            # report to all stats the rest unsuccess
            for key in [
                    'query', 'correct', 'not_done', 'success', 'success_query',
                    'not_done_loss', 'not_done_prob'
            ]:
                for img_idx, batch_idx in img_idx_to_batch_idx.proj_dict.items(
                ):
                    pos = selected[batch_idx].item()
                    value_all = getattr(self, key + "_all")
                    value = eval(key)[img_idx].item()
                    value_all[
                        pos] = value  # 由于value_all是全部图片都放在一个数组里,当前batch选择出来
            img_idx_to_batch_idx.proj_dict.clear()

            tmp_info_dict = {
                "batch_idx": data_idx + 1,
                "batch_size": args.batch_size
            }
            for key in [
                    'query_all', 'correct_all', 'not_done_all', 'success_all',
                    'success_query_all'
            ]:
                value_all = getattr(self, key).detach().cpu().numpy().tolist()
                tmp_info_dict[key] = value_all
            with open(tmp_dump_path, "w") as result_file_obj:
                json.dump(tmp_info_dict, result_file_obj, sort_keys=True)

        log.info('Saving results to {}'.format(result_dump_path))
        meta_info_dict = {
            "avg_correct":
            self.correct_all.mean().item(),
            "avg_not_done":
            self.not_done_all[self.correct_all.byte()].mean().item(),
            "mean_query":
            self.success_query_all[self.success_all.byte()].mean().item(),
            "median_query":
            self.success_query_all[self.success_all.byte()].median().item(),
            "max_query":
            self.success_query_all[self.success_all.byte()].max().item(),
            "correct_all":
            self.correct_all.detach().cpu().numpy().astype(np.int32).tolist(),
            "not_done_all":
            self.not_done_all.detach().cpu().numpy().astype(np.int32).tolist(),
            "query_all":
            self.query_all.detach().cpu().numpy().astype(np.int32).tolist(),
            "not_done_loss":
            self.not_done_loss_all[self.not_done_all.byte()].mean().item(),
            "not_done_prob":
            self.not_done_prob_all[self.not_done_all.byte()].mean().item(),
            "args":
            vars(args)
        }
        with open(result_dump_path, "w") as result_file_obj:
            json.dump(meta_info_dict, result_file_obj, sort_keys=True)
        log.info("done, write stats info to {}".format(result_dump_path))
        self.query_all.fill_(0)
        self.correct_all.fill_(0)
        self.not_done_all.fill_(0)
        self.success_all.fill_(0)
        self.success_query_all.fill_(0)
        self.not_done_loss_all.fill_(0)
        self.not_done_prob_all.fill_(0)
        model.cpu()
                                transform=train_preprocessor)
elif dataset == "TinyImageNet":
    train_dataset = TinyImageNet(IMAGE_DATA_ROOT[dataset],
                                 train_preprocessor,
                                 train=True)

batch_size = args.batch_size
train_loader = torch.utils.data.DataLoader(train_dataset,
                                           batch_size=batch_size,
                                           shuffle=True,
                                           num_workers=0)

print('==> Building model..')
arch_list = MODELS_TRAIN_STANDARD[args.dataset]
model_dict = {}
for arch in arch_list:
    if StandardModel.check_arch(arch, args.dataset):
        print("begin use arch {}".format(arch))
        model = StandardModel(args.dataset, arch, no_grad=True)
        model_dict[arch] = model.eval()
        print("use arch {} done".format(arch))
print("==> Save gradient..")
for arch, model in model_dict.items():
    dump_path = "{}/benign_images_logits_pair/{}/{}_images.npy".format(
        PY_ROOT, args.dataset, arch)
    os.makedirs(os.path.dirname(dump_path), exist_ok=True)
    model = model.cuda()
    save_image_logits_pairs(model, train_loader, dump_path, args.batch_size,
                            args.max_items)
    model.cpu()
Ejemplo n.º 11
0
    def __init__(self, dataset, batch_size, meta_arch, meta_train_type, distill_loss, data_loss, norm, targeted, use_softmax, mode="meta"):
        if mode == "meta":
            target_str = "targeted_attack_random" if targeted else "untargeted_attack"
            # 2Q_DISTILLATION@CIFAR-100@TRAIN_I_TEST_II@model_resnet34@loss_pair_mse@dataloss_cw_l2_untargeted_attack@epoch_4@meta_batch_size_30@num_support_50@num_updates_12@lr_0.001@inner_lr_0.01.pth.tar
            self.meta_model_path = "{root}/train_pytorch_model/meta_simulator/{meta_train_type}@{dataset}@{split}@model_{meta_arch}@loss_{loss}@dataloss_{data_loss}_{norm}_{target_str}*inner_lr_0.01.pth.tar".format(
                root=PY_ROOT, meta_train_type=meta_train_type.upper(), dataset=dataset, split=SPLIT_DATA_PROTOCOL.TRAIN_I_TEST_II,
                meta_arch=meta_arch, loss=distill_loss, data_loss=data_loss, norm=norm, target_str=target_str)
            log.info("start using {}".format(self.meta_model_path))
            self.meta_model_path = glob.glob(self.meta_model_path)
            pattern = re.compile(".*model_(.*?)@.*inner_lr_(.*?)\.pth.*")
            assert len(self.meta_model_path) > 0
            self.meta_model_path = self.meta_model_path[0]
            log.info("load meta model {}".format(self.meta_model_path))
            ma = pattern.match(os.path.basename(self.meta_model_path))
            arch = ma.group(1)
            self.inner_lr = float(ma.group(2))
            meta_backbone = self.construct_model(arch, dataset)
            self.meta_network = MetaNetwork(meta_backbone)
            self.pretrained_weights = torch.load(self.meta_model_path, map_location=lambda storage, location: storage)
            self.meta_network.load_state_dict(self.pretrained_weights["state_dict"])
            log.info("Load model in epoch {}.".format(self.pretrained_weights["epoch"]))
            self.pretrained_weights = self.pretrained_weights["state_dict"]
        elif mode == "vanilla":
            target_str = "targeted" if targeted else "untargeted"
            arch = meta_arch
            # 2Q_DISTILLATION@CIFAR-100@TRAIN_I_TEST_II@model_resnet34@loss_pair_mse@dataloss_cw_l2_untargeted_attack@epoch_4@meta_batch_size_30@num_support_50@num_updates_12@lr_0.001@inner_lr_0.01.pth.tar
            self.meta_model_path = "{root}/train_pytorch_model/vanilla_simulator/{dataset}@{norm}_norm_{target_str}@{meta_arch}*.tar".format(
                root=PY_ROOT, dataset=dataset,
                meta_arch=meta_arch,norm=norm, target_str=target_str)
            log.info("start using {}".format(self.meta_model_path))
            self.meta_model_path = glob.glob(self.meta_model_path)
            assert len(self.meta_model_path) > 0
            self.meta_model_path = self.meta_model_path[0]
            log.info("load meta model {}".format(self.meta_model_path))
            self.inner_lr = 0.01
            self.meta_network = self.construct_model(meta_arch, dataset)
            self.pretrained_weights = torch.load(self.meta_model_path, map_location=lambda storage, location: storage)
            log.info("Load model in epoch {}.".format(self.pretrained_weights["epoch"]))
            self.pretrained_weights = self.pretrained_weights["state_dict"]
        elif mode == "deep_benign_images":
            arch = "resnet34"
            self.inner_lr = 0.01
            self.meta_network = self.construct_model(arch, dataset)
            self.meta_model_path = "{root}/train_pytorch_model/real_image_model/{dataset}@{arch}@epoch_200@lr_0.1@batch_200.pth.tar".format(
                root=PY_ROOT, dataset=dataset, arch=arch)
            assert os.path.exists(self.meta_model_path), "{} does not exists!".format(self.meta_model_path)
            self.pretrained_weights = torch.load(self.meta_model_path, map_location=lambda storage, location: storage)[
                "state_dict"]
        elif mode == "random_init":
            arch = "resnet34"
            self.inner_lr = 0.01
            self.meta_network = self.construct_model(arch, dataset)
            self.pretrained_weights = self.meta_network.state_dict()
        elif mode == 'ensemble_avg':
            self.inner_lr = 0.01
            self.archs = ["densenet-bc-100-12","resnet-110","vgg19_bn"]
            self.meta_network = []  # meta_network和pretrained_weights都改成list
            self.pretrained_weights = []
            for arch in self.archs:
                model = StandardModel(dataset, arch, no_grad=False, load_pretrained=True)
                model.eval()
                model.cuda()
                self.meta_network.append(model)
                self.pretrained_weights.append(model.state_dict())
        elif mode == "benign_images":
            self.inner_lr = 0.01
            self.meta_model_path = "{root}/train_pytorch_model/meta_simulator_on_benign_images/{dataset}@{split}*@inner_lr_0.01.pth.tar".format(
                root=PY_ROOT, meta_train_type=meta_train_type.upper(), dataset=dataset,
                split=SPLIT_DATA_PROTOCOL.TRAIN_I_TEST_II)
            self.meta_model_path = glob.glob(self.meta_model_path)
            pattern = re.compile(".*model_(.*?)@.*")
            assert len(self.meta_model_path) > 0
            self.meta_model_path = self.meta_model_path[0]
            ma = pattern.match(os.path.basename(self.meta_model_path))
            log.info("Loading meta model from {}".format(self.meta_model_path))
            arch = ma.group(1)
            self.pretrained_weights = torch.load(self.meta_model_path, map_location=lambda storage, location: storage)["state_dict"]
            meta_backbone = self.construct_model(arch, dataset)
            self.meta_network = MetaNetwork(meta_backbone)
            self.meta_network.load_state_dict(self.pretrained_weights)
            self.meta_network.eval()
            self.meta_network.cuda()
        elif mode == "reptile_on_benign_images":
            self.inner_lr = 0.01
            self.meta_model_path = "{root}/train_pytorch_model/meta_simulator_reptile_on_benign_images/{dataset}@{split}*@inner_lr_0.01.pth.tar".format(
                root=PY_ROOT, meta_train_type=meta_train_type.upper(), dataset=dataset,
                split=SPLIT_DATA_PROTOCOL.TRAIN_I_TEST_II)
            self.meta_model_path = glob.glob(self.meta_model_path)
            pattern = re.compile(".*model_(.*?)@.*")
            assert len(self.meta_model_path) > 0
            self.meta_model_path = self.meta_model_path[0]
            log.info("Loading meta model from {}".format(self.meta_model_path))
            ma = pattern.match(os.path.basename(self.meta_model_path))
            arch = ma.group(1)
            self.pretrained_weights = torch.load(self.meta_model_path, map_location=lambda storage, location: storage)["state_dict"]
            meta_backbone = self.construct_model(arch, dataset)
            self.meta_network = MetaNetwork(meta_backbone)
            self.meta_network.load_state_dict(self.pretrained_weights)
            self.meta_network.eval()
            self.meta_network.cuda()


        self.arch = arch
        self.dataset = dataset
        self.need_pair_distance = (distill_loss.lower()=="pair_mse")
        # self.need_pair_distance = False
        self.softmax = nn.Softmax(dim=1)
        self.mse_loss = nn.MSELoss(reduction="mean")
        self.pair_wise_distance = nn.PairwiseDistance(p=2)
        self.use_softmax = use_softmax
        if mode != "ensemble_avg":
            self.meta_network.load_state_dict(self.pretrained_weights)
            self.meta_network.eval()
            self.meta_network.cuda()
        self.batch_size = batch_size
        if mode == 'ensemble_avg':
            self.batch_weights = defaultdict(dict)
            for idx in range(len(self.pretrained_weights)):
                for i in range(batch_size):
                    self.batch_weights[idx][i] = self.pretrained_weights[idx]
        else:
            self.batch_weights = dict()
            for i in range(batch_size):
                self.batch_weights[i] = self.pretrained_weights
    def __init__(self, tot_num_tasks, dataset, inner_batch_size, protocol):
        """
        Args:
            num_samples_per_class: num samples to generate "per class" in one batch
            batch_size: size of meta batch size (e.g. number of functions)
        """
        self.img_size = IMAGE_SIZE[dataset]
        self.dataset = dataset

        if protocol == SPLIT_DATA_PROTOCOL.TRAIN_I_TEST_II:
            self.model_names = MODELS_TRAIN_STANDARD[self.dataset]
        elif protocol == SPLIT_DATA_PROTOCOL.TRAIN_II_TEST_I:
            self.model_names = MODELS_TEST_STANDARD[self.dataset]
        elif protocol == SPLIT_DATA_PROTOCOL.TRAIN_ALL_TEST_ALL:
            self.model_names = MODELS_TRAIN_STANDARD[
                self.dataset] + MODELS_TEST_STANDARD[self.dataset]

        self.model_dict = {}
        for arch in self.model_names:
            if StandardModel.check_arch(arch, dataset):
                model = StandardModel(dataset, arch, no_grad=False).eval()
                if dataset != "ImageNet":
                    model = model.cuda()
                self.model_dict[arch] = model
        is_train = True
        preprocessor = DataLoaderMaker.get_preprocessor(
            IMAGE_SIZE[dataset], is_train)
        if dataset == "CIFAR-10":
            train_dataset = CIFAR10(IMAGE_DATA_ROOT[dataset],
                                    train=is_train,
                                    transform=preprocessor)
        elif dataset == "CIFAR-100":
            train_dataset = CIFAR100(IMAGE_DATA_ROOT[dataset],
                                     train=is_train,
                                     transform=preprocessor)
        elif dataset == "MNIST":
            train_dataset = MNIST(IMAGE_DATA_ROOT[dataset],
                                  train=is_train,
                                  transform=preprocessor)
        elif dataset == "FashionMNIST":
            train_dataset = FashionMNIST(IMAGE_DATA_ROOT[dataset],
                                         train=is_train,
                                         transform=preprocessor)
        elif dataset == "TinyImageNet":
            train_dataset = TinyImageNet(IMAGE_DATA_ROOT[dataset],
                                         preprocessor,
                                         train=is_train)
        elif dataset == "ImageNet":
            preprocessor = DataLoaderMaker.get_preprocessor(
                IMAGE_SIZE[dataset], is_train, center_crop=True)
            sub_folder = "/train" if is_train else "/validation"  # Note that ImageNet uses pretrainedmodels.utils.TransformImage to apply transformation
            train_dataset = ImageFolder(IMAGE_DATA_ROOT[dataset] + sub_folder,
                                        transform=preprocessor)
        self.train_dataset = train_dataset
        self.total_num_images = len(train_dataset)
        self.all_tasks = dict()
        all_images_indexes = np.arange(self.total_num_images).tolist()
        for i in range(tot_num_tasks):
            self.all_tasks[i] = {
                "image": random.sample(all_images_indexes, inner_batch_size),
                "arch": random.choice(list(self.model_dict.keys()))
            }
Ejemplo n.º 13
0
if __name__ == "__main__":
    args = get_parse_args()
    if args.norm == "l2":
        args.epsilon = 4.6
    elif args.norm == "linf":
        args.epsilon = 0.031372
        if args.dataset == "ImageNet":
            args.epsilon = 0.05
    data_loader = get_img_label_data_loader(args.dataset, args.batch_size,
                                            True)
    test_data_loader = get_img_label_data_loader(args.dataset, args.batch_size,
                                                 False)
    os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"
    os.environ['CUDA_VISIBLE_DEVICES'] = str(args.gpu)
    target_model = StandardModel(args.dataset, args.model, no_grad=True)
    target_model = target_model.cuda()
    current_state = State(
        (args.batch_size, IN_CHANNELS[args.dataset],
         IMAGE_SIZE[args.dataset][0], IMAGE_SIZE[args.dataset][1]), args.norm,
        args.epsilon)
    fcn = MyFCN((IN_CHANNELS[args.dataset], IMAGE_SIZE[args.dataset][0],
                 IMAGE_SIZE[args.dataset][1]), args.n_actions)
    fcn.apply(fcn.init_weights)
    optimizer = Adam(fcn.parameters(), lr=args.learning_rate)
    agent = PixelWiseA3C(fcn, optimizer, args.episode_len, args.gamma)
    agent.model.cuda()
    agent.shared_model.cuda()
    i = 0
    episode = 0
    save_model_path = "{}/train_pytorch_model/sign_player/{}_untargeted_{}_attack_on_{}.pth.tar".format(
        PY_ROOT, args.dataset, args.norm, args.model)
Ejemplo n.º 14
0
def main():
    args = get_args()
    os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"
    os.environ['CUDA_VISIBLE_DEVICES'] = str(args.gpu)
    logger.info(args)
    model_path = '{}/train_pytorch_model/adversarial_train/fast_adv_train/{}@{}@epoch_{}.pth.tar'.format(
        PY_ROOT, args.dataset, args.arch, args.epochs)
    out_dir = os.path.dirname(model_path)
    os.makedirs(out_dir, exist_ok=True)
    np.random.seed(args.seed)
    torch.manual_seed(args.seed)
    torch.cuda.manual_seed(args.seed)

    start_start_time = time.time()
    train_loader = DataLoaderMaker.get_img_label_data_loader(args.dataset, args.batch_size, True)
    test_loader = DataLoaderMaker.get_img_label_data_loader(args.dataset, args.batch_size, False)

    epsilon = (args.epsilon / 255.) / std
    pgd_alpha = (args.pgd_alpha / 255.) / std

    model = StandardModel(args.dataset, args.arch, no_grad=False)
    model.apply(initialize_weights)
    model.cuda()
    model.train()

    opt = torch.optim.SGD(model.parameters(), lr=args.lr_max, momentum=0.9, weight_decay=5e-4)

    model, opt = amp.initialize(model, opt, opt_level="O2", loss_scale=1.0, master_weights=False)

    criterion = nn.CrossEntropyLoss()

    if args.attack == 'free':
        delta = torch.zeros(args.batch_size, 3, 32, 32).cuda()
        delta.requires_grad = True
    elif args.attack == 'fgsm' and args.fgsm_init == 'previous':
        delta = torch.zeros(args.batch_size, 3, 32, 32).cuda()
        delta.requires_grad = True

    if args.attack == 'free':
        assert args.epochs % args.attack_iters == 0
        epochs = int(math.ceil(args.epochs / args.attack_iters))
    else:
        epochs = args.epochs

    if args.lr_schedule == 'cyclic':
        lr_schedule = lambda t: np.interp([t], [0, args.epochs * 2 // 5, args.epochs], [0, args.lr_max, 0])[0]
    elif args.lr_schedule == 'piecewise':
        def lr_schedule(t):
            if t / args.epochs < 0.5:
                return args.lr_max
            elif t / args.epochs < 0.75:
                return args.lr_max / 10.
            else:
                return args.lr_max / 100.

    prev_robust_acc = 0.
    logger.info('Epoch \t Time \t LR \t \t Train Loss \t Train Acc')
    for epoch in range(epochs):
        start_time = time.time()
        train_loss = 0
        train_acc = 0
        train_n = 0
        for i, (X, y) in enumerate(train_loader):
            X = X.cuda().float()
            y = y.cuda().long()
            if i == 0:
                first_batch = X, y
            lr = lr_schedule(epoch + (i + 1) / len(train_loader))
            opt.param_groups[0].update(lr=lr)

            if args.attack == 'pgd':
                delta = attack_pgd(model, X, y, epsilon, pgd_alpha, args.attack_iters, args.restarts, opt)

            elif args.attack == 'fgsm':
                if args.fgsm_init == 'zero':
                    delta = torch.zeros_like(X, requires_grad=True)
                    delta.requires_grad = True
                elif args.fgsm_init == 'random':
                    delta = torch.zeros_like(X).cuda()
                    delta[:, 0, :, :].uniform_(-epsilon[0][0][0].item(), epsilon[0][0][0].item())
                    delta[:, 1, :, :].uniform_(-epsilon[1][0][0].item(), epsilon[1][0][0].item())
                    delta[:, 2, :, :].uniform_(-epsilon[2][0][0].item(), epsilon[2][0][0].item())
                    delta.requires_grad = True
                elif args.fgsm_init == 'previous':
                    delta.requires_grad = True
                output = model(X + delta[:X.size(0)])
                loss = F.cross_entropy(output, y)
                with amp.scale_loss(loss, opt) as scaled_loss:
                    scaled_loss.backward()
                grad = delta.grad.detach()
                delta.data = clamp(delta + args.fgsm_alpha * epsilon * torch.sign(grad), -epsilon, epsilon)
                delta = delta.detach()

            elif args.attack == 'free':
                delta.requires_grad = True
                for j in range(args.attack_iters):
                    epoch_iters = epoch * args.attack_iters + (i * args.attack_iters + j + 1) / len(train_loader)
                    lr = lr_schedule(epoch_iters)
                    opt.param_groups[0].update(lr=lr)
                    output = model(clamp(X + delta[:X.size(0)], lower_limit, upper_limit))
                    loss = F.cross_entropy(output, y)
                    opt.zero_grad()
                    with amp.scale_loss(loss, opt) as scaled_loss:
                        scaled_loss.backward()
                    grad = delta.grad.detach()
                    delta.data = clamp(delta + epsilon * torch.sign(grad), -epsilon, epsilon)
                    nn.utils.clip_grad_norm_(model.parameters(), 0.5)
                    opt.step()
                    delta.grad.zero_()
            elif args.attack == 'none':
                delta = torch.zeros_like(X)

            output = model(clamp(X + delta[:X.size(0)], lower_limit, upper_limit))
            loss = criterion(output, y)
            if args.attack != 'free':
                opt.zero_grad()
                with amp.scale_loss(loss, opt) as scaled_loss:
                    scaled_loss.backward()
                nn.utils.clip_grad_norm_(model.parameters(), 0.5)
                opt.step()

            train_loss += loss.item() * y.size(0)
            train_acc += (output.max(1)[1] == y).sum().item()
            train_n += y.size(0)

        if args.overfit_check:
            # Check current PGD robustness of model using random minibatch
            X, y = first_batch['input'], first_batch['target']
            pgd_delta = attack_pgd(model, X, y, epsilon, pgd_alpha, args.attack_iters, args.restarts, opt)
            with torch.no_grad():
                output = model(clamp(X + pgd_delta[:X.size(0)], lower_limit, upper_limit))
            robust_acc = (output.max(1)[1] == y).sum().item() / y.size(0)
            if robust_acc - prev_robust_acc < -0.5:
                break
            prev_robust_acc = robust_acc
        best_state_dict = copy.deepcopy(model.state_dict())

        train_time = time.time()
        logger.info('%d \t %.1f \t %.4f \t %.4f \t %.4f',
            epoch, train_time - start_time, lr, train_loss/train_n, train_acc/train_n)
    torch.save(best_state_dict, model_path)
    logger.info('Total time: %.4f', train_time - start_start_time)