From acfd87e065ec5aabff1295ffbffafaf54057cb6c Mon Sep 17 00:00:00 2001 From: Kyle Matoba <22180455+kylematoba@users.noreply.github.com> Date: Sun, 26 Dec 2021 20:56:44 +0100 Subject: [PATCH] Make FGM work for exotic dtypes. Some black-ing, pep8-ing. Fix broken test. --- cleverhans/torch/attacks/fast_gradient_method.py | 4 +++- cleverhans/torch/attacks/hop_skip_jump_attack.py | 10 +++++----- cleverhans/torch/tests/test_attacks.py | 2 ++ cleverhans/torch/utils.py | 1 - 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/cleverhans/torch/attacks/fast_gradient_method.py b/cleverhans/torch/attacks/fast_gradient_method.py index 042a62690..156368b38 100644 --- a/cleverhans/torch/attacks/fast_gradient_method.py +++ b/cleverhans/torch/attacks/fast_gradient_method.py @@ -71,7 +71,9 @@ def fast_gradient_method( # x needs to be a leaf variable, of floating point type and have requires_grad being True for # its grad to be computed and stored properly in a backward call - x = x.clone().detach().to(torch.float).requires_grad_(True) + # kylematoba: probably don't need this, but I'll add it here to respect the intention of the earlier cast + assert torch.is_floating_point(x) + x = x.clone().detach().to(x.dtype).requires_grad_(True) if y is None: # Using model predictions as ground truth to avoid label leaking _, y = torch.max(model_fn(x), 1) diff --git a/cleverhans/torch/attacks/hop_skip_jump_attack.py b/cleverhans/torch/attacks/hop_skip_jump_attack.py index fbe3acbea..8b3f12b66 100644 --- a/cleverhans/torch/attacks/hop_skip_jump_attack.py +++ b/cleverhans/torch/attacks/hop_skip_jump_attack.py @@ -89,7 +89,7 @@ def decision_function(images): images = torch.clamp(images, clip_min, clip_max) prob = [] for i in range(0, len(images), batch_size): - batch = images[i : i + batch_size] + batch = images[i: i + batch_size] prob_i = model_fn(batch) prob.append(prob_i) prob = torch.cat(prob, dim=0) @@ -214,7 +214,7 @@ def decision_function(images): def compute_distance(x_ori, x_pert, constraint=2): - """ Compute the distance between two images. """ + """Compute the distance between two images.""" if constraint == 2: dist = torch.norm(x_ori - x_pert, p=2) elif constraint == np.inf: @@ -225,7 +225,7 @@ def compute_distance(x_ori, x_pert, constraint=2): def approximate_gradient( decision_function, sample, num_evals, delta, constraint, shape, clip_min, clip_max ): - """ Gradient direction estimation """ + """Gradient direction estimation""" # Generate random vectors. noise_shape = [num_evals] + list(shape) if constraint == 2: @@ -260,7 +260,7 @@ def approximate_gradient( def project(original_image, perturbed_images, alphas, shape, constraint): - """ Projection onto given l2 / linf balls in a batch. """ + """Projection onto given l2 / linf balls in a batch.""" alphas = alphas.view((alphas.shape[0],) + (1,) * (len(shape) - 1)) if constraint == 2: projected = (1 - alphas) * original_image + alphas * perturbed_images @@ -274,7 +274,7 @@ def project(original_image, perturbed_images, alphas, shape, constraint): def binary_search_batch( original_image, perturbed_images, decision_function, shape, constraint, theta ): - """ Binary search to approach the boundary. """ + """Binary search to approach the boundary.""" # Compute distance between each of perturbed image and original image. dists_post_update = torch.stack( diff --git a/cleverhans/torch/tests/test_attacks.py b/cleverhans/torch/tests/test_attacks.py index 3715de197..9b3caf8e8 100644 --- a/cleverhans/torch/tests/test_attacks.py +++ b/cleverhans/torch/tests/test_attacks.py @@ -489,6 +489,7 @@ def test_clips(self): if norm == 1: self.assertRaises( NotImplementedError, + self.attack, model_fn=self.model, x=self.normalized_x, eps=0.3, @@ -1045,3 +1046,4 @@ def test_grad_sparsity_checks(self): with self.assertRaises(ValueError) as context: gs = torch.empty(101).uniform_(90, 99) self.generate_adversarial_examples(sanity_checks=False, grad_sparsity=gs) + diff --git a/cleverhans/torch/utils.py b/cleverhans/torch/utils.py index f5ada925a..d4e4942ce 100644 --- a/cleverhans/torch/utils.py +++ b/cleverhans/torch/utils.py @@ -84,7 +84,6 @@ def optimize_linear(grad, eps, norm=np.inf): # Take sign of gradient optimal_perturbation = torch.sign(grad) elif norm == 1: - abs_grad = torch.abs(grad) sign = torch.sign(grad) red_ind = list(range(1, len(grad.size()))) abs_grad = torch.abs(grad)