Skip to content

Commit a43b6cf

Browse files
authored
Merge pull request #2120 from Trusted-AI/dev_1.14.1
Update to ART 1.14.1
2 parents dd50d9f + b35a559 commit a43b6cf

File tree

11 files changed

+709
-673
lines changed

11 files changed

+709
-673
lines changed

art/attacks/evasion/auto_projected_gradient_descent.py

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -231,28 +231,33 @@ def __init__(self, reduction="mean"):
231231
self.ce_loss = torch.nn.CrossEntropyLoss(reduction="none")
232232
self.reduction = reduction
233233

234-
def __call__(self, y_true: torch.Tensor, y_pred: torch.Tensor) -> torch.Tensor:
234+
def __call__(self, y_pred: torch.Tensor, y_true: torch.Tensor) -> torch.Tensor:
235235
if self.reduction == "mean":
236-
return self.ce_loss(y_true, y_pred).mean()
236+
return self.ce_loss(y_pred, y_true).mean()
237237
if self.reduction == "sum":
238-
return self.ce_loss(y_true, y_pred).sum()
238+
return self.ce_loss(y_pred, y_true).sum()
239239
if self.reduction == "none":
240-
return self.ce_loss(y_true, y_pred)
240+
return self.ce_loss(y_pred, y_true)
241241
raise NotImplementedError()
242242

243243
def forward(
244244
self, input: torch.Tensor, target: torch.Tensor # pylint: disable=W0622
245245
) -> torch.Tensor:
246246
"""
247247
Forward method.
248+
248249
:param input: Predicted labels of shape (nb_samples, nb_classes).
249250
:param target: Target labels of shape (nb_samples, nb_classes).
250251
:return: Difference Logits Ratio Loss.
251252
"""
252-
return self.__call__(y_true=target, y_pred=input)
253+
return self.__call__(y_pred=input, y_true=target)
253254

254255
_loss_object_pt: torch.nn.modules.loss._Loss = CrossEntropyLossTorch(reduction="mean")
255256

