Esempio n. 1
0
def advtrain(model, device, train_loader, optimizer, epoch, log_interval):
    model.train()
    avg_loss = 0
    # in training loop:

    adversary = FGSM(model,
                     loss_fn=nn.NLLLoss(reduction='sum'),
                     eps=0.3,
                     clip_min=0.,
                     clip_max=1.,
                     targeted=False)

    for batch_idx, (data, target) in enumerate(train_loader):
        # gpu나 cpu로 데이터를 옮김
        data, target = data.to(device), target.to(device)
        data = adversary.perturb(data, target)
        # gradient descent전에 gradient buffer를 0으로 초기화 하는 역할을 한다
        optimizer.zero_grad()
        output = model(data)
        # negative log-likelihood: nll loss, 딥러닝 모델의 손실함수이다
        loss = F.nll_loss(output, target)
        loss.backward()
        optimizer.step(
        )  # Does the update based on the current gradient stored in grad
        # 여기서 기존에 저장되어있던 gradient를 기반으로 update 하기 때문에 위의 초기화가 필요함
        avg_loss += F.nll_loss(output, target, reduction='sum').item()

        if batch_idx % log_interval == 0:
            print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
                epoch, batch_idx * len(data), len(train_loader.dataset),
                100. * batch_idx / len(train_loader), loss.item()))
    avg_loss /= len(train_loader.dataset)
    return avg_loss
Esempio n. 2
0
    def create_adv_input(self, x, y, model):
        # Prepare copied model
        model = copy.deepcopy(model)

        # Prepare input and corresponding label
        data = torch.from_numpy(np.expand_dims(x, axis=0).astype(np.float32))
        target = torch.from_numpy(np.array([y]).astype(np.int64))
        data.requires_grad = True

        from advertorch.attacks import GradientSignAttack
        adversary = GradientSignAttack(model.forward, eps=self.eps)
        perturbed_data = adversary.perturb(data, target)

        # Have to be different
        output = model.forward(perturbed_data)
        final_pred = output.max(
            1, keepdim=True)[1]  # get the index of the max log-probability

        if final_pred.item() == target.item():
            return perturbed_data, 0
        else:
            return perturbed_data, 1
