Skip to content

Commit 182f598

Browse files
authored
Merge pull request #1154 from Trusted-AI/development_maintenance_170
General maintenance updates for ART 1.7.0
2 parents fd5a5da + 40cbe86 commit 182f598

36 files changed

+273
-66
lines changed

.gitignore

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,6 @@ ENV/
9696
*.jpg
9797
demo/pics/*
9898

99-
# ignore local config
100-
*config.ini
101-
10299
# Things TF might pull when testing
103100
*.gz
104101
*.npy

art/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@
77
from art import attacks
88
from art import defences
99
from art import estimators
10+
from art import evaluations
1011
from art import metrics
11-
from art import wrappers
12+
from art import preprocessing
1213

1314
# Semantic Version
1415
__version__ = "1.7.0-dev"

art/attacks/evasion/auto_projected_gradient_descent.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,11 @@ def generate(self, x: np.ndarray, y: Optional[np.ndarray] = None, **kwargs) -> n
382382
raise ValueError("Target labels `y` need to be provided for a targeted attack.")
383383
y = get_labels_np_array(self.estimator.predict(x, batch_size=self.batch_size)).astype(np.int32)
384384

385+
if self.estimator.nb_classes == 2 and y.shape[1] == 1:
386+
raise ValueError(
387+
"This attack has not yet been tested for binary classification with a single output classifier."
388+
)
389+
385390
x_adv = x.astype(ART_NUMPY_DTYPE)
386391

387392
for _ in trange(max(1, self.nb_random_init), desc="AutoPGD - restart", disable=not self.verbose):

art/attacks/evasion/boundary.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,11 @@ def generate(self, x: np.ndarray, y: Optional[np.ndarray] = None, **kwargs) -> n
125125
"""
126126
y = check_and_transform_label_format(y, self.estimator.nb_classes, return_one_hot=False)
127127

128+
if y is not None and self.estimator.nb_classes == 2 and y.shape[1] == 1:
129+
raise ValueError(
130+
"This attack has not yet been tested for binary classification with a single output classifier."
131+
)
132+
128133
# Get clip_min and clip_max from the classifier or infer them from data
129134
if self.estimator.clip_values is not None:
130135
clip_min, clip_max = self.estimator.clip_values

art/attacks/evasion/brendel_bethge.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2198,6 +2198,11 @@ def generate( # pylint: disable=W0221
21982198
logger.info("Using model predictions as correct labels for FGM.")
21992199
y = get_labels_np_array(self.estimator.predict(x, batch_size=self.batch_size)) # type: ignore
22002200

2201+
if self.estimator.nb_classes == 2 and y.shape[1] == 1:
2202+
raise ValueError(
2203+
"This attack has not yet been tested for binary classification with a single output classifier."
2204+
)
2205+
22012206
# Prediction from the initial adversarial examples if not None
22022207
x_adv_init = kwargs.get("x_adv_init")
22032208

art/attacks/evasion/carlini.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,11 @@ def generate(self, x: np.ndarray, y: Optional[np.ndarray] = None, **kwargs) -> n
252252
if y is None:
253253
y = get_labels_np_array(self.estimator.predict(x, batch_size=self.batch_size))
254254

255+
if self.estimator.nb_classes == 2 and y.shape[1] == 1:
256+
raise ValueError(
257+
"This attack has not yet been tested for binary classification with a single output classifier."
258+
)
259+
255260
# Compute perturbation with implicit batching
256261
nb_batches = int(np.ceil(x_adv.shape[0] / float(self.batch_size)))
257262
for batch_id in trange(nb_batches, desc="C&W L_2", disable=not self.verbose):
@@ -656,6 +661,11 @@ def generate(self, x: np.ndarray, y: Optional[np.ndarray] = None, **kwargs) -> n
656661
if y is None:
657662
y = get_labels_np_array(self.estimator.predict(x, batch_size=self.batch_size))
658663

664+
if self.estimator.nb_classes == 2 and y.shape[1] == 1:
665+
raise ValueError(
666+
"This attack has not yet been tested for binary classification with a single output classifier."
667+
)
668+
659669
# Compute perturbation with implicit batching
660670
nb_batches = int(np.ceil(x_adv.shape[0] / float(self.batch_size)))
661671
for batch_id in trange(nb_batches, desc="C&W L_inf", disable=not self.verbose):
@@ -971,6 +981,11 @@ def generate(self, x: np.ndarray, y: Optional[np.ndarray] = None, **kwargs) -> n
971981
if y is None:
972982
y = get_labels_np_array(self.estimator.predict(x, batch_size=self.batch_size))
973983

984+
if self.estimator.nb_classes == 2 and y.shape[1] == 1:
985+
raise ValueError(
986+
"This attack has not yet been tested for binary classification with a single output classifier."
987+
)
988+
974989
if self.mask is None:
975990
# No initial activation provided, use the full feature set
976991
activation = np.ones(x.shape)

art/attacks/evasion/deepfool.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,11 @@ def generate(self, x: np.ndarray, y: Optional[np.ndarray] = None, **kwargs) -> n
101101
x_adv = x.astype(ART_NUMPY_DTYPE)
102102
preds = self.estimator.predict(x, batch_size=self.batch_size)
103103

104+
if self.estimator.nb_classes == 2 and preds.shape[1] == 1:
105+
raise ValueError(
106+
"This attack has not yet been tested for binary classification with a single output classifier."
107+
)
108+
104109
if is_probability(preds[0]):
105110
logger.warning(
106111
"It seems that the attacked model is predicting probabilities. DeepFool expects logits as model output "

art/attacks/evasion/elastic_net.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,11 @@ def generate(self, x: np.ndarray, y: Optional[np.ndarray] = None, **kwargs) -> n
215215
if y is None:
216216
y = get_labels_np_array(self.estimator.predict(x, batch_size=self.batch_size))
217217

218+
if self.estimator.nb_classes == 2 and y.shape[1] == 1:
219+
raise ValueError(
220+
"This attack has not yet been tested for binary classification with a single output classifier."
221+
)
222+
218223
# Compute adversarial examples with implicit batching
219224
nb_batches = int(np.ceil(x_adv.shape[0] / float(self.batch_size)))
220225
for batch_id in trange(nb_batches, desc="EAD", disable=not self.verbose):

art/attacks/evasion/feature_adversaries/feature_adversaries_pytorch.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
| Paper link: https://arxiv.org/abs/1511.05122
2222
"""
2323
import logging
24-
from typing import TYPE_CHECKING, Optional, Union
24+
from typing import TYPE_CHECKING, Optional, Tuple, Union
2525

2626
import numpy as np
2727
from tqdm.auto import trange
@@ -68,7 +68,7 @@ def __init__(
6868
optimizer: Optional["Optimizer"] = None,
6969
optimizer_kwargs: Optional[dict] = None,
7070
lambda_: float = 0.0,
71-
layer: Union[int, str] = -1,
71+
layer: Union[int, str, Tuple[int, ...], Tuple[str, ...]] = -1,
7272
max_iter: int = 100,
7373
batch_size: int = 32,
7474
step_size: Optional[Union[int, float]] = None,
@@ -93,9 +93,9 @@ def __init__(
9393
"""
9494
super().__init__(estimator=estimator)
9595

96+
self.delta = delta
9697
self.optimizer = optimizer
9798
self._optimizer_kwargs = {} if optimizer_kwargs is None else optimizer_kwargs
98-
self.delta = delta
9999
self.lambda_ = lambda_
100100
self.layer = layer if isinstance(layer, tuple) else (layer,)
101101
self.batch_size = batch_size

art/attacks/evasion/frame_saliency.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,11 @@ def generate(self, x: np.ndarray, y: Optional[np.ndarray] = None, **kwargs) -> n
125125
else:
126126
targets = y
127127

128+
if self.estimator.nb_classes == 2 and targets.shape[1] == 1:
129+
raise ValueError(
130+
"This attack has not yet been tested for binary classification with a single output classifier."
131+
)
132+
128133
nb_samples = x.shape[0]
129134
nb_frames = x.shape[self.frame_index]
130135
x_adv = x.astype(ART_NUMPY_DTYPE)

0 commit comments

Comments
 (0)