Skip to content

Commit

Permalink
Update workflows for TensorFlow/Keras 2.14
Browse files Browse the repository at this point in the history
Signed-off-by: Beat Buesser <[email protected]>
  • Loading branch information
beat-buesser committed Oct 21, 2023
1 parent 010201a commit fe81770
Show file tree
Hide file tree
Showing 35 changed files with 107 additions and 94 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

import logging
import math
from typing import Optional, Tuple, Union, TYPE_CHECKING
from typing import Any, Optional, Tuple, Union, TYPE_CHECKING

import numpy as np
from tqdm.auto import trange
Expand Down Expand Up @@ -270,15 +270,15 @@ def _get_circular_patch_mask(self, nb_samples: int, sharpness: int = 40) -> "tor
y = np.linspace(-1, 1, diameter)
x_grid, y_grid = np.meshgrid(x, y, sparse=True)
z_grid = (x_grid ** 2 + y_grid ** 2) ** sharpness
image_mask = 1 - np.clip(z_grid, -1, 1)
image_mask: Union[int, np.ndarray[Any, np.dtype[Any]]] = 1 - np.clip(z_grid, -1, 1)
elif self.patch_type == "square":
image_mask = np.ones((diameter, diameter))

image_mask = np.expand_dims(image_mask, axis=0)
image_mask = np.broadcast_to(image_mask, self.patch_shape)
image_mask = torch.Tensor(np.array(image_mask)).to(self.estimator.device)
image_mask = torch.stack([image_mask] * nb_samples, dim=0)
return image_mask
image_mask_tensor = torch.Tensor(np.array(image_mask)).to(self.estimator.device)
image_mask_tensor = torch.stack([image_mask_tensor] * nb_samples, dim=0)
return image_mask_tensor

