Skip to content

Commit 73c41b5

Browse files
authored
Merge pull request #1759 from Trusted-AI/development_issue_1662
Add targeted option to AdversarialPatch and AdversarialPatchNumpy
2 parents 8ccf19e + 4056965 commit 73c41b5

File tree

2 files changed

+19
-0
lines changed

2 files changed

+19
-0
lines changed

art/attacks/evasion/adversarial_patch/adversarial_patch.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ class AdversarialPatch(EvasionAttack):
5656
"learning_rate",
5757
"max_iter",
5858
"batch_size",
59+
"targeted",
5960
"verbose",
6061
]
6162

@@ -71,6 +72,7 @@ def __init__(
7172
max_iter: int = 500,
7273
batch_size: int = 16,
7374
patch_shape: Optional[Tuple[int, int, int]] = None,
75+
targeted: bool = True,
7476
verbose: bool = True,
7577
):
7678
"""
@@ -89,6 +91,7 @@ def __init__(
8991
:param patch_shape: The shape of the adversarial patch as a tuple of shape (width, height, nb_channels).
9092
Currently only supported for `TensorFlowV2Classifier`. For classifiers of other frameworks
9193
the `patch_shape` is set to the shape of the input samples.
94+
:param targeted: Indicates whether the attack is targeted (True) or untargeted (False).
9295
:param verbose: Show progress bars.
9396
"""
9497
super().__init__(estimator=classifier)
@@ -106,6 +109,7 @@ def __init__(
106109
max_iter=max_iter,
107110
batch_size=batch_size,
108111
patch_shape=patch_shape,
112+
targeted=targeted,
109113
verbose=verbose,
110114
)
111115
elif isinstance(self.estimator, PyTorchClassifier):
@@ -121,6 +125,7 @@ def __init__(
121125
batch_size=batch_size,
122126
patch_shape=patch_shape,
123127
patch_type="circle",
128+
targeted=targeted,
124129
verbose=verbose,
125130
)
126131
else:
@@ -134,6 +139,7 @@ def __init__(
134139
learning_rate=learning_rate,
135140
max_iter=max_iter,
136141
batch_size=batch_size,
142+
targeted=targeted,
137143
verbose=verbose,
138144
)
139145
self._check_params()
@@ -241,5 +247,8 @@ def _check_params(self) -> None:
241247
if not self._attack.batch_size > 0:
242248
raise ValueError("The batch size must be greater than 0.")
243249

250+
if not isinstance(self._attack.targeted, bool):
251+
raise ValueError("The argument `targeted` has to be of type bool.")
252+
244253
if not isinstance(self._attack.verbose, bool):
245254
raise ValueError("The argument `verbose` has to be of type bool.")

art/attacks/evasion/adversarial_patch/adversarial_patch_numpy.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ def __init__(
7474
max_iter: int = 500,
7575
clip_patch: Union[list, tuple, None] = None,
7676
batch_size: int = 16,
77+
targeted: bool = True,
7778
verbose: bool = True,
7879
) -> None:
7980
"""
@@ -92,6 +93,8 @@ def __init__(
9293
:param clip_patch: The minimum and maximum values for each channel in the form
9394
[(float, float), (float, float), (float, float)].
9495
:param batch_size: The size of the training batch.
96+
:param targeted: Indicates whether the attack is targeted (True) or untargeted (False). Currently only targeted
97+
attacks are supported.
9598
:param verbose: Show progress bars.
9699
"""
97100
super().__init__(estimator=classifier)
@@ -104,6 +107,7 @@ def __init__(
104107
self.max_iter = max_iter
105108
self.batch_size = batch_size
106109
self.clip_patch = clip_patch
110+
self.targeted = targeted
107111
self.verbose = verbose
108112
self._check_params()
109113

@@ -299,6 +303,12 @@ def _check_params(self) -> None:
299303
if self.batch_size <= 0:
300304
raise ValueError("The batch size must be greater than 0.")
301305

306+
if not isinstance(self.targeted, bool) and not self.targeted:
307+
raise ValueError(
308+
"The argument `targeted` has to be of type bool. Currently AdversarialPatchNumpy only supports targeted"
309+
"attacks."
310+
)
311+
302312
if not isinstance(self.verbose, bool):
303313
raise ValueError("The argument `verbose` has to be of type bool.")
304314

0 commit comments

Comments
 (0)