Note
Click here to download the full example code
Visualizing Adversarial ExamplesΒΆ
This example shows how to generate and plot adversarial examples for a batch of datapoints from CIFAR-10, and compares the examples from different constraint sets, penalizations and solvers.
Out:
<frozen importlib._bootstrap>:219: RuntimeWarning: numpy.ufunc size changed, may indicate binary incompatibility. Expected 192 from C header, got 216 from PyObject
<frozen importlib._bootstrap>:219: RuntimeWarning: numpy.ufunc size changed, may indicate binary incompatibility. Expected 192 from C header, got 216 from PyObject
Files already downloaded and verified
L2 norm constraint.
GroupL1 constraint.
F1 score: 0.095 for alpha=0.8000
Nuclear norm ball adv examples
F1 score: 0.633 for alpha=0.5000
from itertools import product
import numpy as np
import torch
import torchvision
from robustbench.data import load_cifar10
from robustbench.utils import load_model
import matplotlib.pyplot as plt
import chop
from chop.image import group_patches, matplotlib_imshow_batch
from chop.logging import Trace
from sklearn.metrics import f1_score
from torch.autograd import profiler
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
# device = torch.device('cpu')
batch_size = 7
# Note that this example uses load_cifar10 from the robustbench library
data, target = load_cifar10(n_examples=batch_size, data_dir='~/datasets')
data = data.to(device)
target = target.to(device)
classes = ('plane', 'car', 'bird', 'cat',
'deer', 'dog', 'frog', 'horse',
'ship', 'truck')
model = load_model('Standard') # Can be changed to any model from the robustbench model zoo
model = model.to(device)
criterion = torch.nn.CrossEntropyLoss(reduction='none')
# Define the constraint set + initial point
print("L2 norm constraint.")
alpha = 127 / 255
constraint = chop.constraints.L2Ball(alpha)
def image_constraint_prox(delta, step_size=None):
adv_img = torch.clamp(data + delta, 0, 1)
delta = adv_img - data
return delta
def prox(delta, step_size=None):
delta = constraint.prox(delta, step_size)
delta = image_constraint_prox(delta, step_size)
return delta
adversary = chop.Adversary(chop.optim.minimize_pgd_madry)
callback_L2 = Trace()
_, delta = adversary.perturb(data, target, model, criterion,
prox=prox,
lmo=constraint.lmo,
max_iter=20,
step=2. / 20,
callback=callback_L2)
# Plot adversarial images
fig, ax = plt.subplots(nrows=7, ncols=batch_size, figsize=(16, 14))
# Plot clean data
matplotlib_imshow_batch(data, labels=[classes[k] for k in target], axes=ax[0, :],
title="Original images")
# Adversarial Lp images
adv_output = model(data + delta)
adv_labels = torch.argmax(adv_output, dim=-1)
matplotlib_imshow_batch(data + delta, labels=[classes[k] for k in adv_labels], axes=ax[1, :],
title=f'L{constraint.p}')
# Perturbation
matplotlib_imshow_batch(abs(delta), axes=ax[4, :], normalize=True,
title=f'L{constraint.p}')
print("GroupL1 constraint.")
groups = group_patches(x_patch_size=8, y_patch_size=8)
for eps in [5e-2]:
alpha = eps * len(groups)
constraint_group = chop.constraints.GroupL1Ball(alpha, groups)
adversary_group = chop.Adversary(chop.optim.minimize_frank_wolfe)
# callback_group = Trace(callable=lambda kw: criterion(model(data + kw['x']), target))
callback_group = Trace()
with profiler.profile() as prof:
_, delta_group = adversary_group.perturb(data, target, model, criterion,
lmo=constraint_group.lmo,
max_iter=20,
callback=callback_group)
delta_group = image_constraint_prox(delta_group)
# Show adversarial examples and perturbations
adv_output_group = model(data + delta_group)
adv_labels_group = torch.argmax(adv_output_group, dim=-1)
matplotlib_imshow_batch(data + delta_group, labels=(classes[k] for k in adv_labels_group),
axes=ax[2, :],
title='Group Lasso')
matplotlib_imshow_batch(abs(delta_group), axes=ax[5, :], normalize=True,
title='Group Lasso')
print(f"F1 score: {f1_score(target.detach().cpu(), adv_labels_group.detach().cpu(), average='macro'):.3f}"
f" for alpha={alpha:.4f}")
print("Nuclear norm ball adv examples")
for alpha in [.5]:
constraint_nuc = chop.constraints.NuclearNormBall(alpha)
def prox_nuc(delta, step_size=None):
delta = constraint_nuc.prox(delta, step_size)
delta = image_constraint_prox(delta, step_size)
return delta
adversary = chop.Adversary(chop.optim.minimize_frank_wolfe)
callback_nuc = Trace()
_, delta_nuc = adversary.perturb(data, target, model, criterion,
# prox=prox,
lmo=constraint_nuc.lmo,
max_iter=20,
# step=2. / 20,
callback=callback_nuc)
# Clamp last iterate to image space
delta_nuc = image_constraint_prox(delta_nuc)
# Add nuclear examples to plot
adv_output_nuc = model(data + delta_nuc)
adv_labels_nuc = torch.argmax(adv_output_nuc, dim=-1)
matplotlib_imshow_batch(data + delta_nuc, labels=(classes[k] for k in adv_labels_nuc),
axes=ax[3, :],
title='Nuclear Norm')
matplotlib_imshow_batch(abs(delta_nuc), axes=ax[6, :], normalize=True,
title='Nuclear Norm')
print(f"F1 score: {f1_score(target.detach().cpu(), adv_labels_nuc.detach().cpu(), average='macro'):.3f}"
f" for alpha={alpha:.4f}")
plt.tight_layout()
plt.show()
# TODO refactor this in functions
# Plot group lasso loss values
fig, ax = plt.subplots(figsize=(6, 10), nrows=batch_size, sharex=True)
for k in range(batch_size):
ax[k].plot([-trace[k] for trace in callback_group.trace_f])
plt.tight_layout()
plt.show()
# Plot loss functions per datapoint
fig, ax = plt.subplots(figsize=(6, 10), nrows=batch_size, sharex=True)
for k in range(batch_size):
ax[k].plot([-trace[k] for trace in callback_nuc.trace_f])
plt.tight_layout()
plt.show()
# Plot loss functions per datapoint
fig, ax = plt.subplots(figsize=(6, 10), nrows=batch_size, sharex=True)
for k in range(batch_size):
ax[k].plot([-trace[k] for trace in callback_L2.trace_f])
plt.tight_layout()
plt.show()
Total running time of the script: ( 0 minutes 22.447 seconds)
Estimated memory usage: 2548 MB