def _random_overlay(
self,
Expand Down
10 changes: 5 additions & 5 deletions art/attacks/evasion/boundary.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
from __future__ import absolute_import, division, print_function, unicode_literals

import logging
from typing import Optional, Tuple, TYPE_CHECKING
from typing import List, Optional, Tuple, TYPE_CHECKING

import numpy as np
from tqdm.auto import tqdm, trange
Expand Down Expand Up @@ -268,14 +268,14 @@ def _attack(
for _ in trange(self.max_iter, desc="Boundary attack - iterations", disable=not self.verbose):
# Trust region method to adjust delta
for _ in range(self.num_trial):
potential_advs = []
potential_advs_list: List[np.ndarray] = []
for _ in range(self.sample_size):
potential_adv = x_adv + self._orthogonal_perturb(self.curr_delta, x_adv, original_sample)
potential_adv = np.clip(potential_adv, clip_min, clip_max)
potential_advs.append(potential_adv)
potential_advs_list.append(potential_adv)

preds = np.argmax(
self.estimator.predict(np.array(potential_advs), batch_size=self.batch_size),
self.estimator.predict(np.array(potential_advs_list), batch_size=self.batch_size),
axis=1,
)

Expand All @@ -292,7 +292,7 @@ def _attack(
self.curr_delta /= self.step_adapt

if delta_ratio > 0:
x_advs = np.array(potential_advs)[np.where(satisfied)[0]]
x_advs = np.array(potential_advs_list)[np.where(satisfied)[0]]
break
else: # pragma: no cover
logger.warning("Adversarial example found but not optimal.")
Expand Down
8 changes: 4 additions & 4 deletions art/attacks/evasion/brendel_bethge.py
Original file line number Diff line number Diff line change
Expand Up @@ -2378,7 +2378,7 @@ def generate(
return best_advs.astype(config.ART_NUMPY_DTYPE)

def norms(self, x: np.ndarray) -> np.ndarray:
order = self.norm if self.norm != "inf" else np.inf
order = float(self.norm) if self.norm != "inf" else np.inf
norm = np.linalg.norm(x=x.reshape(x.shape[0], -1), ord=order, axis=1)
return norm

Expand Down Expand Up @@ -2542,15 +2542,15 @@ def _binary_search(
"""
# First set upper and lower bounds as well as the threshold for the binary search
if norm == 2:
(upper_bound, lower_bound) = (1, 0)
(upper_bound, lower_bound) = (np.array(1.0), np.array(0.0))

if threshold is None:
threshold = self.theta

else:
(upper_bound, lower_bound) = (
np.max(abs(original_sample - current_sample)),
0,
np.array(0.0),
)

if threshold is None:
Expand Down Expand Up @@ -2580,7 +2580,7 @@ def _binary_search(
result = self._interpolate(
current_sample=current_sample,
original_sample=original_sample,
alpha=upper_bound,
alpha=float(upper_bound),
norm=norm,
)

Expand Down
2 changes: 1 addition & 1 deletion art/attacks/evasion/carlini.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ def __init__(
self._tanh_smoother = 0.999999

def _loss(
self, x: np.ndarray, x_adv: np.ndarray, target: np.ndarray, c_weight: float
self, x: np.ndarray, x_adv: np.ndarray, target: np.ndarray, c_weight: np.ndarray
) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:
"""
Compute the objective function value.
Expand Down
4 changes: 2 additions & 2 deletions art/attacks/evasion/dpatch_robust.py
Original file line number Diff line number Diff line change
Expand Up @@ -409,8 +409,8 @@ def _untransform_gradients(
gradients = transforms["brightness"] * gradients

# Undo rotations:
rot90 = (4 - transforms["rot90"]) % 4
gradients = np.rot90(gradients, rot90, (1, 2))
rot90 = int((4 - transforms["rot90"]) % 4)
gradients = np.rot90(gradients, k=rot90, axes=(1, 2))

# Account for cropping when considering the upper left point of the patch:
x_1 = self.patch_location[0] - int(transforms["crop_x"])
Expand Down
14 changes: 10 additions & 4 deletions art/attacks/evasion/fast_gradient.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,14 +159,17 @@ def _minimal_perturbation(self, x: np.ndarray, y: np.ndarray, mask: np.ndarray)
# Get current predictions
active_indices = np.arange(len(batch))

current_eps: Union[int, float, np.ndarray]
partial_stop_condition: Union[bool, np.ndarray]

if isinstance(self.eps, np.ndarray) and isinstance(self.eps_step, np.ndarray):
if len(self.eps.shape) == len(x.shape) and self.eps.shape[0] == x.shape[0]:
current_eps = self.eps_step[batch_index_1:batch_index_2]
partial_stop_condition = (current_eps <= self.eps[batch_index_1:batch_index_2]).all()
partial_stop_condition = bool((current_eps <= self.eps[batch_index_1:batch_index_2]).all())

else:
current_eps = self.eps_step
partial_stop_condition = (current_eps <= self.eps).all()
partial_stop_condition = bool((current_eps <= self.eps).all())

else:
current_eps = self.eps_step
Expand All @@ -190,11 +193,11 @@ def _minimal_perturbation(self, x: np.ndarray, y: np.ndarray, mask: np.ndarray)
if isinstance(self.eps, np.ndarray) and isinstance(self.eps_step, np.ndarray):
if len(self.eps.shape) == len(x.shape) and self.eps.shape[0] == x.shape[0]:
current_eps = current_eps + self.eps_step[batch_index_1:batch_index_2]
partial_stop_condition = (current_eps <= self.eps[batch_index_1:batch_index_2]).all()
partial_stop_condition = bool((current_eps <= self.eps[batch_index_1:batch_index_2]).all())

else:
current_eps = current_eps + self.eps_step
partial_stop_condition = (current_eps <= self.eps).all()
partial_stop_condition = bool((current_eps <= self.eps).all())

else:
current_eps = current_eps + self.eps_step
Expand Down Expand Up @@ -539,6 +542,9 @@ def _compute(
# Get perturbation
perturbation = self._compute_perturbation(batch, batch_labels, mask_batch, decay, momentum)

batch_eps: Union[int, float, np.ndarray]
batch_eps_step: Union[int, float, np.ndarray]

# Compute batch_eps and batch_eps_step
if isinstance(eps, np.ndarray) and isinstance(eps_step, np.ndarray):
if len(eps.shape) == len(x.shape) and eps.shape[0] == x.shape[0]:
Expand Down
6 changes: 3 additions & 3 deletions art/attacks/evasion/hop_skip_jump.py
Original file line number Diff line number Diff line change
Expand Up @@ -485,15 +485,15 @@ def _binary_search(
"""
# First set upper and lower bounds as well as the threshold for the binary search
if norm == 2:
(upper_bound, lower_bound) = (1, 0)
(upper_bound, lower_bound) = (np.array(1.0), np.array(0.0))

if threshold is None:
threshold = self.theta

else:
(upper_bound, lower_bound) = (
np.max(abs(original_sample - current_sample)),
0,
np.array(0.0),
)

if threshold is None:
Expand Down Expand Up @@ -523,7 +523,7 @@ def _binary_search(
result = self._interpolate(
current_sample=current_sample,
original_sample=original_sample,
alpha=upper_bound,
alpha=float(upper_bound),
norm=norm,
)

Expand Down
5 changes: 2 additions & 3 deletions art/attacks/evasion/lowprofool.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,8 @@ def __weighted_lp_norm(self, perturbations: np.ndarray) -> np.ndarray:
:param perturbations: Perturbations of samples towards being adversarial.
:return: Array with weighted Lp-norm of perturbations.
"""
return self.lambd * np.linalg.norm(
self.importance_vec * perturbations, axis=1, ord=(np.inf if self.norm == "inf" else self.norm)
).reshape(-1, 1)
order: Union[int, float] = np.inf if self.norm == "inf" else float(self.norm)
return self.lambd * np.linalg.norm(self.importance_vec * perturbations, axis=1, ord=order).reshape(-1, 1)

def __weighted_lp_norm_gradient(self, perturbations: np.ndarray) -> np.ndarray:
"""
Expand Down
2 changes: 1 addition & 1 deletion art/attacks/evasion/pe_malware_attack.py
Original file line number Diff line number Diff line change
Expand Up @@ -816,7 +816,7 @@ def get_dos_locations(x: np.ndarray) -> Tuple[List[List[int]], List[List[int]]]:
size.append(int(0x3C) - mz_offset)
start.append(mz_offset)

size.append(pointer_to_pe_header - int(0x40) - 1)
size.append(int(pointer_to_pe_header) - int(0x40) - 1)
start.append(int(0x40))

batch_of_starts.append(start)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,9 @@ def generate(self, x: np.ndarray, y: Optional[np.ndarray] = None, **kwargs) -> n

batch_index_1, batch_index_2 = batch_id * self.batch_size, (batch_id + 1) * self.batch_size

batch_eps: Union[int, float, np.ndarray]
batch_eps_step: Union[int, float, np.ndarray]

# Compute batch_eps and batch_eps_step
if isinstance(self.eps, np.ndarray) and isinstance(self.eps_step, np.ndarray):
if len(self.eps.shape) == len(x.shape) and self.eps.shape[0] == x.shape[0]:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,9 @@ def generate(self, x: np.ndarray, y: Optional[np.ndarray] = None, **kwargs) -> n

batch_index_1, batch_index_2 = batch_id * self.batch_size, (batch_id + 1) * self.batch_size

batch_eps: Union[int, float, np.ndarray]
batch_eps_step: Union[int, float, np.ndarray]

# Compute batch_eps and batch_eps_step
if isinstance(self.eps, np.ndarray) and isinstance(self.eps_step, np.ndarray):
if len(self.eps.shape) == len(x.shape) and self.eps.shape[0] == x.shape[0]:
Expand Down
4 changes: 2 additions & 2 deletions art/attacks/extraction/knockoff_nets.py
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,7 @@ def _reward_loss(self, y_output: np.ndarray, y_hat: np.ndarray) -> float:

return reward

def _reward_all(self, y_output: np.ndarray, y_hat: np.ndarray, n: int) -> np.ndarray:
def _reward_all(self, y_output: np.ndarray, y_hat: np.ndarray, n: int) -> float:
"""
Compute `all` reward value.
Expand All @@ -395,7 +395,7 @@ def _reward_all(self, y_output: np.ndarray, y_hat: np.ndarray, n: int) -> np.nda
else:
reward = [max(min(r, 1), 0) for r in reward]

return np.mean(reward)
return float(np.mean(reward))

def _check_params(self) -> None:
if not isinstance(self.batch_size_fit, int) or self.batch_size_fit <= 0:
Expand Down
7 changes: 5 additions & 2 deletions art/attacks/inference/reconstruction/white_box.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ def reconstruct(self, x: np.ndarray, y: Optional[np.ndarray] = None, **kwargs) -

tol = float("inf")
x_0 = x[0, :]
x_guess = None
y_guess = None
x_guess: Optional[np.ndarray] = None
y_guess: int

for _y in range(self.estimator.nb_classes):
args = (_y, x, y, self._estimator, self.estimator, self.params)
Expand All @@ -97,6 +97,9 @@ def reconstruct(self, x: np.ndarray, y: Optional[np.ndarray] = None, **kwargs) -
x_guess = _x
y_guess = _y

if x_guess is None:
raise ValueError("Guessed values are None.")

x_reconstructed = np.expand_dims(x_guess, axis=0)
y_reconstructed = np.zeros(shape=(1, self.estimator.nb_classes))
y_reconstructed[0, y_guess] = 1
Expand Down
4 changes: 3 additions & 1 deletion art/attacks/poisoning/feature_collision_attack.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,9 @@ def objective(
num_features = base_image.size
num_activations = poison_feature_rep.size
beta = self.similarity_coeff * (num_activations / num_features) ** 2
return np.linalg.norm(poison_feature_rep - target_feature_rep) + beta * np.linalg.norm(poison - base_image)
return float(
np.linalg.norm(poison_feature_rep - target_feature_rep) + beta * np.linalg.norm(poison - base_image)
)

def _check_params(self) -> None:
if self.learning_rate <= 0:
Expand Down
10 changes: 5 additions & 5 deletions art/attacks/poisoning/gradient_matching_attack.py
Original file line number Diff line number Diff line change
Expand Up @@ -314,11 +314,11 @@ def __init__(
self,
gradient_matching: GradientMatchingAttack,
classifier: PyTorchClassifier,
epsilon: float,
num_poison: int,
len_noise: int,
min_: float,
max_: float,
epsilon,
num_poison,
len_noise,
min_,
max_,
):
super().__init__()
self.gradient_matching = gradient_matching
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ def poison( # pylint: disable=W0221
dist[min_index[0], min_index[1]] = 1e5

loss = np.linalg.norm(feat1 - feat2) ** 2
losses.update(loss, len(trigger_samples))
losses.update(float(loss), len(trigger_samples))

# loss gradient computation for KerasClassifier
if isinstance(self.estimator, KerasClassifier):
Expand Down
16 changes: 8 additions & 8 deletions art/attacks/poisoning/poisoning_attack_svm.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,14 @@ class PoisoningAttackSVM(PoisoningAttackWhiteBox):
def __init__(
self,
classifier: "ScikitlearnSVC",
step: Optional[float] = None,
eps: Optional[float] = None,
x_train: Optional[np.ndarray] = None,
y_train: Optional[np.ndarray] = None,
x_val: Optional[np.ndarray] = None,
y_val: Optional[np.ndarray] = None,
max_iter: int = 100,
verbose: bool = True,
step: float,
eps: float,
x_train: np.ndarray,
y_train: np.ndarray,
x_val: np.ndarray,
y_val: np.ndarray,
max_iter: int,
verbose: bool,
) -> None:
"""
Initialize an SVM poisoning attack.
Expand Down
4 changes: 2 additions & 2 deletions art/attacks/poisoning/sleeper_agent_attack.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,10 @@ def __init__(
"""
if isinstance(classifier.preprocessing, (StandardisationMeanStdPyTorch, StandardisationMeanStdTensorFlow)):
clip_values_normalised = (
classifier.clip_values - classifier.preprocessing.mean
classifier.clip_values - classifier.preprocessing.mean # type: ignore
) / classifier.preprocessing.std
clip_values_normalised = (clip_values_normalised[0], clip_values_normalised[1])
epsilon_normalised = epsilon * (clip_values_normalised[1] - clip_values_normalised[0])
epsilon_normalised = epsilon * (clip_values_normalised[1] - clip_values_normalised[0]) # type: ignore
patch_normalised = (patch - classifier.preprocessing.mean) / classifier.preprocessing.std
else:
raise ValueError("classifier.preprocessing not an instance of pytorch/tensorflow")
Expand Down
Loading

0 comments on commit fe81770

Please sign in to comment.