print("skipping target: {}".format(target_idx))
                no_save = False
                break
            if args.device == 'cuda':
                state_dict = torch.load(poisons_path)
            else:
                state_dict = torch.load(poisons_path,
                                        map_location=torch.device('cpu'))

            poison_tuple_list, base_idx_list = state_dict[
                'poison'], state_dict['idx']
            print("Poisons loaded")
            poisoned_dset = PoisonedDataset(
                args.train_data_path,
                subset='others',
                transform=transform_train,
                num_per_label=args.num_per_class,
                poison_tuple_list=poison_tuple_list,
                poison_indices=base_idx_list,
                subset_group=args.subset_group)
            print("Poisoned dataset created")
            res[ite] = get_stats(
                '{}/{}/log.txt'.format(args.eval_poisons_root, target_idx),
                state_dict, ite - 1)

            res[ite]['victims'] = {}
            for victim_name in args.target_net:
                print(victim_name)
                victim_net = load_pretrained_net(
                    victim_name,
                    args.test_chk_name,
                    model_chk_path=args.model_resume_path,
Exemplo n.º 2
0
def train_network_with_poison(net, target_imgs, targets_indices, poison_tuple_list, base_idx_list, chk_path, args,
                              save_state=False, eval_targets=None, device='cuda'):
    # requires implementing a get_penultimate_params_list() method to get the parameter identifier of the net's last
    # layer
    if args.end2end:
        params = net.parameters()
    else:
        params = net.module.get_penultimate_params_list()

    if args.retrain_opt == 'adam':
        print("Using Adam for retraining")
        optimizer = torch.optim.Adam(params, lr=args.retrain_lr, weight_decay=args.retrain_wd)
    else:
        print("Using SGD for retraining")
        optimizer = torch.optim.SGD(params, lr=args.retrain_lr, momentum=args.retrain_momentum,
                                    weight_decay=args.retrain_wd)

    net.eval()

    criterion = nn.CrossEntropyLoss().to('cuda')

    # Create the poisoned dataset
    transform_train = transforms.Compose([
        transforms.ToTensor(),
        transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)),
    ])
    transform_test = transforms.Compose([
        transforms.ToTensor(),
        transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)),
    ])
    poisoned_dset = PoisonedDataset(args.train_data_path, subset='others', transform=transform_train,
                                    num_per_label=args.num_per_class, poison_tuple_list=poison_tuple_list,
                                    poison_indices=base_idx_list, subset_group=args.subset_group)

    poisoned_loader = torch.utils.data.DataLoader(poisoned_dset, batch_size=args.retrain_bsize, shuffle=True)

    # The test set of clean CIFAR10
    testset = torchvision.datasets.CIFAR10(root=args.dset_path, train=False, download=True, transform=transform_test)
    test_loader = torch.utils.data.DataLoader(testset, batch_size=500)

    if not args.end2end:
        # create a dataloader that returns the features
        poisoned_loader = torch.utils.data.DataLoader(FeatureSet(poisoned_loader, net, device=args.device),
                                                      batch_size=64, shuffle=True)

    for epoch in range(args.retrain_epochs):
        net.eval()
        loss_meter = AverageMeter()
        acc_meter = AverageMeter()
        time_meter = AverageMeter()

        if epoch in args.lr_decay_epoch:
            for param_group in optimizer.param_groups:
                param_group['lr'] *= 0.1

        end_time = time.time()
        for ite, (input, target) in enumerate(poisoned_loader):
            input, target = input.to('cuda'), target.to('cuda')

            if args.end2end:
                feat = net.module.penultimate(input)
            else:
                feat = input
            output = net.module.linear(feat)

            loss = criterion(output, target)

            optimizer.zero_grad()
            loss.backward()
            optimizer.step()

            prec1 = accuracy(output, target)[0]

            time_meter.update(time.time() - end_time)
            end_time = time.time()
            loss_meter.update(loss.item(), input.size(0))
            acc_meter.update(prec1.item(), input.size(0))

            if epoch % 30 == 0 and (ite == len(poisoned_loader) - 1):
                print("{2}, Epoch {0}, Iteration {1}, loss {loss.val:.3f} ({loss.avg:.3f}), "
                      "acc {acc.val:.3f} ({acc.avg:.3f})".
                      format(epoch, ite, time.strftime("%Y-%m-%d %H:%M:%S"),
                             loss=loss_meter, acc=acc_meter))
            sys.stdout.flush()

        if epoch == args.retrain_epochs - 1:
            # print the scores for target and base

            print("------------")
            print("Stats after retraining for {} epochs".format(epoch))
            poison_pred_list = []
            for poison_img, _ in poison_tuple_list:
                base_scores = net(poison_img[None, :, :, :].to(device))
                base_score, base_pred = base_scores.topk(1, 1, True, True)
                poison_pred_list.append(base_pred.item())
            print("Target label: {}, Poison label: {}, Poisons' Predictions:{}"
                  .format(args.target_label, args.poison_label, poison_pred_list))
            targets_acc_meter = AverageMeter()
            for idx, target_img in zip(targets_indices, target_imgs):
                # print the scores for target and base
                target_pred = net(target_img.to(device))
                score, pred = target_pred.topk(1, 1, True, True)
                prec = accuracy(target_pred, torch.tensor([args.poison_label]).to(device))[0]
                targets_acc_meter.update(prec.item(), target_img.size(0))
                print("Target sample: {}, Prediction:{}, Target's Score:{}".format(idx,
                                                                                   pred[0][0].item(), list(
                        target_pred.detach().view(-1).cpu().numpy())))
            print("Current ATTACK acc on target samples: {acc.avg:.3f}".
                  format(acc=targets_acc_meter))

    # Evaluate the results on the clean test set
    print("-----------------------------------------------")
    print("Now evaluating the network on the clean test set")
    val_acc_meter = AverageMeter()
    with torch.no_grad():
        for ite, (input, target) in enumerate(test_loader):
            input, target = input.to(device), target.to(device)
            output = net(input)

            prec1 = accuracy(output, target)[0]
            val_acc_meter.update(prec1.item(), input.size(0))

            if ite % 100 == 0 or ite == len(test_loader) - 1:
                print("{2} Epoch {0}, Val iteration {1}, "
                      "acc {acc.val:.3f} ({acc.avg:.3f})".
                      format(epoch, ite, time.strftime("%Y-%m-%d %H:%M:%S"), acc=val_acc_meter))
    print("* Prec: {}".format(val_acc_meter.avg))
    print("-----------------------------")
    eval_targets_acc_meter = AverageMeter()
    if eval_targets is not None:
        print("Now evaluating on the extenral target eval set")
        preds = []
        with torch.no_grad():
            for ite, (input, target) in enumerate(eval_targets):
                input, target = input.to(device), target.to(device)
                output = net(input)
                _, pred = output.topk(1, 1, True, True)
                preds.append(str(pred[0][0].item()))

                prec1 = accuracy(output, torch.tensor([args.poison_label]).to(device))[0]
                eval_targets_acc_meter.update(prec1.item(), input.size(0))
        print("Predictions for the external targets: {}".format(", ".join(preds)))
        print("ATTACK acc: {}".format(eval_targets_acc_meter.avg))

    if save_state:
        state_dict = {"state_dict": net.state_dict(), "epoch": epoch, "acc": val_acc_meter.avg}
        torch.save(state_dict, os.path.join(chk_path, 'last_epoch.pth'))

    return targets_acc_meter.avg, eval_targets_acc_meter.avg