257+
reduce_labels = True
258+
int_labels = True
259+
probability_labels = True
260+
256261
elif loss_type == "difference_logits_ratio":
257262
if is_probability(
258263
estimator.predict(x=np.ones(shape=(1, *estimator.input_shape), dtype=ART_NUMPY_DTYPE))
@@ -316,13 +321,18 @@ def forward(
316321
) -> torch.Tensor:
317322
"""
318323
Forward method.
324+
319325
:param input: Predicted labels of shape (nb_samples, nb_classes).
320326
:param target: Target labels of shape (nb_samples, nb_classes).
321327
:return: Difference Logits Ratio Loss.
322328
"""
323329
return self.__call__(y_true=target, y_pred=input)
324330

325331
_loss_object_pt = DifferenceLogitsRatioPyTorch()
332+
333+
reduce_labels = False
334+
int_labels = False
335+
probability_labels = False
326336
else:
327337
raise NotImplementedError()
328338

@@ -340,6 +350,10 @@ def forward(
340350
device_type=str(estimator._device),
341351
)
342352

353+
estimator_apgd._reduce_labels = reduce_labels
354+
estimator_apgd._int_labels = int_labels
355+
estimator_apgd._probability_labels = probability_labels
356+
343357
else: # pragma: no cover
344358
raise ValueError(f"The loss type {loss_type} is not supported for the provided estimator.")
345359

art/attacks/poisoning/bad_det/bad_det_rma.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
from __future__ import absolute_import, division, print_function, unicode_literals
2424

2525
import logging
26-
from typing import Dict, List, Tuple
26+
from typing import Dict, List, Tuple, Optional
2727

2828
import numpy as np
2929
from tqdm.auto import tqdm
@@ -54,7 +54,7 @@ class BadDetRegionalMisclassificationAttack(PoisoningAttackObjectDetector):
5454
def __init__(
5555
self,
5656
backdoor: PoisoningAttackBackdoor,
57-
class_source: int = 0,
57+
class_source: Optional[int] = None,
5858
class_target: int = 1,
5959
percent_poison: float = 0.3,
6060
channels_first: bool = False,
@@ -64,7 +64,8 @@ def __init__(
6464
Creates a new BadDet Regional Misclassification Attack
6565
6666
:param backdoor: the backdoor chosen for this attack.
67-
:param class_source: The source class from which triggers were selected.
67+
:param class_source: The source class (optionally) from which triggers were selected. If no source is
68+
provided, then all classes will be poisoned.
6869
:param class_target: The target label to which the poisoned model needs to misclassify.
6970
:param percent_poison: The ratio of samples to poison in the source class, with range [0, 1].
7071
:param channels_first: Set channels first or last.
@@ -116,7 +117,7 @@ def poison( # pylint: disable=W0221
116117
target_dict = {k: v.copy() for k, v in y_i.items()}
117118
y_poison.append(target_dict)
118119

119-
if self.class_source in y_i["labels"]:
120+
if self.class_source is None or self.class_source in y_i["labels"]:
120121
source_indices.append(i)
121122

122123
# select indices of samples to poison
@@ -130,7 +131,7 @@ def poison( # pylint: disable=W0221
130131
labels = y_poison[i]["labels"]
131132

132133
for j, (box, label) in enumerate(zip(boxes, labels)):
133-
if label == self.class_source:
134+
if self.class_source is None or label == self.class_source:
134135
# extract the bounding box from the image
135136
x_1, y_1, x_2, y_2 = box.astype(int)
136137
bounding_box = image[y_1:y_2, x_1:x_2, :]

art/defences/trainer/ibp_certified_trainer_pytorch.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,8 @@ def __init__(
109109
classifier: "IBP_CERTIFIER_TYPE",
110110
nb_epochs: Optional[int] = 20,
111111
bound: float = 0.1,
112-
loss_weighting: float = 0.1,
113112
batch_size: int = 32,
113+
loss_weighting: Optional[int] = None,
114114
use_certification_schedule: bool = True,
115115
certification_schedule: Optional[Any] = None,
116116
use_loss_weighting_schedule: bool = True,
@@ -133,9 +133,9 @@ def __init__(
133133
* *max_iter*: The maximum number of iterations.
134134
* *batch_size*: Size of the batch on which adversarial samples are generated.
135135
* *num_random_init*: Number of random initialisations within the epsilon ball.
136+
:param loss_weighting: Weighting factor for the certified loss.
136137
:param bound: The perturbation range for the interval. If the default certification schedule is used
137138
will be the upper limit.
138-
:param loss_weighting: Weighting factor for the certified loss.
139139
:param nb_epochs: Number of training epochs.
140140
:param use_certification_schedule: If to use a training schedule for the certification radius.
141141
:param certification_schedule: Schedule for gradually increasing the certification radius. Empirical studies
@@ -152,6 +152,14 @@ def __init__(
152152
"art.estimators.certification.interval.pytorch.PyTorchIBPClassifier"
153153
)
154154

155+
if not use_loss_weighting_schedule and loss_weighting is None:
156+
raise ValueError(
157+
"If a loss weighting schedule is not used then a value for loss_weighting should be supplied."
158+
)
159+
160+
if use_loss_weighting_schedule and loss_weighting is not None:
161+
raise ValueError("Using a loss weighting schedule is incompatible with a fixed loss_weighting.")
162+
155163
super().__init__(classifier=classifier)
156164
self.classifier: "IBP_CERTIFIER_TYPE"
157165
self.pgd_params: "PGDParamDict"
@@ -300,8 +308,10 @@ def fit( # pylint: disable=W0221
300308
self.loss_weighting_schedule = self.initialise_default_scheduler(
301309
initial_val=0.0, final_val=0.5, epochs=epochs
302310
)
311+
elif self.loss_weighting is not None:
312+
loss_weighting_k = self.loss_weighting
303313
else:
304-
loss_weighting_k = 0.1
314+
raise ValueError("Unable to determine loss weighting.")
305315

306316
for _ in tqdm(range(epochs)):
307317
if self.use_certification_schedule and self.certification_schedule is not None:

0 commit comments

Comments
 (0)