Esempio n. 3
0
    nb_iter=40, eps_iter=0.01, rand_init=True, clip_min=0.0, clip_max=1.0,
    targeted=False)
    """

    from advertorch.attacks import GradientSignAttack
    import time
    t = time.time()
    adversary = GradientSignAttack(
        model,
        loss_fn=nn.CrossEntropyLoss(reduction="sum"),
        eps=0.02,
        clip_min=0.0,
        clip_max=1.0,
        targeted=False)

    adv_untarget = adversary.perturb(cln_data, true_label)
    target = torch.ones_like(true_label) * 3
    adversary.targeted = True
    adv_targeted = adversary.perturb(cln_data, target)

    pred_cln = get_cls(model(cln_data))
    pred_untarget = get_cls(model(adv_untarget))
    pred_target = get_cls(model(adv_targeted))

    import matplotlib.pyplot as plt
    plt.figure(figsize=(10, 8))
    for ii in range(batch_size):
        plt.subplot(3, batch_size, ii + 1)
        _imshow(cln_data[ii])
        plt.title("clean \n pred: {}".format(pred_cln[ii]))
        plt.subplot(3, batch_size, ii + 1 + batch_size)
adversary = GradientSignAttack(
    model, loss_fn=nn.CrossEntropyLoss(reduction="sum"), eps=0.3,
    clip_min=0.0, clip_max=1.0,
    targeted=False)
correct_1 = 0.0
correct_5 = 0.0
attack_correct_1 = 0.0
attack_correct_5 = 0.0
total = 0
for n_iter, (image, label) in enumerate(cifar100_test_loader):
    print("iteration: {}\ttotal {} iterations".format(n_iter + 1, len(cifar100_test_loader)))
    image = Variable(image).cuda()
    label = Variable(label).cuda()
    output = model(image)
    adv_untargeted = adversary.perturb(image,None)
    attack_output = model(adv_untargeted)
    # for i in range(16):
    #     save_image_tensor2pillow(image[i],str(i)+'.jpg')
    #     save_image_tensor2pillow(adv_untargeted[i],'attack_'+str(i)+'.jpg')    
    _, pred = output.topk(5, 1, largest=True, sorted=True)
    _attack,pred_attack = attack_output.topk(5, 1, largest=True, sorted=True)
    # pred为output的class index
    label = label.view(label.size(0), -1).expand_as(pred)
    correct = pred.eq(label).float()
    attack_correct = pred_attack.eq(label).float()
    print(pred)
    print("-"*50)
    print(pred_attack)
    #compute top 5
    correct_5 += correct[:, :5].sum()
Esempio n. 5
0
def train(epoch):
    net1.train()
    net2.train()

    adjust_learning_rate(optimizer, epoch)
    adjust_lamda(epoch)

    total_S1 = 0
    total_S2 = 0
    total_U1 = 0
    total_U2 = 0
    train_correct_S1 = 0
    train_correct_S2 = 0
    train_correct_U1 = 0
    train_correct_U2 = 0
    running_loss = 0.0
    ls = 0.0
    lc = 0.0
    ld = 0.0

    # create iterator for b1, b2, bu
    S_iter1 = iter(S_loader1)
    S_iter2 = iter(S_loader2)
    U_iter = iter(U_loader)
    print('epoch:', epoch + 1)
    # for i, (inputs, targets) in enumerate(zip(S_loader1, S_loader2, U_loader):
    for i in tqdm(range(step)):
        inputs_S1, labels_S1 = S_iter1.next()
        inputs_S2, labels_S2 = S_iter2.next()
        inputs_U, labels_U = U_iter.next(
        )  # note that labels_U will not be used for training.

        inputs_S1 = inputs_S1.cuda()
        labels_S1 = labels_S1.cuda()
        inputs_S2 = inputs_S2.cuda()
        labels_S2 = labels_S2.cuda()
        inputs_U = inputs_U.cuda()

        logit_S1 = net1(inputs_S1)
        logit_S2 = net2(inputs_S2)
        logit_U1 = net1(inputs_U)
        logit_U2 = net2(inputs_U)

        _, predictions_S1 = torch.max(logit_S1, 1)
        _, predictions_S2 = torch.max(logit_S2, 1)

        # pseudo labels of U
        _, predictions_U1 = torch.max(logit_U1, 1)
        _, predictions_U2 = torch.max(logit_U2, 1)

        #net1 adversary object
        adversary1 = GradientSignAttack(
            net1,
            loss_fn=nn.CrossEntropyLoss(reduction="sum"),
            eps=args.epsilon,
            clip_min=0.0,
            clip_max=1.0,
            targeted=False)

        #net2 adversary object
        adversary2 = GradientSignAttack(
            net2,
            loss_fn=nn.CrossEntropyLoss(reduction="sum"),
            eps=args.epsilon,
            clip_min=0.0,
            clip_max=1.0,
            targeted=False)

        #generate adversarial examples
        perturbed_data_S1 = adversary1.perturb(inputs_S1, labels_S1)
        perturbed_data_U1 = adversary1.perturb(inputs_U, predictions_U1)

        perturbed_data_S2 = adversary2.perturb(inputs_S2, labels_S2)
        perturbed_data_U2 = adversary2.perturb(inputs_U, predictions_U2)

        perturbed_logit_S1 = net1(perturbed_data_S2)
        perturbed_logit_S2 = net2(perturbed_data_S1)

        perturbed_logit_U1 = net1(perturbed_data_U2)
        perturbed_logit_U2 = net2(perturbed_data_U1)

        # zero the parameter gradients
        optimizer.zero_grad()
        net1.zero_grad()
        net2.zero_grad()

        Loss_sup = loss_sup(logit_S1, logit_S2, labels_S1, labels_S2)
        Loss_cot = loss_cot(logit_U1, logit_U2)
        Loss_diff = loss_diff(logit_S1, logit_S2, perturbed_logit_S1,
                              perturbed_logit_S2, logit_U1, logit_U2,
                              perturbed_logit_U1, perturbed_logit_U2)

        total_loss = Loss_sup + lambda_cot * Loss_cot + lambda_diff * Loss_diff
        total_loss.backward()
        optimizer.step()

        train_correct_S1 += np.sum(
            predictions_S1.cpu().numpy() == labels_S1.cpu().numpy())
        total_S1 += labels_S1.size(0)

        train_correct_U1 += np.sum(
            predictions_U1.cpu().numpy() == labels_U.cpu().numpy())
        total_U1 += labels_U.size(0)

        train_correct_S2 += np.sum(
            predictions_S2.cpu().numpy() == labels_S2.cpu().numpy())
        total_S2 += labels_S2.size(0)

        train_correct_U2 += np.sum(
            predictions_U2.cpu().numpy() == labels_U.cpu().numpy())
        total_U2 += labels_U.size(0)

        running_loss += total_loss.item()
        ls += Loss_sup.item()
        lc += Loss_cot.item()
        ld += Loss_diff.item()

        # using tensorboard to monitor loss and acc
        writer.add_scalars(
            'data/loss', {
                'loss_sup': Loss_sup.item(),
                'loss_cot': Loss_cot.item(),
                'loss_diff': Loss_diff.item()
            }, (epoch) * (step) + i)
        writer.add_scalars(
            'data/training_accuracy', {
                'net1 acc': 100. * (train_correct_S1) / (total_S1),
                'net2 acc': 100. * (train_correct_S2) / (total_S2)
            }, (epoch) * (step) + i)
        if (i + 1) % 50 == 0:
            # print statistics
            tqdm.write(
                'net1 training acc: %.3f%% | net2 training acc: %.3f%% | total loss: %.3f | loss_sup: %.3f | loss_cot: %.3f | loss_diff: %.3f  '
                % (100. * (train_correct_S1 + train_correct_U1) /
                   (total_S1 + total_U1), 100. *
                   (train_correct_S2 + train_correct_U2) /
                   (total_S2 + total_U2), running_loss / (i + 1), ls /
                   (i + 1), lc / (i + 1), ld / (i + 1)))
Esempio n. 6
0
                               loss_fn=nn.CrossEntropyLoss(reduction="sum"),
                               eps=0.3,
                               clip_min=0.0,
                               clip_max=1.0,
                               targeted=False)

for epoch in range(nb_epoch):
    model.train()
    for batch_idx, (data, target) in enumerate(train_loader):
        data, target = data.to(device), target.to(device)
        ori = data
        if mode == 'adv' or (mode == 'half' and random.random() > 0.5):
            # when performing attack, the model needs to be in eval mode
            # also the parameters should be accumulating gradients
            with ctx_noparamgrad_and_eval(model):
                data = adversary.perturb(data, target)

        optimizer.zero_grad()
        output = model(data)
        loss = F.cross_entropy(output, target, reduction='elementwise_mean')
        loss.backward()
        optimizer.step()
        if batch_idx % log_interval == 0:
            print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
                epoch, batch_idx * len(data), len(train_loader.dataset),
                100. * batch_idx / len(train_loader), loss.item()))

    model.eval()
    test_clnloss = 0
    clncorrect = 0