From 98082234314b86838eee3631a23e9bb3303c2bef Mon Sep 17 00:00:00 2001 From: Lei Hsiung Date: Thu, 14 Sep 2023 03:13:25 +0800 Subject: [PATCH 01/26] Add CompositeAdversarialAttack Signed-off-by: Lei Hsiung --- art/attacks/evasion/__init__.py | 1 + .../evasion/composite_adversarial_attack.py | 488 ++++++++++++++++++ notebooks/composite-adversarial-attack.ipynb | 292 +++++++++++ 3 files changed, 781 insertions(+) create mode 100644 art/attacks/evasion/composite_adversarial_attack.py create mode 100644 notebooks/composite-adversarial-attack.ipynb diff --git a/art/attacks/evasion/__init__.py b/art/attacks/evasion/__init__.py index fb452f21d4..feea60f9a8 100644 --- a/art/attacks/evasion/__init__.py +++ b/art/attacks/evasion/__init__.py @@ -18,6 +18,7 @@ from art.attacks.evasion.brendel_bethge import BrendelBethgeAttack from art.attacks.evasion.boundary import BoundaryAttack +from art.attacks.evasion.composite_adversarial_attack import CompositeAdversarialAttack from art.attacks.evasion.carlini import CarliniL2Method, CarliniLInfMethod, CarliniL0Method from art.attacks.evasion.decision_tree_attack import DecisionTreeAttack from art.attacks.evasion.deepfool import DeepFool diff --git a/art/attacks/evasion/composite_adversarial_attack.py b/art/attacks/evasion/composite_adversarial_attack.py new file mode 100644 index 0000000000..8142231527 --- /dev/null +++ b/art/attacks/evasion/composite_adversarial_attack.py @@ -0,0 +1,488 @@ +# MIT License +# +# Copyright (C) The Adversarial Robustness Toolbox (ART) Authors 2020 +# +# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated +# documentation files (the "Software"), to deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit +# persons to whom the Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the +# Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +""" +This module implements the composite adversarial attack by sequentially perturbing different components of the inputs. +It uses order scheduling to search for the attack sequence and uses the iterative gradient sign method to optimize the +perturbations in semantic space and Lp-ball (see `FastGradientMethod` and `BasicIterativeMethod`). + +| Paper link: https://arxiv.org/abs/2202.04235 +""" + +from __future__ import absolute_import, division, print_function, unicode_literals + +import logging + +from typing import Optional, Tuple, TYPE_CHECKING + +import numpy as np +from tqdm.auto import tqdm + +from art.attacks.attack import EvasionAttack +from art.config import ART_NUMPY_DTYPE +from art.estimators.estimator import BaseEstimator, LossGradientsMixin +from art.estimators.classification.classifier import ClassifierMixin +from art.utils import ( + compute_success, + check_and_transform_label_format, + get_labels_np_array +) + +if TYPE_CHECKING: + # pylint: disable=C0412 + import torch + import torch.nn.functional as F + from art.estimators.classification.pytorch import PyTorchClassifier + from math import pi + +logger = logging.getLogger(__name__) + + +class CompositeAdversarialAttack(EvasionAttack): + """ + Implementation of the composite adversarial attack on image classifiers in PyTorch. The attack is constructed by adversarially + perturbing the hue component of the inputs. It uses the iterative gradient sign method to optimise the semantic + perturbations (see `FastGradientMethod` and `BasicIterativeMethod`). This implementation extends the original + optimisation method to other norms as well. + + Note that this attack is intended for only PyTorch image classifiers with RGB images in the range [0, 1] as inputs. + + | Paper link: https://arxiv.org/abs/2202.04235 + """ + + attack_params = EvasionAttack.attack_params + [ + "enabled_attack", + "hue_epsilon", + "sat_epsilon", + "rot_epsilon", + "bri_epsilon", + "con_epsilon", + "pgd_epsilon", + "early_stop", + "max_iter", + "max_inner_iter", + "schedule", + "batch_size", + "verbose", + ] + _estimator_requirements = (BaseEstimator, LossGradientsMixin, ClassifierMixin) # type: ignore + + def __init__( + self, + classifier: "PyTorchClassifier", + enabled_attack: Tuple = (0, 1, 2, 3, 4, 5), + # Default: Full Attacks; 0: Hue, 1: Saturation, 2: Rotation, 3: Brightness, 4: Contrast, 5: PGD (L-infinity) + hue_epsilon: Tuple = (-pi, pi), + sat_epsilon: Tuple = (0.7, 1.3), + rot_epsilon: Tuple = (-10, 10), + bri_epsilon: Tuple = (-0.2, 0.2), + con_epsilon: Tuple = (0.7, 1.3), + pgd_epsilon: Tuple = (-8 / 255, 8 / 255), # L-infinity + early_stop: bool = True, + max_iter: int = 5, + max_inner_iter: int = 10, + attack_order: str = "scheduled", + batch_size: int = 1, + verbose: bool = True, + ) -> None: + """ + Create an instance of the :class:`.HueGradientPyTorch`. + + :param classifier: A trained PyTorch classifier. + :param enabled_attack: The norm of the adversarial perturbation. Possible values: `"inf"`, `np.inf`, `1` or `2`. + :param hue_epsilon: The boundary of the hue perturbation. The value is expected to be in the interval + `[-pi, pi]`. Perturbation of `0` means no shift and `-pi` and `pi` give a complete reversal + of the hue channel in the HSV colour space in the positive and negative directions, + respectively. See `kornia.enhance.adjust_hue` for more details. + :param sat_epsilon: The boundary of the saturation perturbation. The value is expected to be in the interval + `[0, infinity)`. Perturbation of `0` gives a black and white image, `1` gives the original + image, while `2` enhances the saturation by a factor of 2. See + `kornia.geometry.transform.rotate` for more details. + :param rot_epsilon: The boundary of the rotation perturbation (in degrees). Positive values mean + counter-clockwise rotation. See `kornia.geometry.transform.rotate` for more details. + :param bri_epsilon: The boundary of the brightness perturbation. The value is expected to be in the interval + `[-1, 1]`. Perturbation of `0` means no shift, `-1` gives a complete black image, and `1` + gives a complete white image. See `kornia.enhance.adjust_brightness` for more details. + :param con_epsilon: The boundary of the contrast perturbation. The value is expected to be in the interval + `[0, infinity)`. Perturbation of `0` gives a complete black image, `1` does not modify the + image, and any other value modifies the brightness by this factor. See + `kornia.enhance.adjust_contrast` for more details. + :param pgd_epsilon: The maximum perturbation that the attacker can introduce in the L-infinity ball. + :param early_stop: When True, the attack will stop if the perturbed example is classified incorrectly by the + classifier. + :param max_iter: The maximum number of iterations for attack order optimization. + :param max_inner_iter: The maximum number of iterations for each attack optimization. + :param attack_order: Specify the scheduling type for composite adversarial attack. The value is expected to be + `fixed`, `random', or `scheduled`. `fixed` means the attack order is the same as specified + in `enabled_attack`. `random` means the attack order is randomly generated at each iteration. + `scheduled` means to enable the attack order optimization proposed in the paper. If only one + attack is enabled, `fixed` will be used. + :param batch_size: The batch size to use during the generation of adversarial samples. + :param verbose: Show progress bars. + """ + super().__init__(estimator=classifier) + self.classifier = classifier + self.model = classifier.model + self.device = next(self.model.parameters()).device + self.fixed_order = enabled_attack + self.enabled_attack = tuple(sorted(enabled_attack)) + self.seq_num = len(enabled_attack) # attack_num + self.early_stop = early_stop + self.linf_idx = self.enabled_attack.index(5) if 5 in self.enabled_attack else None + self.eps_pool = torch.tensor( + [hue_epsilon, sat_epsilon, rot_epsilon, bri_epsilon, con_epsilon, pgd_epsilon], device=self.device) + self.attack_order = attack_order + self.max_inner_iter = max_inner_iter + self.max_iter = max_iter if self.attack_order == 'scheduled' else 1 + self.targeted = False + self.batch_size = batch_size + self.verbose = verbose + self.attack_pool = ( + self.caa_hue, self.caa_saturation, self.caa_rotation, self.caa_brightness, self.caa_contrast, self.caa_linf) + + import kornia + self.attack_pool_base = ( + kornia.enhance.adjust_hue, kornia.enhance.adjust_saturation, kornia.geometry.transform.rotate, + kornia.enhance.adjust_brightness, kornia.enhance.adjust_contrast, self.get_linf_perturbation) + self.attack_dict = tuple([self.attack_pool[i] for i in self.enabled_attack]) + self.step_size_pool = [2.5 * ((eps[1] - eps[0]) / 2) / self.max_inner_iter for eps in + self.eps_pool] # 2.5 * ε-test / num_steps + + self._check_params() + self._description = "Composite Adversarial Attack" + self._is_scheduling = False + self.adv_val_pool = self.eps_space = self.adv_val_space = self.curr_dsm = \ + self.curr_seq = self.is_attacked = self.is_not_attacked = None + + def _check_params(self) -> None: + super()._check_params() + if self.attack_order not in ('fixed', 'random', 'scheduled'): + print("attack_order: {}, should be either 'fixed', 'random', or 'scheduled'.".format(self.attack_order)) + raise ValueError + + def _set_targets( + self, + x: np.ndarray, + y: Optional[np.ndarray], + classifier_mixin: bool = True + ) -> np.ndarray: + """ + Check and set up targets. + + :param x: An array with all the original inputs. + :param y: Target values (class labels) one-hot-encoded of shape `(nb_samples, nb_classes)` or indices of shape + `(nb_samples,)`. Only provide this parameter if you'd like to use true labels when crafting + adversarial samples. Otherwise, model predictions are used as labels to avoid the "label leaking" + effect (explained in this paper: https://arxiv.org/abs/1611.01236). Default is `None`. + :param classifier_mixin: Whether the estimator is of type `ClassifierMixin`. + :return: The targets. + """ + if classifier_mixin: + if y is not None: + y = check_and_transform_label_format(y, nb_classes=self.estimator.nb_classes) + + if y is None: + # Throw an error if the attack is targeted, but no targets are provided. + if self.targeted: # pragma: no cover + raise ValueError("Target labels `y` need to be provided for a targeted attack.") + + # Use the model predictions as correct outputs. + if classifier_mixin: + targets = get_labels_np_array(self.estimator.predict(x, batch_size=self.batch_size)) + else: + targets = self.estimator.predict(x, batch_size=self.batch_size) + + else: + targets = y + + return targets + + def _setup_attack(self): + hue_space = torch.rand(self.batch_size, device=self.device) * ( + self.eps_pool[0][1] - self.eps_pool[0][0]) + self.eps_pool[0][0] + sat_space = torch.rand(self.batch_size, device=self.device) * ( + self.eps_pool[1][1] - self.eps_pool[1][0]) + self.eps_pool[1][0] + rot_space = torch.rand(self.batch_size, device=self.device) * ( + self.eps_pool[2][1] - self.eps_pool[2][0]) + self.eps_pool[2][0] + bri_space = torch.rand(self.batch_size, device=self.device) * ( + self.eps_pool[3][1] - self.eps_pool[3][0]) + self.eps_pool[3][0] + con_space = torch.rand(self.batch_size, device=self.device) * ( + self.eps_pool[4][1] - self.eps_pool[4][0]) + self.eps_pool[4][0] + pgd_space = 0.001 * torch.randn([self.batch_size, 3, 32, 32], device=self.device) + self.adv_val_pool = [hue_space, sat_space, rot_space, bri_space, con_space, pgd_space] + + self.eps_space = [self.eps_pool[i] for i in self.enabled_attack] + self.adv_val_space = [self.adv_val_pool[i] for i in self.enabled_attack] + + def generate( + self, + x: np.ndarray, + y: Optional[np.ndarray] = None, + **kwargs + ) -> np.ndarray: + targets = self._set_targets(x, y) + dataset = torch.utils.data.TensorDataset( + torch.from_numpy(x.astype(ART_NUMPY_DTYPE)), + torch.from_numpy(y.astype(ART_NUMPY_DTYPE)), + ) + data_loader = torch.utils.data.DataLoader( + dataset=dataset, batch_size=self.batch_size, shuffle=False, drop_last=False + ) + + # Start to compute adversarial examples. + x_adv = x.copy().astype(ART_NUMPY_DTYPE) + + # Compute perturbations with batching. + for (batch_id, batch_all) in enumerate( + tqdm(data_loader, desc=self._description, leave=False, disable=not self.verbose) + ): + self._batch_id = batch_id + (batch_x, batch_targets, batch_mask) = batch_all[0], batch_all[1], None + batch_index_1, batch_index_2 = batch_id * self.batch_size, (batch_id + 1) * self.batch_size + + x_adv[batch_index_1:batch_index_2] = self._generate_batch( + x=batch_x, + y=batch_targets, + mask=batch_mask, + ) + + logger.info( + "Success rate of attack: %.2f%%", + 100 * compute_success(self.estimator, x, targets, x_adv, self.targeted, batch_size=self.batch_size), + ) + + return x_adv + + def _generate_batch( + self, + x: "torch.Tensor", + y: "torch.Tensor", + mask: "torch.Tensor" + ) -> np.ndarray: + """ + Generate a batch of adversarial samples and return them in a NumPy array. + + :param x: Original inputs. + :param y: Target values (class labels) one-hot-encoded of shape `(nb_samples, nb_classes)`. + :param mask: A 1D array of masks defining which samples to perturb. Shape needs to be `(nb_samples,)`. + Samples for which the mask is zero will not be adversarially perturbed. + :return: Adversarial examples. + """ + + self.batch_size = x.shape[0] + self._setup_attack() + self.is_attacked = torch.zeros(self.batch_size, device=self.device).bool() + self.is_not_attacked = torch.ones(self.batch_size, device=self.device).bool() + x, y = x.to(self.device), y.to(self.device) + + return self.caa_attack(x, y).cpu().detach().numpy() + + def _comp_pgd(self, data, labels, attack_idx, attack_parameter, ori_is_attacked): + adv_data = self.attack_pool_base[attack_idx](data, attack_parameter) + for _ in range(self.max_inner_iter): + outputs = self.model(adv_data) + + if not self._is_scheduling and self.early_stop: + cur_pred = outputs.max(1, keepdim=True)[1].squeeze() + self.is_attacked = torch.logical_or(ori_is_attacked, + cur_pred != labels.max(1, keepdim=True)[1].squeeze()) + + with torch.enable_grad(): + cost = F.cross_entropy(outputs, labels) + _grad = torch.autograd.grad(cost, attack_parameter)[0] + if not self._is_scheduling: + _grad[self.is_attacked] = 0 + attack_parameter = torch.clamp(attack_parameter + torch.sign(_grad) * self.step_size_pool[attack_idx], + self.eps_pool[attack_idx][0], + self.eps_pool[attack_idx][1]).detach().requires_grad_() + adv_data = self.attack_pool_base[attack_idx](data, attack_parameter) + + return adv_data, attack_parameter + + def caa_hue(self, data, hue, labels): + hue = hue.detach().clone() + hue[self.is_attacked] = 0 + hue.requires_grad_() + sur_data = data.detach().requires_grad_() + + return self._comp_pgd(data=sur_data, labels=labels, attack_idx=0, attack_parameter=hue, + ori_is_attacked=self.is_attacked.clone()) + + def caa_saturation(self, data, saturation, labels): + saturation = saturation.detach().clone() + saturation[self.is_attacked] = 1 + saturation.requires_grad_() + sur_data = data.detach().requires_grad_() + + return self._comp_pgd(data=sur_data, labels=labels, attack_idx=1, attack_parameter=saturation, + ori_is_attacked=self.is_attacked.clone()) + + def caa_rotation(self, data, theta, labels): + theta = theta.detach().clone() + theta[self.is_attacked] = 0 + theta.requires_grad_() + sur_data = data.detach().requires_grad_() + + return self._comp_pgd(data=sur_data, labels=labels, attack_idx=2, attack_parameter=theta, + ori_is_attacked=self.is_attacked.clone()) + + def caa_brightness(self, data, brightness, labels): + brightness = brightness.detach().clone() + brightness[self.is_attacked] = 0 + brightness.requires_grad_() + sur_data = data.detach().requires_grad_() + + return self._comp_pgd(data=sur_data, labels=labels, attack_idx=3, attack_parameter=brightness, + ori_is_attacked=self.is_attacked.clone()) + + def caa_contrast(self, data, contrast, labels): + contrast = contrast.detach().clone() + contrast[self.is_attacked] = 1 + contrast.requires_grad_() + sur_data = data.detach().requires_grad_() + + return self._comp_pgd(data=sur_data, labels=labels, attack_idx=4, attack_parameter=contrast, + ori_is_attacked=self.is_attacked.clone()) + + def caa_linf(self, data, labels): + sur_data = data.detach() + adv_data = data.detach().requires_grad_() + ori_is_attacked = self.is_attacked.clone() + for _ in range(self.max_inner_iter): + outputs = self.model(adv_data) + + if not self._is_scheduling and self.early_stop: + cur_pred = outputs.max(1, keepdim=True)[1].squeeze() + self.is_attacked = torch.logical_or(ori_is_attacked, + cur_pred != labels.max(1, keepdim=True)[1].squeeze()) + + with torch.enable_grad(): + cost = F.cross_entropy(outputs, labels) + _grad = torch.autograd.grad(cost, adv_data)[0] + if not self._is_scheduling: + _grad[self.is_attacked] = 0 + adv_data = adv_data + self.step_size_pool[5] * torch.sign(_grad) + eta = torch.clamp(adv_data - sur_data, min=self.eps_pool[5][0], max=self.eps_pool[5][1]) + adv_data = torch.clamp(sur_data + eta, min=0., max=1.).detach_().requires_grad_() + + return adv_data + + def get_linf_perturbation(self, data, noise): + return torch.clamp(data + noise, 0.0, 1.0) + + def update_attack_order(self, images, labels, adv_val=None): + def hungarian(matrix_batch): + sol = torch.tensor([-i for i in range(1, matrix_batch.shape[0] + 1)], dtype=torch.int32) + for i in range(matrix_batch.shape[0]): + topk = 1 + sol[i] = torch.topk(matrix_batch[i], topk)[1][topk - 1] + while sol.shape != torch.unique(sol).shape: + topk = topk + 1 + sol[i] = torch.topk(matrix_batch[i], topk)[1][topk - 1] + return sol + + def sinkhorn_normalization(ori_dsm, n_iters=20): + for _ in range(n_iters): + ori_dsm /= ori_dsm.sum(dim=0, keepdim=True) + ori_dsm /= ori_dsm.sum(dim=1, keepdim=True) + return ori_dsm + + if self.attack_order == 'fixed': + if self.curr_seq is None: + self.fixed_order = tuple([self.enabled_attack.index(i) for i in self.fixed_order]) + self.curr_seq = torch.tensor(self.fixed_order, device=self.device) + elif self.attack_order == 'random': + self.curr_seq = torch.randperm(self.seq_num) + elif self.attack_order == 'scheduled': + if self.curr_dsm is None: + self.curr_dsm = sinkhorn_normalization(torch.rand((self.seq_num, self.seq_num))) + self.curr_seq = hungarian(self.curr_dsm) + self.curr_dsm = self.curr_dsm.detach().requires_grad_() + adv_img = images.clone().detach().requires_grad_() + original_iter_num = self.max_inner_iter + self.max_inner_iter = 3 + self._is_scheduling = True + for tdx in range(self.seq_num): + prev_img = adv_img.clone() + adv_img = torch.zeros_like(adv_img) + for idx in range(self.seq_num): + if idx == self.linf_idx: + adv_img = adv_img + self.curr_dsm[tdx][idx] * self.attack_dict[idx](prev_img, labels) + else: + _adv_img, _ = self.attack_dict[idx](prev_img, adv_val[idx], labels) + adv_img = adv_img + self.curr_dsm[tdx][idx] * _adv_img + self._is_scheduling = False + self.max_inner_iter = original_iter_num + outputs = self.model(adv_img) + with torch.enable_grad(): + cost = F.cross_entropy(outputs, labels) + + dsm_grad = torch.autograd.grad(cost, self.curr_dsm)[0] + + prev_seq = self.curr_seq.clone() + dsm_noise = torch.zeros_like(self.curr_dsm) + while torch.equal(prev_seq, self.curr_seq): + self.curr_dsm = sinkhorn_normalization(torch.exp(self.curr_dsm + dsm_grad + dsm_noise).detach()) + self.curr_seq = hungarian(self.curr_dsm.detach()) + dsm_noise = (torch.randn_like(self.curr_dsm) + 1) * 2 # Escaping local optimum + else: + raise ValueError() + + def caa_attack(self, images, labels): + attack = self.attack_dict + adv_img = images.detach().clone() + adv_val_saved = torch.zeros((self.seq_num, self.batch_size), device=self.device) + adv_val = [self.adv_val_space[idx] for idx in range(self.seq_num)] + + if self.is_attacked.sum() > 0: + for att_id in range(self.seq_num): + if att_id == self.linf_idx: + continue + adv_val[att_id].detach() + adv_val[att_id][self.is_attacked] = adv_val_saved[att_id][self.is_attacked] + adv_val[att_id].requires_grad_() + + for _ in range(self.max_iter): + self.update_attack_order(images, labels, adv_val) + + adv_img = adv_img.detach().clone() + self.is_not_attacked = torch.logical_not(self.is_attacked) + adv_img[self.is_not_attacked] = images[self.is_not_attacked].clone() + adv_img.requires_grad = True + + for tdx in range(self.seq_num): + idx = self.curr_seq[tdx] + if idx == self.linf_idx: + adv_img = attack[idx](adv_img, labels) + else: + adv_img, adv_val_updated = attack[idx](adv_img, adv_val[idx], labels) + adv_val[idx] = adv_val_updated + + outputs = self.model(adv_img) + cur_pred = outputs.max(1, keepdim=True)[1].squeeze() + self.is_attacked = torch.logical_or(self.is_attacked, cur_pred != labels.max(1, keepdim=True)[1].squeeze()) + + if self.is_attacked.sum() > 0: + for att_id in range(self.seq_num): + if att_id == self.linf_idx: + continue + adv_val_saved[att_id][self.is_attacked] = adv_val[att_id][self.is_attacked].detach() + + if self.is_attacked.sum() == self.batch_size: + break + + return adv_img diff --git a/notebooks/composite-adversarial-attack.ipynb b/notebooks/composite-adversarial-attack.ipynb new file mode 100644 index 0000000000..630f8a9d13 --- /dev/null +++ b/notebooks/composite-adversarial-attack.ipynb @@ -0,0 +1,292 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "10b7328c-03a0-4ab5-a451-eee98801bd55", + "metadata": {}, + "source": [ + "# Composite Adversarial Attacks in PyTorch\n", + "This notebook provides a demonstration showing how to use ART to launch the composite adversarial attack (CAA) [1]. CAA consists of the following perturbations:\n", + "\n", + "- Hue\n", + "- Saturation\n", + "- Rotation\n", + "- Brightness\n", + "- Contrast\n", + "- PGD ($\\ell_\\infty$)\n", + "\n", + "[1] Towards Compositional Adversarial Robustness: Generalizing Adversarial Training to Composite Semantic Perturbations (CVPR 2023)" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "53cf6ef7-9572-4a30-a71e-8315844a5c3d", + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import torch.nn as nn\n", + "import torch.optim as optim\n", + "\n", + "from art.attacks.evasion import CompositeAdversarialAttack\n", + "from art.estimators.classification import PyTorchClassifier\n", + "from art.utils import load_cifar10\n", + "\n", + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "2f689043-e7c8-4e87-b49c-5ff7d11a447f", + "metadata": {}, + "outputs": [], + "source": [ + "(x_train, y_train), (x_test, y_test), min_pixel_value, max_pixel_value = load_cifar10()\n", + "\n", + "# Swap the axes to PyTorch's NCHW format.\n", + "x_train = np.transpose(x_train, (0, 3, 1, 2)).astype(np.float32)\n", + "x_test = np.transpose(x_test, (0, 3, 1, 2)).astype(np.float32)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "e5775160-2a0b-49bc-9bf6-57a9613906e1", + "metadata": {}, + "outputs": [], + "source": [ + "# Create a simple convolutional neural network.\n", + "model = nn.Sequential(\n", + " nn.Conv2d(3, 8, 5), nn.BatchNorm2d(8), nn.ReLU(), nn.MaxPool2d(2, 2), \n", + " nn.Conv2d(8, 16, 5), nn.BatchNorm2d(16), nn.ReLU(), nn.MaxPool2d(2, 2),\n", + " nn.Flatten(), \n", + " nn.Linear(5*5*16, 128), \n", + " nn.Linear(128, 10)\n", + ")\n", + "\n", + "# Define the loss function and the optimizer.\n", + "criterion = nn.CrossEntropyLoss()\n", + "optimizer = optim.Adam(model.parameters(), lr=0.01)\n", + "\n", + "# Create the ART classifier.\n", + "classifier = PyTorchClassifier(\n", + " model=model,\n", + " clip_values=(min_pixel_value, max_pixel_value),\n", + " loss=criterion,\n", + " optimizer=optimizer,\n", + " input_shape=(3, 32, 32),\n", + " nb_classes=10,\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "7cdda5a3-d7a3-4210-a47c-fd5571e3ea92", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Accuracy on the benign test set: 56.269999999999996%\n" + ] + } + ], + "source": [ + "# Train the ART classifier.\n", + "classifier.fit(x_train, y_train, batch_size=64, nb_epochs=5, verbose=True)\n", + "\n", + "# Evaluate the ART classifier on benign test examples.\n", + "predictions_benign = classifier.predict(x_test)\n", + "\n", + "accuracy = np.sum(np.argmax(predictions_benign, axis=1) == np.argmax(y_test, axis=1)) / len(y_test)\n", + "print(\"Accuracy on the benign test set: {}%\".format(accuracy * 100))" + ] + }, + { + "cell_type": "markdown", + "id": "1b45e556-d405-4620-8a0f-77628b8c5e33", + "metadata": {}, + "source": [ + "## Launch Composite Adversarial Attack\n", + "\n", + "`CompositeAdversarialAttack` has the following parameters:\n", + "- `classifier`: A trained PyTorch classifier.\n", + "- `enabled_attack`: Attack pool selection; and attack order specification for `fixed` order. For simplicity, we use the following abbreviations to specify each attack types. 0: Hue, 1: Saturation, 2: Rotation, 3: Brightness, 4: Contrast, 5: PGD($\\ell_\\infty$).\n", + "- `hue_epsilon`: The boundary of the hue perturbation. The value is expected to be in the interval `[-pi, pi]`. Perturbation of `0` means no shift and `-pi` and `pi` give a complete reversal of the hue channel in the HSV colour space in the positive and negative directions, respectively. See `kornia.enhance.adjust_hue` for more details.\n", + "- `sat_epsilon`: The boundary of the saturation perturbation. The value is expected to be in the interval `[0, infinity)`. Perturbation of `0` gives a black and white image, `1` gives the original image, while `2` enhances the saturation by a factor of 2. See `kornia.geometry.transform.rotate` for more details.\n", + "- `rot_epsilon`: The boundary of the rotation perturbation (in degrees). Positive values mean counter-clockwise rotation. See `kornia.geometry.transform.rotate` for more details.\n", + "- `bri_epsilon`: The boundary of the brightness perturbation. The value is expected to be in the interval `[-1, 1]`. Perturbation of `0` means no shift, `-1` gives a complete black image, and `1` gives a complete white image. See `kornia.enhance.adjust_brightness` for more details.\n", + "- `con_epsilon`: The boundary of the contrast perturbation. The value is expected to be in the interval `[0, infinity)`. Perturbation of `0` gives a complete black image, `1` does not modify the image, and any other value modifies the brightness by this factor. See `kornia.enhance.adjust_contrast` for more details.\n", + "- `pgd_epsilon`: The maximum perturbation that the attacker can introduce in the L-infinity ball.\n", + "- `early_stop`: When True, the attack will stop if the perturbed example is classified incorrectly by the classifier.\n", + "- `max_iter`: The maximum number of iterations for attack order optimization.\n", + "- `max_inner_iter`: The maximum number of iterations for each attack optimization.\n", + "- `attack_order`: Specify the scheduling type for the composite adversarial attack. The value is expected to be `fixed`, `random`, or `scheduled`. `fixed` means the attack order is the same as specified in `enabled_attack`. `random` means the attack order is randomly generated at each iteration. `scheduled` means to enable the attack order optimization proposed in the paper. If only one attack is enabled, `fixed` will be used.\n", + "- `batch_size`: The batch size to use during the generation of adversarial samples." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "f36c10c0-ddb6-4787-8b97-41e1f228ea62", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Composite Adversarial Attack: 0%| | 0/157 [00:00" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAh8AAAEjCAYAAACSDWOaAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/OQEPoAAAACXBIWXMAAA9hAAAPYQGoP6dpAABGiklEQVR4nO3deXSU9b0/8PfsM5nsOyELAWSRzRYBURRUBHE5YtFW23Mv2FqpBayitcZfq3Vp02qPYhVpbb1ge7T00lP01lpcUEKtQCvCRVEQMEBCyEpmkkwy+/P7g5tphpnPlyQkTybJ+3XOnCPzmWfmmWdm3n4zM5/5GDRN00BERESkE+NA7wARERENL1x8EBERka64+CAiIiJdcfFBREREuuLig4iIiHTFxQcRERHpiosPIiIi0hUXH0RERKQrLj6IiIhIV1x8DFKjRo3CsmXLIv/etm0bDAYDtm3b1me3YTAY8OMf/7jPrq8//Otf/8LFF18Mp9MJg8GAvXv3DvQuEQ2ooZwNy5YtQ3Jycp9f75NPPonRo0fDZDLhggsu6PPrp1hcfPTChg0bYDAYIie73Y5x48Zh5cqVqKurG+jd65E33ngj4RcYkkAggJtvvhmnTp3C008/jd///vcoKSnB888/jw0bNgz07sX4yU9+AoPBgMmTJw/0rlA/YTYMPm+99Rbuv/9+XHLJJVi/fj1++tOfDvQunVVrayvuv/9+lJaWwmazYeTIkbjpppvQ3t4+0LvWbeaB3oHB7NFHH0VpaSm8Xi/ef/99rFu3Dm+88QY++eQTJCUl6bovl112GTo6OmC1Wnu03RtvvIG1a9fGDZmOjg6YzYn7FDly5AiOHTuG3/zmN7j99tsj5z///PPIzs6O+utvoFVXV+OnP/0pnE7nQO8K6YDZMHi8++67MBqNePHFF3t8jAaC2+3G3LlzUV1djTvuuANjx45FQ0MD/v73v8Pn8+n+/OqtofHsGSCLFi3ChRdeCAC4/fbbkZWVhaeeegqvvfYabr311rjbeDyefvkfkNFohN1u79Pr7Ovr62v19fUAgPT09H6/rWAwiHA43Otwuu+++3DRRRchFAqhsbGxj/eOEg2zYfCor6+Hw+Hos4WHpmnwer1wOBx9cn1nKisrw7Fjx/DRRx+htLQ0cv4PfvCDfrm9/sKPXfrQFVdcAQCorKwE8O/PJ48cOYJrrrkGKSkp+MY3vgEACIfDWLNmDSZNmgS73Y68vDwsX74czc3NUdepaRoef/xxFBYWIikpCZdffjn2798fc9vS57q7du3CNddcg4yMDDidTkydOhXPPPNMZP/Wrl0LAFFvFXeK97nunj17sGjRIqSmpiI5ORlXXnkldu7cGXWZzree//GPf2D16tXIycmB0+nEjTfeiIaGhrMex3379mHZsmUYPXo07HY78vPz8c1vfhNNTU2Ryyxbtgxz584FANx8880wGAyYN28eRo0ahf3796OioiJyf+bNmxfZzuVy4e6770ZRURFsNhvGjh2Ln//85wiHw5HLHD16FAaDAb/4xS+wZs0ajBkzBjabDZ9++ikA4MCBAzh+/PhZ70en7du3409/+hPWrFnT7W1oaGE2nHau2dDpiy++wMKFC+F0OlFQUIBHH30UZw5o785xNBgMWL9+PTweT+Q+dn5kGwwG8dhjj0Ve/6NGjcKDDz4In88XdTujRo3CddddhzfffBMXXnghHA4Hfv3rXwPoXt4AwMmTJ3HgwAEEAgHl/Xa5XFi/fj3uuOMOlJaWwu/3x+zPYMF3PvrQkSNHAABZWVmR84LBIBYuXIg5c+bgF7/4ReQtseXLl2PDhg247bbbcNddd6GyshLPPfcc9uzZg3/84x+wWCwAgIceegiPP/44rrnmGlxzzTX46KOPsGDBAvj9/rPuz9tvv43rrrsOI0aMwPe+9z3k5+fjs88+w+uvv47vfe97WL58OWpqavD222/j97///Vmvb//+/bj00kuRmpqK+++/HxaLBb/+9a8xb948VFRUYNasWVGXX7VqFTIyMvDwww/j6NGjWLNmDVauXIk//vGPZ93vL774Arfddhvy8/Oxf/9+vPDCC9i/fz927twJg8GA5cuXY+TIkfjpT3+Ku+66CzNmzEBeXh48Hg9WrVqF5ORk/L//9/8AAHl5eQCA9vZ2zJ07FydOnMDy5ctRXFyMDz74AGVlZTh58mTM4mD9+vXwer244447YLPZkJmZCQCYOHEi5s6d260v8IVCIaxatQq33347pkyZctbL09DEbOibbABOv6auvvpqXHTRRXjiiSewZcsWPPzwwwgGg3j00Ucjl+vOcfz973+PF154Af/85z/x29/+FgBw8cUXAzj9jtVLL72Em266Cffeey927dqF8vJyfPbZZ9i8eXPUPh08eBC33norli9fjm9/+9sYP358j/KmrKwML730EiorKzFq1Cjxvr///vvwer0YO3YsbrrpJrz66qsIh8OYPXs21q5dO7i+LKtRj61fv14DoL3zzjtaQ0ODVlVVpW3cuFHLysrSHA6HVl1drWmapi1dulQDoD3wwANR2//973/XAGgvv/xy1PlbtmyJOr++vl6zWq3atddeq4XD4cjlHnzwQQ2AtnTp0sh57733ngZAe++99zRN07RgMKiVlpZqJSUlWnNzc9TtdL2uFStWaNLTAID28MMPR/69ePFizWq1akeOHImcV1NTo6WkpGiXXXZZzPGZP39+1G3dc889mslk0lwuV9zb69Te3h5z3h/+8AcNgLZ9+/aY+7xp06aoy06aNEmbO3duzHU89thjmtPp1D7//POo8x944AHNZDJpx48f1zRN0yorKzUAWmpqqlZfXx9zPQDiXn88zz33nJaWlha5nrlz52qTJk3q1rY0+DAb+jcbOo/bqlWrovb52muv1axWq9bQ0KBpWvePY+d1Op3OqMvt3btXA6DdfvvtUeffd999GgDt3XffjZxXUlKiAdC2bNkSddnu5k3X+1VZWam8/0899ZQGQMvKytJmzpypvfzyy9rzzz+v5eXlaRkZGVpNTY1y+0TCj13Owfz585GTk4OioiLccsstSE5OxubNmzFy5Mioy915551R/960aRPS0tJw1VVXobGxMXKaPn06kpOT8d577wEA3nnnHfj9fqxatSrqLc+77777rPu2Z88eVFZW4u677475TkTX6+quUCiEt956C4sXL8bo0aMj548YMQJf//rX8f7776OlpSVqmzvuuCPqti699FKEQiEcO3ZMeVtdPyv1er1obGzERRddBAD46KOPerzvnTZt2oRLL70UGRkZUcd9/vz5CIVC2L59e9TllyxZgpycnJjr0TStW+96NDU14aGHHsKPfvSjuNdDQxezoX+yodPKlSuj9nnlypXw+/145513AHT/OEreeOMNAMDq1aujzr/33nsBAH/961+jzi8tLcXChQujzutJ3mzYsAGapinf9QCAtra2yH3eunUrvv71r+POO+/Eq6++iubm5shHZYMBP3Y5B2vXrsW4ceNgNpuRl5eH8ePHw2iMXs+ZzWYUFhZGnXfo0CG43W7k5ubGvd7OL1J2vhDPO++8qHpOTg4yMjKU+9b5Nm9ftXU2NDSgvb0d48ePj6lNnDgR4XAYVVVVmDRpUuT84uLiqMt17vOZn12f6dSpU3jkkUewcePGyLHo5Ha7e3sXcOjQIezbt09cCJx5W12/zNUbP/zhD5GZmYlVq1ad0/XQ4MNsOK2vswE4/QXaroscABg3bhyA09/XArp/HCXHjh2D0WjE2LFjo87Pz89Henp6zCIpXlb0NG+6o/MPs+uvvz7q904uuugilJaW4oMPPujxdQ4ULj7OwcyZMyPfaJfYbLaY0AmHw8jNzcXLL78cd5uh8leyyWSKe752xhfDzvTVr34VH3zwAb7//e/jggsuQHJyMsLhMK6++uqYL2r1RDgcxlVXXYX7778/br0zwDqdy7fVDx06hBdeeAFr1qxBTU1N5Hyv14tAIICjR48iNTU18j0SGlqYDWq9zYbu6qvj2N13guJlRU/zpjsKCgoA/Pt7bF3l5uZ2a/GWKLj4GABjxozBO++8g0suuUT5P7iSkhIAp/9H1nWl39DQcNYn2ZgxYwAAn3zyCebPny9errsvrpycHCQlJeHgwYMxtQMHDsBoNKKoqKhb16XS3NyMrVu34pFHHsFDDz0UOf/QoUPdvg7pPo0ZMwZtbW3K49FXTpw4gXA4jLvuugt33XVXTL20tBTf+9732AFDUZgNZxcOh/HFF19E/c/7888/B4DIxxbdPY6SkpIShMNhHDp0CBMnToycX1dXB5fLFTn+Kv2RN9OnTwdwOl/OVFNTgwkTJvTZbfU3fudjAHz1q19FKBTCY489FlMLBoNwuVwATn9ubLFY8Oyzz0b9RdCd/2F9+ctfRmlpKdasWRO5vk5dr6vzdwXOvMyZTCYTFixYgNdeey3y1iZw+sX4yiuvYM6cOUhNTT3rfp1N519EZ/4F1JP/STudzrj356tf/Sp27NiBN998M6bmcrkQDAa7df3dabWdPHkyNm/eHHOaNGkSiouLsXnzZnzrW9/q1u3R8MFs6J7nnnsuap+fe+45WCwWXHnllQC6fxwl11xzDYDY4/nUU08BAK699tqz7mNP8qa7rbbjx4/HtGnT8Nprr0X9XtBbb72FqqoqXHXVVWfdr0TBdz4GwNy5c7F8+XKUl5dj7969WLBgASwWCw4dOoRNmzbhmWeewU033YScnBzcd999KC8vx3XXXYdrrrkGe/bswd/+9jdkZ2crb8NoNGLdunW4/vrrccEFF+C2227DiBEjcODAAezfvz/yguhcSd91111YuHAhTCYTbrnllrjX+fjjj+Ptt9/GnDlz8N3vfhdmsxm//vWv4fP58MQTT/TJsUlNTcVll12GJ554AoFAACNHjsRbb70V+X2E7pg+fTrWrVuHxx9/HGPHjkVubi6uuOIKfP/738f//M//4LrrrsOyZcswffp0eDwefPzxx/jTn/6Eo0ePnvW4At1rtc3OzsbixYtjzu8Ms3g1ImbD2dntdmzZsgVLly7FrFmz8Le//Q1//etf8eCDD0Y+TunucZRMmzYNS5cuxQsvvACXy4W5c+fin//8J1566SUsXrwYl19++Vn3syd5091WWwB4+umncdVVV2HOnDlYvnw53G43nnrqKYwbNy7mC8wJbaDabAazznaxf/3rX8rLxWvh6uqFF17Qpk+frjkcDi0lJUWbMmWKdv/990e1S4VCIe2RRx7RRowYoTkcDm3evHnaJ598opWUlCjb6Tq9//772lVXXaWlpKRoTqdTmzp1qvbss89G6sFgUFu1apWWk5OjGQyGqNY6nNFOp2ma9tFHH2kLFy7UkpOTtaSkJO3yyy/XPvjgg24dH2kfz1RdXa3deOONWnp6upaWlqbdfPPNWk1NTcz+SK22tbW12rXXXqulpKTEtMW2trZqZWVl2tixYzWr1aplZ2drF198sfaLX/xC8/v9mqb9u9X2ySefjLt/Z15nT7DVdmhjNvRvNnQetyNHjmgLFizQkpKStLy8PO3hhx/WQqFQr46j9FgEAgHtkUce0UpLSzWLxaIVFRVpZWVlmtfrjbpcSUmJdu2118bd3+7kTec+oButtp3efvtt7aKLLtLsdruWmZmp/cd//Id28uTJbm2bKAya1kff8CEiIiLqBn7ng4iIiHTFxQcRERHpiosPIiIi0hUXH0RERKQrLj6IiIhIV1x8EBERka767UfG1q5diyeffBK1tbWYNm0ann32WcycOfOs24XDYdTU1CAlJaVXExaJ6NxpmobW1lYUFBTEzB/pT73NDYDZQTTQepQb/fHjIRs3btSsVqv2X//1X9r+/fu1b3/721p6erpWV1d31m2rqqo0ADzxxFMCnKqqqvojIuI6l9zQNGYHTzwlyqk7udEvPzI2a9YszJgxI/L7++FwGEVFRVi1ahUeeOAB5bZutxvp6elY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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "visualise(x_test, x_test_adv, predictions_benign, predictions_adv, y_test)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f988fc1d-b74d-4968-a033-ea729bea788c", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.18" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 5d821702428d0594262467bc7d3042678c9e5366 Mon Sep 17 00:00:00 2001 From: Lei Hsiung Date: Thu, 14 Sep 2023 11:19:43 -0400 Subject: [PATCH 02/26] Apply suggestions from code review Co-authored-by: Beat Buesser <49047826+beat-buesser@users.noreply.github.com> Signed-off-by: Lei Hsiung --- .../evasion/composite_adversarial_attack.py | 26 ++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/art/attacks/evasion/composite_adversarial_attack.py b/art/attacks/evasion/composite_adversarial_attack.py index 8142231527..8490e1d7a5 100644 --- a/art/attacks/evasion/composite_adversarial_attack.py +++ b/art/attacks/evasion/composite_adversarial_attack.py @@ -1,6 +1,6 @@ # MIT License # -# Copyright (C) The Adversarial Robustness Toolbox (ART) Authors 2020 +# Copyright (C) The Adversarial Robustness Toolbox (ART) Authors 2023 # # Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated # documentation files (the "Software"), to deal in the Software without restriction, including without limitation the @@ -52,7 +52,7 @@ logger = logging.getLogger(__name__) -class CompositeAdversarialAttack(EvasionAttack): +class CompositeAdversarialAttackPyTorch(EvasionAttack): """ Implementation of the composite adversarial attack on image classifiers in PyTorch. The attack is constructed by adversarially perturbing the hue component of the inputs. It uses the iterative gradient sign method to optimise the semantic @@ -100,7 +100,7 @@ def __init__( verbose: bool = True, ) -> None: """ - Create an instance of the :class:`.HueGradientPyTorch`. + Create an instance of the :class:`.CompositeAdversarialAttackPyTorch`. :param classifier: A trained PyTorch classifier. :param enabled_attack: The norm of the adversarial perturbation. Possible values: `"inf"`, `np.inf`, `1` or `2`. @@ -134,6 +134,8 @@ def __init__( :param batch_size: The batch size to use during the generation of adversarial samples. :param verbose: Show progress bars. """ + import torch + super().__init__(estimator=classifier) self.classifier = classifier self.model = classifier.model @@ -171,7 +173,7 @@ def __init__( def _check_params(self) -> None: super()._check_params() if self.attack_order not in ('fixed', 'random', 'scheduled'): - print("attack_order: {}, should be either 'fixed', 'random', or 'scheduled'.".format(self.attack_order)) + logger.info("attack_order: {}, should be either 'fixed', 'random', or 'scheduled'.".format(self.attack_order)) raise ValueError def _set_targets( @@ -212,6 +214,8 @@ def _set_targets( return targets def _setup_attack(self): + import torch + hue_space = torch.rand(self.batch_size, device=self.device) * ( self.eps_pool[0][1] - self.eps_pool[0][0]) + self.eps_pool[0][0] sat_space = torch.rand(self.batch_size, device=self.device) * ( @@ -234,6 +238,8 @@ def generate( y: Optional[np.ndarray] = None, **kwargs ) -> np.ndarray: + import torch + targets = self._set_targets(x, y) dataset = torch.utils.data.TensorDataset( torch.from_numpy(x.astype(ART_NUMPY_DTYPE)), @@ -282,6 +288,8 @@ def _generate_batch( Samples for which the mask is zero will not be adversarially perturbed. :return: Adversarial examples. """ + import torch + self.batch_size = x.shape[0] self._setup_attack() @@ -292,6 +300,8 @@ def _generate_batch( return self.caa_attack(x, y).cpu().detach().numpy() def _comp_pgd(self, data, labels, attack_idx, attack_parameter, ori_is_attacked): + import torch + adv_data = self.attack_pool_base[attack_idx](data, attack_parameter) for _ in range(self.max_inner_iter): outputs = self.model(adv_data) @@ -359,6 +369,8 @@ def caa_contrast(self, data, contrast, labels): ori_is_attacked=self.is_attacked.clone()) def caa_linf(self, data, labels): + import torch + sur_data = data.detach() adv_data = data.detach().requires_grad_() ori_is_attacked = self.is_attacked.clone() @@ -382,9 +394,13 @@ def caa_linf(self, data, labels): return adv_data def get_linf_perturbation(self, data, noise): + import torch + return torch.clamp(data + noise, 0.0, 1.0) def update_attack_order(self, images, labels, adv_val=None): + import torch + def hungarian(matrix_batch): sol = torch.tensor([-i for i in range(1, matrix_batch.shape[0] + 1)], dtype=torch.int32) for i in range(matrix_batch.shape[0]): @@ -443,6 +459,8 @@ def sinkhorn_normalization(ori_dsm, n_iters=20): raise ValueError() def caa_attack(self, images, labels): + import torch + attack = self.attack_dict adv_img = images.detach().clone() adv_val_saved = torch.zeros((self.seq_num, self.batch_size), device=self.device) From 3a7e69e7f16bdb8bb18a23204e496067e96381e5 Mon Sep 17 00:00:00 2001 From: Lei Hsiung Date: Fri, 15 Sep 2023 03:45:11 +0800 Subject: [PATCH 03/26] Address code review comments Signed-off-by: Lei Hsiung --- art/attacks/evasion/__init__.py | 2 +- .../evasion/composite_adversarial_attack.py | 190 +++++++++++++----- notebooks/README.md | 5 + notebooks/composite-adversarial-attack.ipynb | 45 ++--- 4 files changed, 169 insertions(+), 73 deletions(-) diff --git a/art/attacks/evasion/__init__.py b/art/attacks/evasion/__init__.py index feea60f9a8..3882b839c1 100644 --- a/art/attacks/evasion/__init__.py +++ b/art/attacks/evasion/__init__.py @@ -18,7 +18,7 @@ from art.attacks.evasion.brendel_bethge import BrendelBethgeAttack from art.attacks.evasion.boundary import BoundaryAttack -from art.attacks.evasion.composite_adversarial_attack import CompositeAdversarialAttack +from art.attacks.evasion.composite_adversarial_attack import CompositeAdversarialAttackPyTorch from art.attacks.evasion.carlini import CarliniL2Method, CarliniLInfMethod, CarliniL0Method from art.attacks.evasion.decision_tree_attack import DecisionTreeAttack from art.attacks.evasion.deepfool import DeepFool diff --git a/art/attacks/evasion/composite_adversarial_attack.py b/art/attacks/evasion/composite_adversarial_attack.py index 8490e1d7a5..7a1e8280d3 100644 --- a/art/attacks/evasion/composite_adversarial_attack.py +++ b/art/attacks/evasion/composite_adversarial_attack.py @@ -27,7 +27,7 @@ import logging -from typing import Optional, Tuple, TYPE_CHECKING +from typing import Optional, Tuple, List, TYPE_CHECKING import numpy as np from tqdm.auto import tqdm @@ -45,19 +45,17 @@ if TYPE_CHECKING: # pylint: disable=C0412 import torch - import torch.nn.functional as F from art.estimators.classification.pytorch import PyTorchClassifier - from math import pi logger = logging.getLogger(__name__) class CompositeAdversarialAttackPyTorch(EvasionAttack): """ - Implementation of the composite adversarial attack on image classifiers in PyTorch. The attack is constructed by adversarially - perturbing the hue component of the inputs. It uses the iterative gradient sign method to optimise the semantic - perturbations (see `FastGradientMethod` and `BasicIterativeMethod`). This implementation extends the original - optimisation method to other norms as well. + Implementation of the composite adversarial attack on image classifiers in PyTorch. The attack is constructed by + adversarially perturbing the hue component of the inputs. It uses order scheduling to search for the attack sequence + and uses the iterative gradient sign method to optimize the perturbations in semantic space and Lp-ball (see + `FastGradientMethod` and `BasicIterativeMethod`). Note that this attack is intended for only PyTorch image classifiers with RGB images in the range [0, 1] as inputs. @@ -86,12 +84,12 @@ def __init__( classifier: "PyTorchClassifier", enabled_attack: Tuple = (0, 1, 2, 3, 4, 5), # Default: Full Attacks; 0: Hue, 1: Saturation, 2: Rotation, 3: Brightness, 4: Contrast, 5: PGD (L-infinity) - hue_epsilon: Tuple = (-pi, pi), - sat_epsilon: Tuple = (0.7, 1.3), - rot_epsilon: Tuple = (-10, 10), - bri_epsilon: Tuple = (-0.2, 0.2), - con_epsilon: Tuple = (0.7, 1.3), - pgd_epsilon: Tuple = (-8 / 255, 8 / 255), # L-infinity + hue_epsilon: List = [-np.pi, np.pi], + sat_epsilon: List = [0.7, 1.3], + rot_epsilon: List = [-10, 10], + bri_epsilon: List = [-0.2, 0.2], + con_epsilon: List = [0.7, 1.3], + pgd_epsilon: List = [-8 / 255, 8 / 255], # L-infinity early_stop: bool = True, max_iter: int = 5, max_inner_iter: int = 10, @@ -103,11 +101,15 @@ def __init__( Create an instance of the :class:`.CompositeAdversarialAttackPyTorch`. :param classifier: A trained PyTorch classifier. - :param enabled_attack: The norm of the adversarial perturbation. Possible values: `"inf"`, `np.inf`, `1` or `2`. + :param enabled_attack: Attack pool selection, and attack order designation for fixed order. For simplicity, + we use the following abbreviations to specify each attack types. 0: Hue, 1: Saturation, + 2: Rotation, 3: Brightness, 4: Contrast, 5: PGD(L-infinity). Therefore, `(0,1,2)` means + that the attack combines hue, saturation, and rotation; `(0,1,2,3,4)` means the + semantic attacks; `(0,1,2,3,4,5)` means the full attacks. :param hue_epsilon: The boundary of the hue perturbation. The value is expected to be in the interval - `[-pi, pi]`. Perturbation of `0` means no shift and `-pi` and `pi` give a complete reversal - of the hue channel in the HSV colour space in the positive and negative directions, - respectively. See `kornia.enhance.adjust_hue` for more details. + `[-np.pi, np.pi]`. Perturbation of `0` means no shift and `-np.pi` and `np.pi` give a + complete reversal of the hue channel in the HSV colour space in the positive and negative + directions, respectively. See `kornia.enhance.adjust_hue` for more details. :param sat_epsilon: The boundary of the saturation perturbation. The value is expected to be in the interval `[0, infinity)`. Perturbation of `0` gives a black and white image, `1` gives the original image, while `2` enhances the saturation by a factor of 2. See @@ -142,21 +144,22 @@ def __init__( self.device = next(self.model.parameters()).device self.fixed_order = enabled_attack self.enabled_attack = tuple(sorted(enabled_attack)) - self.seq_num = len(enabled_attack) # attack_num + self.epsilons = [hue_epsilon, sat_epsilon, rot_epsilon, bri_epsilon, con_epsilon, pgd_epsilon] self.early_stop = early_stop - self.linf_idx = self.enabled_attack.index(5) if 5 in self.enabled_attack else None - self.eps_pool = torch.tensor( - [hue_epsilon, sat_epsilon, rot_epsilon, bri_epsilon, con_epsilon, pgd_epsilon], device=self.device) self.attack_order = attack_order - self.max_inner_iter = max_inner_iter self.max_iter = max_iter if self.attack_order == 'scheduled' else 1 + self.max_inner_iter = max_inner_iter self.targeted = False self.batch_size = batch_size self.verbose = verbose - self.attack_pool = ( - self.caa_hue, self.caa_saturation, self.caa_rotation, self.caa_brightness, self.caa_contrast, self.caa_linf) + self._check_params() import kornia + self.seq_num = len(self.enabled_attack) # attack_num + self.linf_idx = self.enabled_attack.index(5) if 5 in self.enabled_attack else None + self.attack_pool = ( + self.caa_hue, self.caa_saturation, self.caa_rotation, self.caa_brightness, self.caa_contrast, self.caa_linf) + self.eps_pool = torch.tensor(self.epsilons, device=self.device) self.attack_pool_base = ( kornia.enhance.adjust_hue, kornia.enhance.adjust_saturation, kornia.geometry.transform.rotate, kornia.enhance.adjust_brightness, kornia.enhance.adjust_contrast, self.get_linf_perturbation) @@ -164,7 +167,6 @@ def __init__( self.step_size_pool = [2.5 * ((eps[1] - eps[0]) / 2) / self.max_inner_iter for eps in self.eps_pool] # 2.5 * ε-test / num_steps - self._check_params() self._description = "Composite Adversarial Attack" self._is_scheduling = False self.adv_val_pool = self.eps_space = self.adv_val_space = self.curr_dsm = \ @@ -172,9 +174,56 @@ def __init__( def _check_params(self) -> None: super()._check_params() + if not isinstance(self.enabled_attack, tuple) or not all( + value in [0, 1, 2, 3, 4, 5] for value in self.enabled_attack): + raise ValueError( + "The parameter `enabled_attack` must be a tuple specifying the attack to launch. For simplicity, we use" + + " the following abbreviations to specify each attack types. 0: Hue, 1: Saturation, 2: Rotation, 3: Br" + + "ightness, 4: Contrast, 5: PGD(L-infinity). Therefore, `(0,1,2)` means that the attack combines hue, " + + "saturation, and rotation; `(0,1,2,3,4)` means the all semantic attacks; `(0,1,2,3,4,5)` means the fu" + + "ll attacks.") + _epsilons_range = [["hue_epsilon", [-np.pi, np.pi], "[-np.pi, np.pi]"], + ["sat_epsilon", [0, np.inf], "[0, np.inf]"], ["rot_epsilon", [-360, 360], "[-360, 360]"], + ["bri_epsilon", [-1, 1], "[-1, 1]"], ["con_epsilon", [0, np.inf], "[0, np.inf]"], + ["pgd_epsilon", [-1, 1], "[-1, 1]"]] + for i in range(6): + if (not isinstance(self.epsilons[i], list) or + not len(self.epsilons[i]) == 2 or + not _epsilons_range[i][1][0] <= self.epsilons[i][0] <= self.epsilons[i][1] <= _epsilons_range[i][1][1]): + logger.info( + "The argument `" + _epsilons_range[i][0] + "` must be an interval within " + _epsilons_range[i][2] + + " of type list.") + raise ValueError( + "The argument `" + _epsilons_range[i][0] + "` must be an interval within " + _epsilons_range[i][2] + + " of type list.") + + if not isinstance(self.early_stop, bool): + logger.info("The flag `early_stop` has to be of type bool.") + raise ValueError("The flag `early_stop` has to be of type bool.") + + if not isinstance(self.targeted, bool): + logger.info("The flag `targeted` has to be of type bool.") + raise ValueError("The flag `targeted` has to be of type bool.") + + if not isinstance(self.max_iter, int) or self.max_iter <= 0: + logger.info("The argument `max_iter` must be positive of type int.") + raise ValueError("The argument `max_iter` must be positive of type int.") + + if not isinstance(self.max_inner_iter, int): + logger.info("The argument `max_inner_iter` must be positive of type int.") + raise TypeError("The argument `max_inner_iter` must be positive of type int.") + if self.attack_order not in ('fixed', 'random', 'scheduled'): - logger.info("attack_order: {}, should be either 'fixed', 'random', or 'scheduled'.".format(self.attack_order)) - raise ValueError + logger.info("The argument `attack_order` should be either `fixed`, `random`, or `scheduled`.") + raise ValueError("The argument `attack_order` should be either `fixed`, `random`, or `scheduled`.") + + if self.batch_size <= 0: + logger.info("The batch size has to be positive.") + raise ValueError("The batch size has to be positive.") + + if not isinstance(self.verbose, bool): + logger.info("The argument `verbose` has to be a Boolean.") + raise ValueError("The argument `verbose` has to be a Boolean.") def _set_targets( self, @@ -214,7 +263,7 @@ def _set_targets( return targets def _setup_attack(self): - import torch + import torch hue_space = torch.rand(self.batch_size, device=self.device) * ( self.eps_pool[0][1] - self.eps_pool[0][0]) + self.eps_pool[0][0] @@ -238,7 +287,7 @@ def generate( y: Optional[np.ndarray] = None, **kwargs ) -> np.ndarray: - import torch + import torch targets = self._set_targets(x, y) dataset = torch.utils.data.TensorDataset( @@ -298,9 +347,16 @@ def _generate_batch( x, y = x.to(self.device), y.to(self.device) return self.caa_attack(x, y).cpu().detach().numpy() - - def _comp_pgd(self, data, labels, attack_idx, attack_parameter, ori_is_attacked): - import torch + def _comp_pgd( + self, + data: "torch.Tensor", + labels: "torch.Tensor", + attack_idx: "torch.Tensor", + attack_parameter: "torch.Tensor", + ori_is_attacked: "torch.Tensor" + ) -> Tuple["torch.Tensor", "torch.Tensor"]: + import torch + import torch.nn.functional as F adv_data = self.attack_pool_base[attack_idx](data, attack_parameter) for _ in range(self.max_inner_iter): @@ -323,7 +379,12 @@ def _comp_pgd(self, data, labels, attack_idx, attack_parameter, ori_is_attacked) return adv_data, attack_parameter - def caa_hue(self, data, hue, labels): + def caa_hue( + self, + data: "torch.Tensor", + hue: "torch.Tensor", + labels: "torch.Tensor" + ) -> Tuple["torch.Tensor", "torch.Tensor"]: hue = hue.detach().clone() hue[self.is_attacked] = 0 hue.requires_grad_() @@ -332,7 +393,12 @@ def caa_hue(self, data, hue, labels): return self._comp_pgd(data=sur_data, labels=labels, attack_idx=0, attack_parameter=hue, ori_is_attacked=self.is_attacked.clone()) - def caa_saturation(self, data, saturation, labels): + def caa_saturation( + self, + data: "torch.Tensor", + saturation: "torch.Tensor", + labels: "torch.Tensor" + ) -> Tuple["torch.Tensor", "torch.Tensor"]: saturation = saturation.detach().clone() saturation[self.is_attacked] = 1 saturation.requires_grad_() @@ -341,7 +407,12 @@ def caa_saturation(self, data, saturation, labels): return self._comp_pgd(data=sur_data, labels=labels, attack_idx=1, attack_parameter=saturation, ori_is_attacked=self.is_attacked.clone()) - def caa_rotation(self, data, theta, labels): + def caa_rotation( + self, + data: "torch.Tensor", + theta: "torch.Tensor", + labels: "torch.Tensor" + ) -> Tuple["torch.Tensor", "torch.Tensor"]: theta = theta.detach().clone() theta[self.is_attacked] = 0 theta.requires_grad_() @@ -350,7 +421,12 @@ def caa_rotation(self, data, theta, labels): return self._comp_pgd(data=sur_data, labels=labels, attack_idx=2, attack_parameter=theta, ori_is_attacked=self.is_attacked.clone()) - def caa_brightness(self, data, brightness, labels): + def caa_brightness( + self, + data: "torch.Tensor", + brightness: "torch.Tensor", + labels: "torch.Tensor" + ) -> Tuple["torch.Tensor", "torch.Tensor"]: brightness = brightness.detach().clone() brightness[self.is_attacked] = 0 brightness.requires_grad_() @@ -359,7 +435,12 @@ def caa_brightness(self, data, brightness, labels): return self._comp_pgd(data=sur_data, labels=labels, attack_idx=3, attack_parameter=brightness, ori_is_attacked=self.is_attacked.clone()) - def caa_contrast(self, data, contrast, labels): + def caa_contrast( + self, + data: "torch.Tensor", + contrast: "torch.Tensor", + labels: "torch.Tensor" + ) -> Tuple["torch.Tensor", "torch.Tensor"]: contrast = contrast.detach().clone() contrast[self.is_attacked] = 1 contrast.requires_grad_() @@ -368,8 +449,13 @@ def caa_contrast(self, data, contrast, labels): return self._comp_pgd(data=sur_data, labels=labels, attack_idx=4, attack_parameter=contrast, ori_is_attacked=self.is_attacked.clone()) - def caa_linf(self, data, labels): - import torch + def caa_linf( + self, + data: "torch.Tensor", + labels: "torch.Tensor" + ) -> "torch.Tensor": + import torch + import torch.nn.functional as F sur_data = data.detach() adv_data = data.detach().requires_grad_() @@ -393,13 +479,23 @@ def caa_linf(self, data, labels): return adv_data - def get_linf_perturbation(self, data, noise): - import torch + def get_linf_perturbation( + self, + data: "torch.Tensor", + noise: "torch.Tensor" + ) -> "torch.Tensor": + import torch return torch.clamp(data + noise, 0.0, 1.0) - def update_attack_order(self, images, labels, adv_val=None): - import torch + def update_attack_order( + self, + images: "torch.Tensor", + labels: "torch.Tensor", + adv_val: Optional["torch.Tensor"] = None + ) -> None: + import torch + import torch.nn.functional as F def hungarian(matrix_batch): sol = torch.tensor([-i for i in range(1, matrix_batch.shape[0] + 1)], dtype=torch.int32) @@ -458,8 +554,12 @@ def sinkhorn_normalization(ori_dsm, n_iters=20): else: raise ValueError() - def caa_attack(self, images, labels): - import torch + def caa_attack( + self, + images: "torch.Tensor", + labels: "torch.Tensor" + ) -> "torch.Tensor": + import torch attack = self.attack_dict adv_img = images.detach().clone() diff --git a/notebooks/README.md b/notebooks/README.md index 7ab184e397..a60eace076 100644 --- a/notebooks/README.md +++ b/notebooks/README.md @@ -108,6 +108,11 @@ demonstrates a MembershipInferenceBlackBox membership inference attack using sha [label_only_membership_inference.ipynb](label_only_membership_inference.ipynb) [[on nbviewer](https://nbviewer.org/github/Trusted-AI/adversarial-robustness-toolbox/blob/main/notebooks/label_only_membership_inference.ipynb)] demonstrates a LabelOnlyDecisionBoundary membership inference attack on a PyTorch classifier for the MNIST dataset. +[composite-adversarial-attack.ipynb](composite-adversarial-attack.ipynb)[[on nbviewer](https://nbviewer.org/github/Trusted-AI/adversarial-robustness-toolbox/blob/main/notebooks/composite-adversarial-attack.ipynb)] +shows how to launch Composite Adversarial Attack (CAA) on Pytorch-based model ([Hsiung et al., 2023](https://arxiv.org/abs/2202.04235)). +CAA composites the perturbations in Lp-ball and semantic space (i.e., hue, saturation, rotation, brightness, and contrast), +and is able to optimize the attack sequence and each attack component, thereby enhancing the efficiency and efficacy of adversarial examples. + ## Metrics [privacy_metric.ipynb](privacy_metric.ipynb) [[on nbviewer](https://nbviewer.jupyter.org/github/Trusted-AI/adversarial-robustness-toolbox/blob/main/notebooks/privacy_metric.ipynb)] diff --git a/notebooks/composite-adversarial-attack.ipynb b/notebooks/composite-adversarial-attack.ipynb index 630f8a9d13..3ce058827b 100644 --- a/notebooks/composite-adversarial-attack.ipynb +++ b/notebooks/composite-adversarial-attack.ipynb @@ -29,7 +29,7 @@ "import torch.nn as nn\n", "import torch.optim as optim\n", "\n", - "from art.attacks.evasion import CompositeAdversarialAttack\n", + "from art.attacks.evasion import CompositeAdversarialAttackPyTorch\n", "from art.estimators.classification import PyTorchClassifier\n", "from art.utils import load_cifar10\n", "\n", @@ -91,7 +91,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Accuracy on the benign test set: 56.269999999999996%\n" + "Accuracy on the benign test set: 50.839999999999996%\n" ] } ], @@ -115,8 +115,8 @@ "\n", "`CompositeAdversarialAttack` has the following parameters:\n", "- `classifier`: A trained PyTorch classifier.\n", - "- `enabled_attack`: Attack pool selection; and attack order specification for `fixed` order. For simplicity, we use the following abbreviations to specify each attack types. 0: Hue, 1: Saturation, 2: Rotation, 3: Brightness, 4: Contrast, 5: PGD($\\ell_\\infty$).\n", - "- `hue_epsilon`: The boundary of the hue perturbation. The value is expected to be in the interval `[-pi, pi]`. Perturbation of `0` means no shift and `-pi` and `pi` give a complete reversal of the hue channel in the HSV colour space in the positive and negative directions, respectively. See `kornia.enhance.adjust_hue` for more details.\n", + "- `enabled_attack`: Attack pool selection, and attack order designation for `fixed` order. For simplicity, we use the following abbreviations to specify each attack types. 0: Hue, 1: Saturation, 2: Rotation, 3: Brightness, 4: Contrast, 5: PGD ($\\ell_\\infty$).\n", + "- `hue_epsilon`: The boundary of the hue perturbation. The value is expected to be in the interval `[-np.pi, np.pi]`. Perturbation of `0` means no shift and `-np.pi` and `np.pi` give a complete reversal of the hue channel in the HSV colour space in the positive and negative directions, respectively. See `kornia.enhance.adjust_hue` for more details.\n", "- `sat_epsilon`: The boundary of the saturation perturbation. The value is expected to be in the interval `[0, infinity)`. Perturbation of `0` gives a black and white image, `1` gives the original image, while `2` enhances the saturation by a factor of 2. See `kornia.geometry.transform.rotate` for more details.\n", "- `rot_epsilon`: The boundary of the rotation perturbation (in degrees). Positive values mean counter-clockwise rotation. See `kornia.geometry.transform.rotate` for more details.\n", "- `bri_epsilon`: The boundary of the brightness perturbation. The value is expected to be in the interval `[-1, 1]`. Perturbation of `0` means no shift, `-1` gives a complete black image, and `1` gives a complete white image. See `kornia.enhance.adjust_brightness` for more details.\n", @@ -158,20 +158,19 @@ } ], "source": [ - "from math import pi\n", "# Create the ART attacker.\n", - "attack = CompositeAdversarialAttack(classifier,\n", - " enabled_attack = (0,1,2,3,4,5),\n", - " hue_epsilon = (-pi, pi),\n", - " sat_epsilon = (0.7, 1.3),\n", - " rot_epsilon = (-10, 10),\n", - " bri_epsilon = (-0.2, 0.2),\n", - " con_epsilon = (0.7, 1.3),\n", - " pgd_epsilon = (-8 / 255, 8 / 255),\n", + "attack = CompositeAdversarialAttackPyTorch(classifier,\n", + " enabled_attack = (0,1,2,3,4,5), # 0: Hue, 1: Saturation, 2: Rotation, 3: Brightness, 4: Contrast, 5: PGD (L-infinity)\n", + " hue_epsilon = [-np.pi, np.pi],\n", + " sat_epsilon = [0.7, 1.3],\n", + " rot_epsilon = [-10, 10],\n", + " bri_epsilon = [-0.2, 0.2],\n", + " con_epsilon = [0.7, 1.3],\n", + " pgd_epsilon = [-8 / 255, 8 / 255],\n", " early_stop = True,\n", " max_iter = 5,\n", " max_inner_iter = 10,\n", - " attack_order = \"scheduled\",\n", + " attack_order = \"scheduled\", # \"scheduled\", \"random\", or \"fixed\"\n", " batch_size = 1,\n", ")\n", "\n", @@ -187,7 +186,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 6, "id": "a76d108d-ee48-4a26-b6fd-3c1945e2e891", "metadata": {}, "outputs": [], @@ -220,13 +219,13 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 7, "id": "b9dee647-5194-48a0-9b0e-a1799c4f8052", "metadata": {}, "outputs": [ { "data": { - "image/png": "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G+vWrUNVVRU+++wzrFixIm6btm7diptuugm33347br31VowYMSKpejNv3jw8++yz2LlzJ4YOHSru+7Bhw1BeXo7//M//xIgRI/CVr3wF1dXVuPfee1FZWYkbb7yxw+PXaxhK2pIlSwwA88Ybb5gDBw6YvXv3mmXLlpmCggKTnp5u9u3bZ4wxZsaMGQaAue++++KW/5//+R8DwPzpT3+Ku33lypVxt+/fv9+4XC5z9dVXm2g0Grvf/fffbwCYGTNmxG576623DADz1ltvGWOMCYfDprKy0gwZMsQcOXIk7nGOXdesWbOMdBoAMPPnz4/9f9q0acblcpnt27fHbquurjbZ2dnmkksuaXd8Jk2aFPdYd911l3E4HKa+vj7h47VpaWlpd9vzzz9vAJi333673T4vX7487r6jRo0yl156abt1PPTQQyYzM9P861//irv9vvvuMw6Hw+zZs8cYY8zOnTsNAJOTk2P279/fbj0AEq5f88EHHxgAZsmSJUktR30La0P31oa24zZnzpy4bb766quNy+UyBw4cMMZ0/ji2rTMzMzPufhs3bjQAzHe/+9242++55x4DwLz55pux24YMGWIAmJUrV8bdt7P15tj92rlzp7r/xhizbt06M2zYMAMg9jN27FhTU1PT4bK9CT92OQGTJk1CUVERKioqcOONNyIrKwsrVqzASSedFHe/O+64I+7/y5cvh9frxRVXXIGDBw/GfsaOHYusrCy89dZbAIA33ngDwWAQc+bMiXvL88477+xw2zZs2ICdO3fizjvvbPediGPX1VmRSASvvfYapk2bhpNPPjl2e1lZGb71rW/hnXfeQWNjY9wyt912W9xjXXzxxYhEIti9e7f6WMe+dej3+3Hw4EGcf/75AICPPvoo6W1vs3z5clx88cXIy8uLO+6TJk1CJBLB22+/HXf/6dOno6ioqN16jDF814NUrA3dUxvazJ49O26bZ8+ejWAwiDfeeANA54+j5JVXXgEAzJ07N+72u+++GwDw97//Pe72yspKTJkyJe62ZOrN0qVLYYxR3/Vok5eXh7POOgv33Xcf/vrXv+Kxxx7Drl27cMMNN8Dv93e4fG/Bj11OwKJFi3DqqaciLS0NJSUlGDFiBOz2+PlcWloaysvL427btm0bGhoaUFxcnHC9bV+kbHshnnLKKXHjRUVFyMvLU7et7W3eM844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", + "image/png": "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", "text/plain": [ "
" ] @@ -236,7 +235,7 @@ }, { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAh8AAAEjCAYAAACSDWOaAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/OQEPoAAAACXBIWXMAAA9hAAAPYQGoP6dpAABByUlEQVR4nO3de3hU1b0//vfcJ9dJQkISJEAAQUXBNiqiKKhIBPWIRVttz1OwVtECLaDlGL+tVLRNK54Wq0hr2wO2TykeWqmttaighKpAFeGHoCDEAMFcuOY2ydzX7w9Oxgwzn5VMmOzc3q/nmeeR/Zm999pr9nxc2bM/e5mUUgpEREREBjF3dwOIiIiof+Hgg4iIiAzFwQcREREZioMPIiIiMhQHH0RERGQoDj6IiIjIUBx8EBERkaE4+CAiIiJDcfBBREREhuLgo5caNmwYZs+eHf735s2bYTKZsHnz5oTtw2Qy4Uc/+lHCttcV3n//fVx11VVISUmByWTCrl27urtJRN2qL+eG2bNnIzU1NeHbXbZsGYYPHw6LxYJLL7004dunaBx8dMLq1athMpnCL6fTiVGjRmHevHmora3t7ubF5bXXXuvxAwyJ3+/HnXfeiVOnTuEXv/gF/vCHP2Do0KF4/vnnsXr16u5uHgBgx44duOmmm5Ceno60tDRMnTqVA6Q+jLmh93njjTewePFiXH311Vi1ahV+8pOfdHeTtDweD0pLS3HRRRchOTkZ5513Hu68807s3bu3u5sWF2t3N6A3W7p0KQoLC+HxePDOO+9g5cqVeO2117Bnzx4kJycb2pZrr70WLS0tsNvtca332muvYcWKFTGTTEtLC6zWnnuKlJeX4/Dhw/jNb36Db3/72+Hlzz//PLKzsyP++usOH374ISZOnIiCggIsWbIEoVAIzz//PCZNmoR///vfGD16dLe2j7oOc0Pv8dZbb8FsNuN3v/td3H3UHb7xjW/gb3/7G+677z58+ctfRlVVFVasWIEJEybgo48+wtChQ7u7iR3SN86ebjJt2jRcdtllAIBvf/vbGDBgAH7+85/jlVdewd133x1zHbfbjZSUlIS3xWw2w+l0JnSbid5eoh07dgwAkJGR0eX7CgQCCIVCcSWnH/7wh0hKSsLWrVsxYMAAAMB//ud/YtSoUXj00Ufxl7/8pauaS92MuaH3OHbsGJKSkhI28FBKwePxICkpKSHba+vzzz/Hyy+/jIcffhjLli0LL7/mmmtw/fXX4+WXX8bChQsTvt+uwJ9dEuj6668HAFRUVAD44vfJ8vJyTJ8+HWlpafjGN74BAAiFQli+fDnGjBkDp9OJ3NxczJkzB6dPn47YplIKTz75JAYPHozk5GRcd911MS+vSb/rbt++HdOnT0dmZiZSUlIwduxYPPPMM+H2rVixAgAiLhW3ivW77s6dOzFt2jSkp6cjNTUVN9xwA7Zt2xbxntZLz++++y4WLVqEnJwcpKSk4Pbbb8fx48fb7cfdu3dj9uzZGD58OJxOJ/Ly8vCtb30LJ0+eDL9n9uzZmDRpEgDgzjvvhMlkwuTJkzFs2DDs3bsXZWVl4eOZPHlyeL26ujosWLAABQUFcDgcGDlyJH72s58hFAqF33Po0CGYTCY8/fTTWL58OUaMGAGHw4GPP/4YALBv3z4cOXKk3eP417/+hSlTpoQHHgCQn5+PSZMm4dVXX0VTU1O726C+gbnhjHPNDa0+++wzFBcXIyUlBYMGDcLSpUtx9gTtHelHk8mEVatWwe12h4+x9SfbQCCAJ554Ivz9HzZsGB599FF4vd6I/QwbNgy33HILXn/9dVx22WVISkrCr3/9awAdyzcAUF1djX379sHv92uPu7GxEQCQm5sbsTw/Px8AumTA01V45SOBysvLASDifzaBQADFxcWYOHEinn766fAl1zlz5mD16tW455578N3vfhcVFRV47rnnsHPnTrz77ruw2WwAgMceewxPPvkkpk+fjunTp+PDDz/E1KlT4fP52m3Pm2++iVtuuQX5+fn43ve+h7y8PHzyySd49dVX8b3vfQ9z5sxBVVUV3nzzTfzhD39od3t79+7FNddcg/T0dCxevBg2mw2//vWvMXnyZJSVlWH8+PER758/fz4yMzOxZMkSHDp0CMuXL8e8efPw0ksvtdvuzz77DPfccw/y8vKwd+9evPDCC9i7dy+2bdsGk8mEOXPm4LzzzsNPfvITfPe738Xll1+O3NxcuN1uzJ8/H6mpqfh//+//Afjii9rc3IxJkybh888/x5w5czBkyBC89957KCkpQXV1NZYvXx7RjlWrVsHj8eD++++Hw+FAVlYWAODCCy/EpEmT2r2Bz+v1xkwGycnJ8Pl82LNnD6688krtNqhvYG5ITG4AgGAwiJtuuglXXnklnnrqKWzYsAFLlixBIBDA0qVLw+/rSD/+4Q9/wAsvvIB///vf+O1vfwsAuOqqqwCcuWL14osv4o477sBDDz2E7du3o7S0FJ988gnWr18f0ab9+/fj7rvvxpw5c3Dfffdh9OjRceWbkpISvPjii6ioqMCwYcPEYx8xYgQGDx6M//7v/8bo0aPxpS99CVVVVVi8eDEKCwtx1113tdt/PYaiuK1atUoBUBs3blTHjx9XlZWVau3atWrAgAEqKSlJHT16VCml1KxZsxQA9cgjj0Ss/69//UsBUH/84x8jlm/YsCFi+bFjx5Tdblc333yzCoVC4fc9+uijCoCaNWtWeNnbb7+tAKi3335bKaVUIBBQhYWFaujQoer06dMR+2m7rblz5yrpNACglixZEv73jBkzlN1uV+Xl5eFlVVVVKi0tTV177bVR/TNlypSIfS1cuFBZLBZVV1cXc3+tmpubo5b96U9/UgDUli1boo553bp1Ee8dM2aMmjRpUtQ2nnjiCZWSkqI+/fTTiOWPPPKIslgs6siRI0oppSoqKhQAlZ6ero4dOxa1HQAxt3+2Sy65RI0aNUoFAoHwMq/Xq4YMGaIAqD//+c/tboN6F+aGrs0Nrf02f/78iDbffPPNym63q+PHjyulOt6PrdtMSUmJeN+uXbsUAPXtb387YvnDDz+sAKi33norvGzo0KEKgNqwYUPEezuab9oeV0VFhfb4lVJq+/btasSIEQpA+FVUVKSqq6vbXbcn4c8u52DKlCnIyclBQUEB7rrrLqSmpmL9+vU477zzIt734IMPRvx73bp1cLlcuPHGG3HixInwq6ioCKmpqXj77bcBABs3boTP58P8+fMjLnkuWLCg3bbt3LkTFRUVWLBgQdQ9EW231VHBYBBvvPEGZsyYgeHDh4eX5+fn4+tf/zreeecdNDQ0RKxz//33R+zrmmuuQTAYxOHDh7X7anu1wOPx4MSJE+ErBB9++GHcbW+1bt06XHPNNcjMzIzo9ylTpiAYDGLLli0R7585cyZycnKitqOU6lDZ4ne+8x18+umnuPfee/Hxxx9jz549+OY3v4nq6moAZ27ao76JuaFrckOrefPmRbR53rx58Pl82LhxI4CO96PktddeAwAsWrQoYvlDDz0EAPjHP/4RsbywsBDFxcURy+LJN6tXr4ZSSnvVo1VmZiYuvfRSPPLII/jrX/+Kp59+GocOHcKdd94Jj8fT7vo9BX92OQcrVqzAqFGjYLVakZubi9GjR8NsjhzPWa1WDB48OGLZgQMHUF9fj4EDB8bcbuuNlK1fxPPPPz8inpOTg8zMTG3bWi/zXnzxxR0/II3jx4+jubk5ZoXGhRdeiFAohMrKSowZMya8fMiQIRHva23z2b9dn+3UqVN4/PHHsXbt2nBftKqvr+/sIeDAgQPYvXt3zAEFgKh9FRYWdnpfAPDAAw+gsrISy5Ytw4svvggAuOyyy7B48WL8+Mc/7pLnFVDPwNxwRqJzA3DmBtq2gxwAGDVqFIAz92sBHe9HyeHDh2E2mzFy5MiI5Xl5ecjIyIgaJMXKFfHmm46or6/HNddcg+9///vhgRBwJq9MnjwZq1atihrQ9lQcfJyDK664InxHu8ThcEQlnVAohIEDB+KPf/xjzHWkk7W3sVgsMZers24MO9tXv/pVvPfee/j+97+PSy+9FKmpqQiFQrjpppuibtSKRygUwo033ojFixfHjLcmsFaJuHnrxz/+MR5++GHs3bsXLpcLl1xyCR599NGY+6O+g7lBr7O5oaMS1Y8dvRIUK1fEm2864i9/+Qtqa2vxH//xHxHLJ02ahPT0dLz77rscfJBsxIgR2LhxI66++mrt/+Ba67UPHDgQMdI/fvx4u38hjBgxAgCwZ88eTJkyRXxfR79cOTk5SE5Oxv79+6Ni+/btg9lsRkFBQYe2pXP69Gls2rQJjz/+OB577LHw8gMHDnR4G9IxjRgxAk1NTdr+6AqZmZmYOHFi+N8bN27E4MGDccEFFxjaDur5mBvaFwqF8Nlnn0X8z/vTTz8FgPDPFh3tR8nQoUMRCoVw4MABXHjhheHltbW1qKur69CzNLoi37Q+qC4YDEYsV0ohGAwiEAgkbF9djfd8dIOvfvWrCAaDeOKJJ6JigUAAdXV1AM78bmyz2fDss89G/EVwdlVGLF/+8pdRWFiI5cuXh7fXqu22Wp8rcPZ7zmaxWDB16lS88sor4UubwJkvw5o1azBx4kSkp6e32672tP5FdPZfQB055lYpKSkxj+erX/0qtm7ditdffz0qVldX1+EvbkdLbWN56aWX8P7772PBggVRf/USMTd0zHPPPRfR5ueeew42mw033HADgI73o2T69OkAovvz5z//OQDg5ptvbreN8eSbjpbatg641q5dG7H8b3/7G9xuN770pS+1266eglc+usGkSZMwZ84clJaWYteuXZg6dSpsNhsOHDiAdevW4ZlnnsEdd9yBnJwcPPzwwygtLcUtt9yC6dOnY+fOnfjnP/+J7Oxs7T7MZjNWrlyJW2+9FZdeeinuuece5OfnY9++fdi7d2/4C1FUVAQA+O53v4vi4mJYLBaxXOvJJ5/Em2++iYkTJ+I73/kOrFYrfv3rX8Pr9eKpp55KSN+kp6fj2muvxVNPPQW/34/zzjsPb7zxRvj5CB1RVFSElStX4sknn8TIkSMxcOBAXH/99fj+97+Pv/3tb7jlllswe/ZsFBUVwe1246OPPsKf//xnHDp0qN1+BTpeartlyxYsXboUU6dOxYABA7Bt2zasWrUKN910E773ve91+Hio/2BuaJ/T6cSGDRswa9YsjB8/Hv/85z/xj3/8A48++mj455SO9qNk3LhxmDVrFl544QXU1dWFn0r84osvYsaMGbjuuuvabWc8+aajpba33norxowZg6VLl+Lw4cO48sorcfDgQTz33HPIz8/HvffeG19ndqduqrLp1VrLxd5//33t+2KVcLX1wgsvqKKiIpWUlKTS0tLUJZdcohYvXqyqqqrC7wkGg+rxxx9X+fn5KikpSU2ePFnt2bNHDR06VFtO1+qdd95RN954o0pLS1MpKSlq7Nix6tlnnw3HA4GAmj9/vsrJyVEmkymitA5nldMppdSHH36oiouLVWpqqkpOTlbXXXedeu+99zrUP1Ibz3b06FF1++23q4yMDOVyudSdd96pqqqqotojldrW1NSom2++WaWlpUWVxTY2NqqSkhI1cuRIZbfbVXZ2trrqqqvU008/rXw+n1Lqi1LbZcuWxWzf2duUHDx4UE2dOlVlZ2crh8OhLrjgAlVaWqq8Xm+761LvxNzQtbmhtd/Ky8vV1KlTVXJyssrNzVVLlixRwWCwU/0ofRZ+v189/vjjqrCwUNlsNlVQUKBKSkqUx+OJeN/QoUPVzTffHLO9Hck3rW1AB0ttT506pRYuXKhGjRqlHA6Hys7OVnfddZf67LPP2l23JzEplaA7fIiIiIg6gD86ExERkaE4+CAiIiJDcfBBREREhuLgg4iIiAzFwQcREREZioMPIiIiMlSXPWRsxYoVWLZsGWpqajBu3Dg8++yzuOKKK9pdLxQKoaqqCmlpaZ2aYZGIzp1SCo2NjRg0aJChT2LtbN4AmDuIultceaMrHh6ydu1aZbfb1f/8z/+ovXv3qvvuu09lZGSo2tradtetrKxUAPjii68e8KqsrOyKFBHTueQNpZg7+OKrp7w6kje65CFj48ePx+WXXx5+/n4oFEJBQQHmz5+PRx55RLtufX09MjIycN/j/wO7Mzn6DSF5/o1TJ2rFmM/jFWPDCoeLMVd6mhizWeSRnc0We9ZGALBr1gMAu1n+q82i+YMuFGgRYynJNjFm02zUootpRrZ1dafFWFqq3KdWm3wxzmqS+9Sk6bNASJ4vobN/1Jvb+cu6xS1/FharfIxOp0OM+XzycQR88vmd5JQn1jIJHeB2u3HH7beirq4OLpdLXD+RziVvAF/kjqdfehdJyanRbzhrMq62dLnD6/WIMV3uyNDMZ2LVfK/sutzRzglr08StJjnVB4PyMaYma76TmuPQxSya77Iud6Smxfhc/4/NKue4zucOnxjrfO7Qr9jcLOcOq1U+DofDKcb8Pvk4An455tRs02SObktjYyMuuej8DuWNhP/s4vP5sGPHDpSUlISXmc1mTJkyBVu3bo16v9frhdf7ReJsbGwEANidyXAkxRh8BOXBh90hJ1ml5BMs5n7+jzM5RYzpBh/aBNLu4KOTCSQgr5ec0rnBhzaBxDj5Wvk0J3tyiqZPbX0jgZg0t1NZtYMP+ctus2kSiGbQph98yH0KdHxm03MVb94A5NyRlJyKpJQYA1xN7nA2N4kxXR8lx9pPa0wzyO55uUP+3qUanDsCms8pLU3Tp30kd1gsmsFeJ3OHLh93/g8XTZ92IG8k/MfcEydOIBgMIjc3N2J5bm4uampqot5fWloKl8sVfiVy6mUi6h3izRsAcwdRb9bt1S4lJSWor68PvyorK7u7SUTUCzB3EPVeCf/ZJTs7GxaLBbW1kb+h1tbWIi8vL+r9DocDDof8OzcR9X3x5g2AuYOoN0v44MNut6OoqAibNm3CjBkzAJy5cWzTpk2YN29eh7eTmmyHIyk6sZiV3GSvW05EIV+zGHPa5d+nUpJ0N0CKIZgh39zmsOovOCXZ5bgZITHm1dxQ57DKvwfabZr9aY5Rd/OT7ndrs+a3Z5Pm+Bx2uxjT/RTubtbccCqvBrtmfwr6eyXMmo6zaX631f1u7ffKv81aNb8jJ+n+By38Nhvwye3oConKGwCQkuxAcjJzR/R2mTtiYe5IXO7w2TueN7rkOR+LFi3CrFmzcNlll+GKK67A8uXL4Xa7cc8993TF7oioD2DeIOo/umTw8bWvfQ3Hjx/HY489hpqaGlx66aXYsGFD1M1kREStmDeI+o8ue8LpvHnz4r5cSkT9G/MGUf/Q7dUuRERE1L9w8EFERESG4uCDiIiIDNVl93ycK4spCKsp+jG7ujI0u0UutbKZNaVkZs1jl3Xb1Dw+2Nsil+dZLPpnEzit8iNt/Zp5JsyQj0MF5PWUST4NgpBL2+w2uZ26kjgo+bPQPZY8qJmjpblZ7u+Tx4+LsdzsTLktujl27PqvjkXTbxZN32gqF2HVtMereSS17jHXfn/s9ZRmDqWezooAc0cMzB2xMXckLncozbbOxisfREREZCgOPoiIiMhQHHwQERGRoTj4ICIiIkNx8EFERESG4uCDiIiIDNVjS23t5iDsMUrcQgGfuI4FcjmVzawpe9OsZw7KZVh2m1z2ZrLIJWE2s3wMZ+LyxxIyyeuaQ/LMhQGPplzQkiLGPD55f8nJcrmcRTelZUj+LKDkUjK3Ry7527HjQzHm15QuZqZfLsYcDnlsrqlAAwCYlOYYQ/JnYdaU2Zk0ZYYhTWms0uxPLKnVrNPTMXfExtwRG3NH4nJHPCX6vPJBREREhuLgg4iIiAzFwQcREREZioMPIiIiMhQHH0RERGQoDj6IiIjIUD231NZqgt0aXZOkTHKdks2smQ0xKJeSWTQzOpo069lgEWN+zUyQwZC+1sqSbpfbo+TSPoTk0rZQQFO+FZTL/poa6sRYarJTjJk1ZW8Bn9ynVpt8StZpZp881SDHkqzyGNunqQzz+eU+s9o15xoApSmXCwblzzCgKQf1afrNbpX7TWnKE0PB2KV00vLewMbcEbs9zB0xMXckLnfEkzd45YOIiIgMxcEHERERGYqDDyIiIjIUBx9ERERkKA4+iIiIyFAcfBAREZGhem6pLYJwmKLLdoImub5JN/uk3yuXr5k15XIqpFnPJHef1Sxv09rOtIYWk1xOpTTle9DMahgIydsMambmbGpsEGNHdH2qKVHTlZIVpCeLsZPHj4ux/2/3bjE2dswYMRbSfBbeoFy65lQ2MQYAIU3pYkuzHLNb5b4J+OWSQItV7jd/QD4Xvd7Y25SW9wYOE3NHzPYwd8TE3JG43OHztYjvP1vCr3z86Ec/gslkinhdcMEFid4NEfUhzBtE/UuXXPkYM2YMNm7c+MVONA8xISICmDeI+pMu+XZbrVbk5eV1xaaJqI9i3iDqP7rkhtMDBw5g0KBBGD58OL7xjW/gyJEj4nu9Xi8aGhoiXkTU/8STNwDmDqLeLOGDj/Hjx2P16tXYsGEDVq5ciYqKClxzzTVobGyM+f7S0lK4XK7wq6CgINFNIqIeLt68ATB3EPVmCR98TJs2DXfeeSfGjh2L4uJivPbaa6irq8P//u//xnx/SUkJ6uvrw6/KyspEN4mIerh48wbA3EHUm3X5HV0ZGRkYNWoUDh48GDPucDjgcETPjGgJemAJRI+NQpqSIbNmVr+Wes0lWU1ZoTLLpWSWJLn77JryNLtVntESAEx+txgL6kogg/J2TTFm+WylTHK/ud31Yqy2Vm5LSnqqvD+zppROc5Ohr0nen9Mmz655vK5OjH24Ry6zS3HI/Tly+HAxBgBWTemit1n+az7JKq8X8splbEHNzKNBXWWfR/hedHOpbXt5A9DkjoAXlkD0QTN3MHfEwtyRwNzhadKsEKnLHzLW1NSE8vJy5Ofnd/WuiKiPYN4g6tsSPvh4+OGHUVZWhkOHDuG9997D7bffDovFgrvvvjvRuyKiPoJ5g6h/SfjPLkePHsXdd9+NkydPIicnBxMnTsS2bduQk5OT6F0RUR/BvEHUvyR88LF27dpEb5KI+jjmDaL+hRPLERERkaE4+CAiIiJD9djJE5wmBacpunTIpORyIl25nENFz3LZKjUkl5K5IJdMmevlsjZHSN6fUz6EM9ttlsuizB65ZMxulkvGEJSP0dcg91tairzNzKwsMVZxtEaMfVYpxz49uEmMnT5RJ8aaPJpSSf9eMWaBvJ5fUyp48ehRYgwA/uPmm8TYebkDxJjXKZ83Hrd8vvnccp+mK/m+CVNL7NI9k+Yc7OkczB2xY8wdMTF3JC53mDT7ORuvfBAREZGhOPggIiIiQ3HwQURERIbi4IOIiIgMxcEHERERGYqDDyIiIjJUjy21PXr4CJxOZ9Ryv18ub2pskGf8C/q9Yuzzzz8XY6cd8rR+7iZ5tsuBA+RSstSU6ONqy2KVS6Z8/oAYs9qTxJjZahdjbk0Jnscsl9lByafPkaoTYqzi6Cm5LT65nU7XQDFmSpFnZpTnyARS7PL4u/rwp2KsqqpWs1XgX/96V4xdeL48q2VORroYa2mqE2PuhpNizH/haDHWVH869r488velp/v8yBEkJydHLWfuYO6IhbkjcbnDHUeJPq98EBERkaE4+CAiIiJDcfBBREREhuLgg4iIiAzFwQcREREZioMPIiIiMhQHH0RERGSoHvucj63/fh9Wa3SdvMkkT1Md0kxF3dIiT/V7qKZKjOlK1a2aoVumS665TnHK9egA4NDs02aVj9/qkKewNlvl5wM0a6aUtmqOQ1nk/dWcahJj/pDccclpGWIMkJ9T4GuSnzdghtyhHo98XqSnycd+ZdElYgwA3PXy8wg8Ho8YO3Ik9nM3AKC8vFyMtQTkudYPn5Rr71uaYx+/3+8X1+np3tv+PhwxvgvMHcwdsTB3JC53eL0dfz4Qr3wQERGRoTj4ICIiIkNx8EFERESG4uCDiIiIDMXBBxERERmKgw8iIiIyVNyltlu2bMGyZcuwY8cOVFdXY/369ZgxY0Y4rpTCkiVL8Jvf/AZ1dXW4+uqrsXLlSpx//vlx7Wd3+SGYzdGlYclJaeI6SsnlVN6AXE7lyhwgxhx2uczMpym1Ot4kl0RZTJp6OABpzhQxFgjKJZAmmzyWtFjk4zBZ5f053PK04D6/PC34qVNyuRggl3bpusYXlMu4Gt1ySZivRV6vIEeevnxAZp4Yc7vrxRgAnDp9XN5uhvxZXDZujBg7Wi1P317fIpdR7jsqT5kd6zsGAMGA/F3qDKPyBgB8VH4IVlv0ecvcwdwRC3NH4nKHz9fxEv24r3y43W6MGzcOK1asiBl/6qmn8Mtf/hK/+tWvsH37dqSkpKC4uFhbn0xEfRvzBhG1FfeVj2nTpmHatGkxY0opLF++HD/4wQ9w2223AQB+//vfIzc3F3/9619x1113nVtriahXYt4gorYSes9HRUUFampqMGXKlPAyl8uF8ePHY+vWrTHX8Xq9aGhoiHgRUf/RmbwBMHcQ9WYJHXzU1NQAAHJzcyOW5+bmhmNnKy0thcvlCr8KCgoS2SQi6uE6kzcA5g6i3qzbq11KSkpQX18fflVWVnZ3k4ioF2DuIOq9Ejr4yMs7c4dvbW1txPLa2tpw7GwOhwPp6ekRLyLqPzqTNwDmDqLeLKGz2hYWFiIvLw+bNm3CpZdeCgBoaGjA9u3b8eCDD8a1raaAgskcXValdLMaJqeKsSRNudjgghFizK8pHTquuSR84qRcopSbO1CMAYAje7AYc9fJ2w2ZQ2LMlZkrxhyOTDHm0VRONQfk39idKfL/CIJ+edZKi0meXdSumQnTZpfLxfxOOXbFl+XytFFDB4kxj08ulQSAinL5fCvf/7EYm3C5PONlQYHcniO7D4sxf1AuTwwFY5eYJrrUVieReQM4kzssJuaOszF3xMbckbjc4ffLn8HZ4h58NDU14eDBg+F/V1RUYNeuXcjKysKQIUOwYMECPPnkkzj//PNRWFiIH/7whxg0aFBETT8R9S/MG0TUVtyDjw8++ADXXXdd+N+LFi0CAMyaNQurV6/G4sWL4Xa7cf/996Ourg4TJ07Ehg0b4HTKozki6tuYN4iorbgHH5MnT4ZSuqfMmbB06VIsXbr0nBpGRH0H8wYRtdXt1S5ERETUv3DwQURERIbi4IOIiIgMldBS20Sy2VNgskQ3L2egXDLktMtjqRMnjooxt7tRbkhInirR45fLEV058vMJziscKe8PQJpLLl9Lz5ZL7U6eOi3GgiH5o9ZVR7W0yGVhzc1y2ZvPL88UCcg1eHa73E6nQ55B06Z8Ymyg5vkPOZlyzKmZ6TNHU34IAOl2eUbPk0eOiLHD5YfEWF5Wthirr90mxmxZOWLMF+M7BgAhs3721J7M6kiB1WaPWs7cwdwRC3NH4nKHP468wSsfREREZCgOPoiIiMhQHHwQERGRoTj4ICIiIkNx8EFERESG4uCDiIiIDNVjS21dGQNgtkSXHFmE0kAA8Ho9YsykGWedOlknxhoaNLMo2uSZEi0heTbEw5/XijEASG+QS81crgx5n5rZN70euZzMZJLL/hw2zSmSkiyGkpTcN2arphxLybNrpiTJ+7MpuQRv8AC5zC5ZM6Olu6FOjAU0pYIAEGNS1bBCTbnkJ/s+E2OjRo2WNyrMTgsA1VWfizFHZlbM5aFgx2en7GlcrgGw2aPPP+aODHmfzB0xMXfElzsCfvlcORuvfBAREZGhOPggIiIiQ3HwQURERIbi4IOIiIgMxcEHERERGYqDDyIiIjJUjy21tVgdMFujS22bW+RSHoumRslilUvJgkF5DGa1poqxkJLXszvSxFh2dr4YA4DU1CQx5kySj8PlkGOxZvlspUxy+ZoKyn0aCMglaq50ud/MZnmboaD8+Vo1s0+GvHL5msuhOb6AV4wFg3LMF5DL7ACgRVOemJzmEmOHa06KsY/L3xBjXq9cYun3yqV0yhL7OFSo95baWmyOmKWszB3MHTHXY+4QY/HmjoBf/lzPxisfREREZCgOPoiIiMhQHHwQERGRoTj4ICIiIkNx8EFERESG4uCDiIiIDBV3qe2WLVuwbNky7NixA9XV1Vi/fj1mzJgRjs+ePRsvvvhixDrFxcXYsGFDXPvJys6FJUaJV8gvz1yYmhRdmhteLyiXE9nMcpnZwIGDxJgpRilwK7tTLnmza8raAMDplD8Wi1UeL+rK3kwWzWyQmvUsJnl/zW65RM2smWFSN9ul0pTSNdfLpWSfHzogxk7Z5OPLSJLbkjsgQ4w5nfIsmQDg8WlK1KzyrJ3W5HQxdvxolRgryM8RY2k++bNoEErpQkEzGsS14mdU3gCArOyBsDuiv3/MHcwdsTB3JC53BOK4nBH3lQ+3241x48ZhxYoV4ntuuukmVFdXh19/+tOf4t0NEfUhzBtE1FbcVz6mTZuGadOmad/jcDiQl5fX6UYRUd/CvEFEbXXJPR+bN2/GwIEDMXr0aDz44IM4eVK+5OX1etHQ0BDxIqL+J568ATB3EPVmCR983HTTTfj973+PTZs24Wc/+xnKysowbdo0BIOxH9dcWloKl8sVfhUUFCS6SUTUw8WbNwDmDqLeLOFzu9x1113h/77kkkswduxYjBgxAps3b8YNN9wQ9f6SkhIsWrQo/O+GhgYmEaJ+Jt68ATB3EPVmXV5qO3z4cGRnZ+PgwYMx4w6HA+np6REvIurf2ssbAHMHUW/W5bPaHj16FCdPnkR+vn42xrMlJafBGmNmSr9mxr+kFLkMLSN9oBgLBeQSLatdntExKVWefVKZ5JkLzRZ9t4eUZl3deFET0kyiCQW5nCoQkMsMA8FmMdZw8oQY0x29TVMu11R/XIxVV8mlZLlZ8v+UMlKyxVizpswspClbBICA5ih1s32eN1j+y330+cPF2KUXybFPP6sUYzs/+iTm8kAggKry/eJ6Xa2zeQMAkpPSYI9RzsjcwdwRC3NH4nKHzyfP5nu2uAcfTU1NEX+NVFRUYNeuXcjKykJWVhYef/xxzJw5E3l5eSgvL8fixYsxcuRIFBcXx7srIuojmDeIqK24Bx8ffPABrrvuuvC/W39znTVrFlauXIndu3fjxRdfRF1dHQYNGoSpU6fiiSeegMMhPxyFiPo25g0iaivuwcfkyZOhlHzp5/XXXz+nBhFR38O8QURtcW4XIiIiMhQHH0RERGQoDj6IiIjIUF1eattZzS0eWGKUsaUlySVqFk0Z2rHj8qOaG+rrxFgoJI/PRo4aLcYysuQyLItNLocDABPkeCAol3DpypyafW4x5vHKZW8Bn/zIalPQL8aUV25Lil2e0TMjI0uMJdnl2RetJvl+goxUeRZJV5oc82mOoVlzXpxZV+4bs0metTLTJZf2JTvkfR6tPCzGLHLXYMzo82Mu9/l82PpOmbxiD+b2eOGPUR/K3MHcEQtzR+JyR0uLXF59Nl75ICIiIkNx8EFERESG4uCDiIiIDMXBBxERERmKgw8iIiIyFAcfREREZKgeW2prt9lgtUWXVZ08cUxcp/y0PBtiMCiXPmVkZoqx/PxcMeYLyCVRfp9HjIVUUIwBQEOzXNrW0iKXtgUD8jFaNDM+2m3yGFRX2uZMSRJjSTb51PI0N4mxkGaWzJTUVDFmMZnEmN0ilx9aLPKx2zTH7gnIJW8AYNLs06Q5Rr9fnnn16MnTYqzZXS/GrFZ5fpS8/MExl5t0NXY9nMNqg525IwpzR2zMHYnLHSaL/tja4pUPIiIiMhQHH0RERGQoDj6IiIjIUBx8EBERkaE4+CAiIiJDcfBBREREhuqxpbb1dadgsdqjlld/XiWuk5wizzJ4wUWXiLGs7IHyNpPlkjBPi1zWdvr0KTHm98tlbQDQrOSSqeRkpxhzpctlUSkOOZakKQuzasrQgpqZKQMB+Rj8frlc0GOWS7VMkNtiNsvlacGgXCro11SUWi3R518rFZLLIQHA45XjJ4/LZZ0nTsqxxsZGMXa6rk6MpSSniDFH2oCYy/0++fPr6errTsHmiP6eMHcwd8TC3FEnxuLNHR6P/tja4pUPIiIiMhQHH0RERGQoDj6IiIjIUBx8EBERkaE4+CAiIiJDcfBBREREhoqr1La0tBQvv/wy9u3bh6SkJFx11VX42c9+htGjR4ff4/F48NBDD2Ht2rXwer0oLi7G888/j9xceYbHWDKzB8Jqiy7xytSUtlk1swFanXKZWWOTPFNiU1ODGHM45DIz3QyDIc2MlgAwKDdH3qdTLuHSzT6pQnIZmtvTIsY8DXKJVp2mJPDkqeNirEVTZnjhhaPFmC0jQ4zJhXSAxSxHdTNMet3ysR+tqdTsETh+Qj5+n6aMtdkt9019nTz7pN0if5V15/emt96KuTwUkmfP7Axjc0cO7M7o0lnmDuaOWJg7Epc7Au2cn23FdeWjrKwMc+fOxbZt2/Dmm2/C7/dj6tSpcLc56IULF+Lvf/871q1bh7KyMlRVVeErX/lKPLshoj6GuYOI2orryseGDRsi/r169WoMHDgQO3bswLXXXov6+nr87ne/w5o1a3D99dcDAFatWoULL7wQ27Ztw5VXXpm4lhNRr8HcQURtndM9H/X1Zy7lZGVlAQB27NgBv9+PKVOmhN9zwQUXYMiQIdi6dWvMbXi9XjQ0NES8iKhvY+4g6t86PfgIhUJYsGABrr76alx88cUAgJqaGtjtdmSc9ftabm4uampqYm6ntLQULpcr/CooKOhsk4ioF2DuIKJODz7mzp2LPXv2YO3atefUgJKSEtTX14dflZX6m3GIqHdj7iCiTk0sN2/ePLz66qvYsmULBg8eHF6el5cHn8+Hurq6iL9gamtrkZeXF3NbDocDDs3ERUTUdzB3EBEQ5+BDKYX58+dj/fr12Lx5MwoLCyPiRUVFsNls2LRpE2bOnAkA2L9/P44cOYIJEybE1TC/UlAquvzL6ZSTjdUql68FlVw6aDHJZWZWi3xxSFOFBaemrK3FrZ8xtKVeLtNqkUOw2jVttckxFZRLxvZ/8rEYO3LokBgLBOVjVEqemXJQfuz/0QBAlsslxlqamzsVqztdJ8ZOnj4pb9MnlxgCQFDTp82a9tRr7lswQz5Pk63yV7mmulqMeRvlY0wko3OHibkjOsbcERNzR+dyR6yfQ0Mh+fM5W1yDj7lz52LNmjV45ZVXkJaWFt65y+VCUlISXC4X7r33XixatAhZWVlIT0/H/PnzMWHCBN6tTtSPMXcQUVtxDT5WrlwJAJg8eXLE8lWrVmH27NkAgF/84hcwm82YOXNmxIOCiKj/Yu4gorbi/tmlPU6nEytWrMCKFSs63Sgi6luYO4ioLc7tQkRERIbi4IOIiIgMxcEHERERGapTz/kwwmcH98NkiS5/u2jMReI6SZoSNd0knWbNvIa60qHaY8fEmLtBnkXQ29JOqZVmtkRdGdbwkcPEWM7AbHmbms6xaUoQXa50MaadQVOeQBQer0eM7du/X4w1ueXZF3Xb9Gv6OqS5T8HdqKlbBNCi+Yybm+XZJ3WzVjo0JXENx06IsVCLfC72ReUHP4XVHl1Wy9zB3BELc4ecO+rq6sRYMBR9jKEYyyS88kFERESG4uCDiIiIDMXBBxERERmKgw8iIiIyFAcfREREZCgOPoiIiMhQPbbU1u9pgskS3TxPU524jlk3G6JmVj9zjP20Cgb8YuzAgU/FWFN9nRiz2/TdbnM4xZhVU2sWCsilfeaApl4wKPfNgKwseZuamTmbW+TytRZNrLLyaKf2Z9IMo5VZDjb75FK6ek2ZmfukvnzVpiltC2jOKRWUP0NPnTxrJYJyCV5/4/c2QoWicwFzB3NHLH0ldwQ0ucOtyR2BFjl3BDXbRMzvBUttiYiIqIfi4IOIiIgMxcEHERERGYqDDyIiIjIUBx9ERERkKA4+iIiIyFA9ttTWYTXDbIkeG/k0pVZOq1xPZTLLZWax9hOOaUrb0tNT5bbY5P2lpiSLMQCwOKNn5GyV7JRL6QJ+TWnfvn1irP7UKTnmlmdgDCq5DMtml4/fqulvh12e0dJklsu4mj3yTJDHT50UY17NrJXQnDOZ6RnyegB8Hs1smJpzGH5NaZtmllRoZleNp/ytL3BazbBamTvOxtwRW2dzR7Mmd1i6KHfoypADmtwR0pbM6uqQNd+LGDXKJhNLbYmIiKiH4uCDiIiIDMXBBxERERmKgw8iIiIyFAcfREREZCgOPoiIiMhQcQ0+SktLcfnllyMtLQ0DBw7EjBkzsH///oj3TJ48GSaTKeL1wAMPJLTRRNS7MHcQUVtxPeejrKwMc+fOxeWXX45AIIBHH30UU6dOxccff4yUlJTw++677z4sXbo0/O/kZH1teixmswXmGLXSQc30ziZT56aM9no19eiaKYyTNFMfm202Mdbi1k9/7j1VJcYqm+U671AgIMZMSq6/tmnaarHKzwawOTXPP9CcWT6f3M6m03LNvccjH7vH0yzGdE/AsGmmzPZ75GnW/ZCPHQBaNM8OgFcTg2b6cu2R6Nqjq72XtqkA6J4NEB9Dc4eJuSMW5g4p1rnc4eyG3NHSIsdCIc35bZaPJKB5JokKysdot0VvU/88kUhxDT42bNgQ8e/Vq1dj4MCB2LFjB6699trw8uTkZOTl5cWzaSLqw5g7iKitc7rno76+HgCQlZUVsfyPf/wjsrOzcfHFF6OkpATNzfLI0uv1oqGhIeJFRH0bcwdR/9bpx6uHQiEsWLAAV199NS6++OLw8q9//esYOnQoBg0ahN27d+O//uu/sH//frz88ssxt1NaWorHH3+8s80gol6GuYOIOj34mDt3Lvbs2YN33nknYvn9998f/u9LLrkE+fn5uOGGG1BeXo4RI0ZEbaekpASLFi0K/7uhoQEFBQWdbRYR9XDMHUTUqcHHvHnz8Oqrr2LLli0YPHiw9r3jx48HABw8eDBmAnE4HHA45MmQiKjvYO4gIiDOwYdSCvPnz8f69euxefNmFBYWtrvOrl27AAD5+fmdaiAR9X7MHUTUVlyDj7lz52LNmjV45ZVXkJaWhpqaGgCAy+VCUlISysvLsWbNGkyfPh0DBgzA7t27sXDhQlx77bUYO3ZsXA1rqj8ZcyrrlsY6cZ1jVfKUyl6PV4wFA3LM79eUTPnlsi+lKU8za8qeAMBmk8uVYk0V3spi0UxFrZmmWzNrMgJBuVzQ45b7xuuVSwK9DZpSU7lLYU2TS/csmrI3pSmx9LvlGxqhKZVs8srHDgDQlMTpS1h154auDFdHLofUdngCGZ07LLboXMDc0ftzR6MmdyjNqZzSBbnDq8kdAU3uqG8nd+jKaYMh+fM1aXJHSHUud1itcu4whaI7XH92nrXteBqycuVKAGceBtTWqlWrMHv2bNjtdmzcuBHLly+H2+1GQUEBZs6ciR/84Afx7IaI+hjmDiJqK+6fXXQKCgpQVlZ2Tg0ior6HuYOI2uLcLkRERGQoDj6IiIjIUBx8EBERkaE4+CAiIiJDdfoJp12t5Uh57DoubclQJ0sYNTMzwqJZT1dnFqPUL7zJdmbqNGm2q5u5MKCZmbKpSS79CmlmioTSHb+mvzVldnDIxz9w0CAx5m6ql2N1p+X9+TRt0fSZ9pzxaUp0z2xYE9PffCnTFbJ1tkTXmFJbI9VWlsNsiU5tSvPdCWpm49TNCGp1aEoRNblD9x23a3JHe7P8Gp07dLPMhjS5w6zJHSFN7rB3Qe5o0OSOgCZ3KN1MwJrvY3M7uUP3WWhv3Nalak3Qpjm/LZrc0dwcPaOz7hw7G698EBERkaE4+CAiIiJDcfBBREREhuLgg4iIiAzFwQcREREZioMPIiIiMlSPLbUFWoQyz86WDWrqkPyablCamK66Maib7VJfauXXlbdqSgK1rJrjsMulfdDNaqgp+9LNBum0y21xJDnE2OmTcp+isUmOxZgdOcykGX9rPsP2Z5jVldPqThzd3wOabeqOMaSbYbfvsYQ8MJui+yMUlD+zkK5sUlOKGDTL57JZkzt0VfpezXkXaCd36MpbdeXEOlZN7rBpcodFkzusmtwRNDh3uDW5w6b5Xlk0ucPn1XyG7cwwqzTfc10ptVkzO68uVzut8jE2NdSJsWZ3dPmyimP2XF75ICIiIkNx8EFERESG4uCDiIiIDMXBBxERERmKgw8iIiIyFAcfREREZKgeXGrrR+ySxM7OCKpbTzfraSdLW3XjOl1ZJKCdERcOuZwMmlIrWNrZpyQkH7/ya0pRW+TyTp9NPoaWFrcY8zdpymm1ZdaaYw/qShc7e661R1dqq6P5fEO6suD+5cysqNElf7oZQZXSzCQakj8v5deUjOpmyhUjgEnzPQ628z22aHKHQ5M7LJp9mjX71H1DlCZ3BDW5I9gFucOtyR3aMmu7fOyeZjl3aM+1dv7k1xbpa0ptdetZNZ+v8smfxemTtWLM74v+nLSz7p6FVz6IiIjIUBx8EBERkaE4+CAiIiJDcfBBREREhuLgg4iIiAzFwQcREREZKq5S25UrV2LlypU4dOgQAGDMmDF47LHHMG3aNACAx+PBQw89hLVr18Lr9aK4uBjPP/88cnNzO9m8RJY66orb5NkXYdF0ka60VVdO217Zq0W3XV25pWZGQU05ma6cVltq7NXNliqXL4eaGuVNej2atnRy1uKQZptdUrrdHt1xaM7FGDO1hsUxm2R3MDJ3ePw+mIPRfaWbnVVpShgtmvXMmplbzZrcoZuB1KLJHbqy1/9bWQzpSniVJncENN+7oCZ3+DW5w+KRc4dfkx+Cmr5J0eQOXTmtWfPZe1s0uSPUuRwQiqMc9Wy6z8Jqk89Fi+a8OVV7TIz5vXL5cuxu66JS28GDB+OnP/0pduzYgQ8++ADXX389brvtNuzduxcAsHDhQvz973/HunXrUFZWhqqqKnzlK1+JZxdE1AcxdxBRWyYVz1NBYsjKysKyZctwxx13ICcnB2vWrMEdd9wBANi3bx8uvPBCbN26FVdeeWWHttfQ0ACXy3UuTRL08ysfOgZf+YA1SQylDRkmxhqPVsnbjPHAmy/o+qU7rnzo1tVd+dCci0r3sLTOq6+vR3p6epdsu6tyR86wkTDH+P7prnyENN+d/n7lQ3e2Gn3lw5mZKcZyNLnjuCZ3+DQPNVMBTe7o5JUPv7nzuUP3v2vdlY8kzTl8uvqIGKtvOC7GYl35UEoh4At1KG90+p6PYDCItWvXwu12Y8KECdixYwf8fj+mTJkSfs8FF1yAIUOGYOvWreJ2vF4vGhoaIl5E1HcxdxBR3IOPjz76CKmpqXA4HHjggQewfv16XHTRRaipqYHdbkdGRkbE+3Nzc1FTUyNur7S0FC6XK/wqKCiI+yCIqOdj7iCiVnEPPkaPHo1du3Zh+/btePDBBzFr1ix8/PHHnW5ASUkJ6uvrw6/KyspOb4uIei7mDiJqFffEcna7HSNHjgQAFBUV4f3338czzzyDr33ta/D5fKirq4v4C6a2thZ5eXni9hwOh3bCIyLqG5g7iKjVOc9qGwqF4PV6UVRUBJvNhk2bNmHmzJkAgP379+PIkSOYMGFCJ7ZsRuybRDU3XJk6eaOmbj0d3X1DupuRNDNoAgA0s2Hqy2k16ynNDaBdNnurICDf4NVUL99sBp/uGHyaWGdnkdWt11WlrZpzsYtuKu0uXZU7bHZnzBszY92EGl5HN6ur7kZNTe7Qzlzbydyhm30XgDZ3BDW5I6TJHQG//L3z+eTvXYvmptJgi3wuBzQ3gKZo2pnkGiBvU5M7/B75GHRluDq62WfbKwwI6v7XocnVKZqbjd0Np8VYQ0Odbociszl6+HCmfbpc/IW4Bh8lJSWYNm0ahgwZgsbGRqxZswabN2/G66+/DpfLhXvvvReLFi1CVlYW0tPTMX/+fEyYMKHDd6sTUd/E3EFEbcU1+Dh27Bi++c1vorq6Gi6XC2PHjsXrr7+OG2+8EQDwi1/8AmazGTNnzox4UBAR9W/MHUTU1jk/5yPRvnjORy/42UVHt832ruSZ+vjPLhqmAYPFmDp5SrOm7ieJ3vSzi1MT0z2ptWt05XM+Eq01dwwadXHcP7voflrpkp9dNDGzbpvnkDt0zzLpNT+7DBgoxgaNHC3GGjW5w+uW29IVP7sE2skdnf3ZJT1Zfn5SS2O9GDtRLd+orTT/37DEeI6NUgo+r69rn/NBRERE1BkcfBAREZGhzrnaJdG++BVIurykuybVyViX/OzQRY/f7lHHmHi6xzx3z6PQjdaz2trDfpXVam1rSKr40H49Ove9Uib5fO3szy7an3LO4WcXpamiEfusvZjm8eraR7ZrJkLUnXO6n46CmknXOnsM7Xe4tJq8Xqidn120hZKak7jTn5Pu/I4z1rqsI3mjxw0+GhtbSy0VYmeLzs5f0skGkbFOa+ZvMVx3/I/X2w37lDU2NnbRXEuJ15o7aso/6eaWUFfxVh8WY6c1sf5Ad0dcVwgG5Pt9OpI3etwNp6FQCFVVVUhLS4PJZEJDQwMKCgpQWVnZa258MwL7Rca+iS2eflFKobGxEYMGDdLecNmTtM0djY2NPAcE/H7Exn6RdbRv4skbPe7Kh9lsxuDB0RUP6enpPCFiYL/I2DexdbRfessVj1Ztc0frZW+eAzL2TWzsF1lH+qajeaN3/ElDREREfQYHH0RERGSoHj/4cDgcWLJkCSeQOgv7Rca+ia0/9Ut/OtZ4sW9iY7/IuqJvetwNp0RERNS39fgrH0RERNS3cPBBREREhuLgg4iIiAzFwQcREREZioMPIiIiMlSPHnysWLECw4YNg9PpxPjx4/Hvf/+7u5tkuC1btuDWW2/FoEGDYDKZ8Ne//jUirpTCY489hvz8fCQlJWHKlCk4cOBA9zTWQKWlpbj88suRlpaGgQMHYsaMGdi/f3/EezweD+bOnYsBAwYgNTUVM2fORG1tbTe12DgrV67E2LFjw08jnDBhAv75z3+G4/2hX5g7mDskzB2xGZ03euzg46WXXsKiRYuwZMkSfPjhhxg3bhyKi4tx7Nix7m6aodxuN8aNG4cVK1bEjD/11FP45S9/iV/96lfYvn07UlJSUFxcDI/HY3BLjVVWVoa5c+di27ZtePPNN+H3+zF16lS43e7wexYuXIi///3vWLduHcrKylBVVYWvfOUr3dhqYwwePBg//elPsWPHDnzwwQe4/vrrcdttt2Hv3r0A+n6/MHecwdwRG3NHbIbnDdVDXXHFFWru3LnhfweDQTVo0CBVWlraja3qXgDU+vXrw/8OhUIqLy9PLVu2LLysrq5OORwO9ac//akbWth9jh07pgCosrIypdSZfrDZbGrdunXh93zyyScKgNq6dWt3NbPbZGZmqt/+9rf9ol+YO6Ixd8iYO2RdmTd65JUPn8+HHTt2YMqUKeFlZrMZU6ZMwdatW7uxZT1LRUUFampqIvrJ5XJh/Pjx/a6f6uvrAQBZWVkAgB07dsDv90f0zQUXXIAhQ4b0q74JBoNYu3Yt3G43JkyY0Of7hbmjY5g7vsDcEc2IvNHjZrUFgBMnTiAYDCI3NzdieW5uLvbt29dNrep5ampqACBmP7XG+oNQKIQFCxbg6quvxsUXXwzgTN/Y7XZkZGREvLe/9M1HH32ECRMmwOPxIDU1FevXr8dFF12EXbt29el+Ye7oGOaOM5g7IhmZN3rk4IMoHnPnzsWePXvwzjvvdHdTeozRo0dj165dqK+vx5///GfMmjULZWVl3d0soh6FuSOSkXmjR/7skp2dDYvFEnUnbW1tLfLy8rqpVT1Pa1/0536aN28eXn31Vbz99tsYPHhweHleXh58Ph/q6uoi3t9f+sZut2PkyJEoKipCaWkpxo0bh2eeeabP9wtzR8cwdzB3xGJk3uiRgw+73Y6ioiJs2rQpvCwUCmHTpk2YMGFCN7asZyksLEReXl5EPzU0NGD79u19vp+UUpg3bx7Wr1+Pt956C4WFhRHxoqIi2Gy2iL7Zv38/jhw50uf7JpZQKASv19vn+4W5o2OYO5g7OqJL80Zi7olNvLVr1yqHw6FWr16tPv74Y3X//ferjIwMVVNT091NM1RjY6PauXOn2rlzpwKgfv7zn6udO3eqw4cPK6WU+ulPf6oyMjLUK6+8onbv3q1uu+02VVhYqFpaWrq55V3rwQcfVC6XS23evFlVV1eHX83NzeH3PPDAA2rIkCHqrbfeUh988IGaMGGCmjBhQje22hiPPPKIKisrUxUVFWr37t3qkUceUSaTSb3xxhtKqb7fL8wdZzB3xMbcEZvReaPHDj6UUurZZ59VQ4YMUXa7XV1xxRVq27Zt3d0kw7399tsKQNRr1qxZSqkzJXM//OEPVW5urnI4HOqGG25Q+/fv795GGyBWnwBQq1atCr+npaVFfec731GZmZkqOTlZ3X777aq6urr7Gm2Qb33rW2ro0KHKbrernJwcdcMNN4QTiFL9o1+YO5g7JMwdsRmdN0xKKdW5ayZERERE8euR93wQERFR38XBBxERERmKgw8iIiIyFAcfREREZCgOPoiIiMhQHHwQERGRoTj4ICIiIkNx8EFERESG4uCDiIiIDMXBBxERERmKgw8iIiIy1P8P7EWmzLpVliEAAAAASUVORK5CYII=", + "image/png": "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", "text/plain": [ "
" ] @@ -246,7 +245,7 @@ }, { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAh8AAAEjCAYAAACSDWOaAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/OQEPoAAAACXBIWXMAAA9hAAAPYQGoP6dpAABGiklEQVR4nO3deXSU9b0/8PfsM5nsOyELAWSRzRYBURRUBHE5YtFW23Mv2FqpBayitcZfq3Vp02qPYhVpbb1ge7T00lP01lpcUEKtQCvCRVEQMEBCyEpmkkwy+/P7g5tphpnPlyQkTybJ+3XOnCPzmWfmmWdm3n4zM5/5GDRN00BERESkE+NA7wARERENL1x8EBERka64+CAiIiJdcfFBREREuuLig4iIiHTFxQcRERHpiosPIiIi0hUXH0RERKQrLj6IiIhIV1x8DFKjRo3CsmXLIv/etm0bDAYDtm3b1me3YTAY8OMf/7jPrq8//Otf/8LFF18Mp9MJg8GAvXv3DvQuEQ2ooZwNy5YtQ3Jycp9f75NPPonRo0fDZDLhggsu6PPrp1hcfPTChg0bYDAYIie73Y5x48Zh5cqVqKurG+jd65E33ngj4RcYkkAggJtvvhmnTp3C008/jd///vcoKSnB888/jw0bNgz07sX4yU9+AoPBgMmTJw/0rlA/YTYMPm+99Rbuv/9+XHLJJVi/fj1++tOfDvQunVVrayvuv/9+lJaWwmazYeTIkbjpppvQ3t4+0LvWbeaB3oHB7NFHH0VpaSm8Xi/ef/99rFu3Dm+88QY++eQTJCUl6bovl112GTo6OmC1Wnu03RtvvIG1a9fGDZmOjg6YzYn7FDly5AiOHTuG3/zmN7j99tsj5z///PPIzs6O+utvoFVXV+OnP/0pnE7nQO8K6YDZMHi8++67MBqNePHFF3t8jAaC2+3G3LlzUV1djTvuuANjx45FQ0MD/v73v8Pn8+n+/OqtofHsGSCLFi3ChRdeCAC4/fbbkZWVhaeeegqvvfYabr311rjbeDyefvkfkNFohN1u79Pr7Ovr62v19fUAgPT09H6/rWAwiHA43Otwuu+++3DRRRchFAqhsbGxj/eOEg2zYfCor6+Hw+Hos4WHpmnwer1wOBx9cn1nKisrw7Fjx/DRRx+htLQ0cv4PfvCDfrm9/sKPXfrQFVdcAQCorKwE8O/PJ48cOYJrrrkGKSkp+MY3vgEACIfDWLNmDSZNmgS73Y68vDwsX74czc3NUdepaRoef/xxFBYWIikpCZdffjn2798fc9vS57q7du3CNddcg4yMDDidTkydOhXPPPNMZP/Wrl0LAFFvFXeK97nunj17sGjRIqSmpiI5ORlXXnkldu7cGXWZzree//GPf2D16tXIycmB0+nEjTfeiIaGhrMex3379mHZsmUYPXo07HY78vPz8c1vfhNNTU2Ryyxbtgxz584FANx8880wGAyYN28eRo0ahf3796OioiJyf+bNmxfZzuVy4e6770ZRURFsNhvGjh2Ln//85wiHw5HLHD16FAaDAb/4xS+wZs0ajBkzBjabDZ9++ikA4MCBAzh+/PhZ70en7du3409/+hPWrFnT7W1oaGE2nHau2dDpiy++wMKFC+F0OlFQUIBHH30UZw5o785xNBgMWL9+PTweT+Q+dn5kGwwG8dhjj0Ve/6NGjcKDDz4In88XdTujRo3CddddhzfffBMXXnghHA4Hfv3rXwPoXt4AwMmTJ3HgwAEEAgHl/Xa5XFi/fj3uuOMOlJaWwu/3x+zPYMF3PvrQkSNHAABZWVmR84LBIBYuXIg5c+bgF7/4ReQtseXLl2PDhg247bbbcNddd6GyshLPPfcc9uzZg3/84x+wWCwAgIceegiPP/44rrnmGlxzzTX46KOPsGDBAvj9/rPuz9tvv43rrrsOI0aMwPe+9z3k5+fjs88+w+uvv47vfe97WL58OWpqavD222/j97///Vmvb//+/bj00kuRmpqK+++/HxaLBb/+9a8xb948VFRUYNasWVGXX7VqFTIyMvDwww/j6NGjWLNmDVauXIk//vGPZ93vL774Arfddhvy8/Oxf/9+vPDCC9i/fz927twJg8GA5cuXY+TIkfjpT3+Ku+66CzNmzEBeXh48Hg9WrVqF5ORk/L//9/8AAHl5eQCA9vZ2zJ07FydOnMDy5ctRXFyMDz74AGVlZTh58mTM4mD9+vXwer244447YLPZkJmZCQCYOHEi5s6d260v8IVCIaxatQq33347pkyZctbL09DEbOibbABOv6auvvpqXHTRRXjiiSewZcsWPPzwwwgGg3j00Ucjl+vOcfz973+PF154Af/85z/x29/+FgBw8cUXAzj9jtVLL72Em266Cffeey927dqF8vJyfPbZZ9i8eXPUPh08eBC33norli9fjm9/+9sYP358j/KmrKwML730EiorKzFq1Cjxvr///vvwer0YO3YsbrrpJrz66qsIh8OYPXs21q5dO7i+LKtRj61fv14DoL3zzjtaQ0ODVlVVpW3cuFHLysrSHA6HVl1drWmapi1dulQDoD3wwANR2//973/XAGgvv/xy1PlbtmyJOr++vl6zWq3atddeq4XD4cjlHnzwQQ2AtnTp0sh57733ngZAe++99zRN07RgMKiVlpZqJSUlWnNzc9TtdL2uFStWaNLTAID28MMPR/69ePFizWq1akeOHImcV1NTo6WkpGiXXXZZzPGZP39+1G3dc889mslk0lwuV9zb69Te3h5z3h/+8AcNgLZ9+/aY+7xp06aoy06aNEmbO3duzHU89thjmtPp1D7//POo8x944AHNZDJpx48f1zRN0yorKzUAWmpqqlZfXx9zPQDiXn88zz33nJaWlha5nrlz52qTJk3q1rY0+DAb+jcbOo/bqlWrovb52muv1axWq9bQ0KBpWvePY+d1Op3OqMvt3btXA6DdfvvtUeffd999GgDt3XffjZxXUlKiAdC2bNkSddnu5k3X+1VZWam8/0899ZQGQMvKytJmzpypvfzyy9rzzz+v5eXlaRkZGVpNTY1y+0TCj13Owfz585GTk4OioiLccsstSE5OxubNmzFy5Mioy915551R/960aRPS0tJw1VVXobGxMXKaPn06kpOT8d577wEA3nnnHfj9fqxatSrqLc+77777rPu2Z88eVFZW4u677475TkTX6+quUCiEt956C4sXL8bo0aMj548YMQJf//rX8f7776OlpSVqmzvuuCPqti699FKEQiEcO3ZMeVtdPyv1er1obGzERRddBAD46KOPerzvnTZt2oRLL70UGRkZUcd9/vz5CIVC2L59e9TllyxZgpycnJjr0TStW+96NDU14aGHHsKPfvSjuNdDQxezoX+yodPKlSuj9nnlypXw+/145513AHT/OEreeOMNAMDq1aujzr/33nsBAH/961+jzi8tLcXChQujzutJ3mzYsAGapinf9QCAtra2yH3eunUrvv71r+POO+/Eq6++iubm5shHZYMBP3Y5B2vXrsW4ceNgNpuRl5eH8ePHw2iMXs+ZzWYUFhZGnXfo0CG43W7k5ubGvd7OL1J2vhDPO++8qHpOTg4yMjKU+9b5Nm9ftXU2NDSgvb0d48ePj6lNnDgR4XAYVVVVmDRpUuT84uLiqMt17vOZn12f6dSpU3jkkUewcePGyLHo5Ha7e3sXcOjQIezbt09cCJx5W12/zNUbP/zhD5GZmYlVq1ad0/XQ4MNsOK2vswE4/QXaroscABg3bhyA09/XArp/HCXHjh2D0WjE2LFjo87Pz89Henp6zCIpXlb0NG+6o/MPs+uvvz7q904uuugilJaW4oMPPujxdQ4ULj7OwcyZMyPfaJfYbLaY0AmHw8jNzcXLL78cd5uh8leyyWSKe752xhfDzvTVr34VH3zwAb7//e/jggsuQHJyMsLhMK6++uqYL2r1RDgcxlVXXYX7778/br0zwDqdy7fVDx06hBdeeAFr1qxBTU1N5Hyv14tAIICjR48iNTU18j0SGlqYDWq9zYbu6qvj2N13guJlRU/zpjsKCgoA/Pt7bF3l5uZ2a/GWKLj4GABjxozBO++8g0suuUT5P7iSkhIAp/9H1nWl39DQcNYn2ZgxYwAAn3zyCebPny9errsvrpycHCQlJeHgwYMxtQMHDsBoNKKoqKhb16XS3NyMrVu34pFHHsFDDz0UOf/QoUPdvg7pPo0ZMwZtbW3K49FXTpw4gXA4jLvuugt33XVXTL20tBTf+9732AFDUZgNZxcOh/HFF19E/c/7888/B4DIxxbdPY6SkpIShMNhHDp0CBMnToycX1dXB5fLFTn+Kv2RN9OnTwdwOl/OVFNTgwkTJvTZbfU3fudjAHz1q19FKBTCY489FlMLBoNwuVwATn9ubLFY8Oyzz0b9RdCd/2F9+ctfRmlpKdasWRO5vk5dr6vzdwXOvMyZTCYTFixYgNdeey3y1iZw+sX4yiuvYM6cOUhNTT3rfp1N519EZ/4F1JP/STudzrj356tf/Sp27NiBN998M6bmcrkQDAa7df3dabWdPHkyNm/eHHOaNGkSiouLsXnzZnzrW9/q1u3R8MFs6J7nnnsuap+fe+45WCwWXHnllQC6fxwl11xzDYDY4/nUU08BAK699tqz7mNP8qa7rbbjx4/HtGnT8Nprr0X9XtBbb72FqqoqXHXVVWfdr0TBdz4GwNy5c7F8+XKUl5dj7969WLBgASwWCw4dOoRNmzbhmWeewU033YScnBzcd999KC8vx3XXXYdrrrkGe/bswd/+9jdkZ2crb8NoNGLdunW4/vrrccEFF+C2227DiBEjcODAAezfvz/yguhcSd91111YuHAhTCYTbrnllrjX+fjjj+Ptt9/GnDlz8N3vfhdmsxm//vWv4fP58MQTT/TJsUlNTcVll12GJ554AoFAACNHjsRbb70V+X2E7pg+fTrWrVuHxx9/HGPHjkVubi6uuOIKfP/738f//M//4LrrrsOyZcswffp0eDwefPzxx/jTn/6Eo0ePnvW4At1rtc3OzsbixYtjzu8Ms3g1ImbD2dntdmzZsgVLly7FrFmz8Le//Q1//etf8eCDD0Y+TunucZRMmzYNS5cuxQsvvACXy4W5c+fin//8J1566SUsXrwYl19++Vn3syd5091WWwB4+umncdVVV2HOnDlYvnw53G43nnrqKYwbNy7mC8wJbaDabAazznaxf/3rX8rLxWvh6uqFF17Qpk+frjkcDi0lJUWbMmWKdv/990e1S4VCIe2RRx7RRowYoTkcDm3evHnaJ598opWUlCjb6Tq9//772lVXXaWlpKRoTqdTmzp1qvbss89G6sFgUFu1apWWk5OjGQyGqNY6nNFOp2ma9tFHH2kLFy7UkpOTtaSkJO3yyy/XPvjgg24dH2kfz1RdXa3deOONWnp6upaWlqbdfPPNWk1NTcz+SK22tbW12rXXXqulpKTEtMW2trZqZWVl2tixYzWr1aplZ2drF198sfaLX/xC8/v9mqb9u9X2ySefjLt/Z15nT7DVdmhjNvRvNnQetyNHjmgLFizQkpKStLy8PO3hhx/WQqFQr46j9FgEAgHtkUce0UpLSzWLxaIVFRVpZWVlmtfrjbpcSUmJdu2118bd3+7kTec+oButtp3efvtt7aKLLtLsdruWmZmp/cd//Id28uTJbm2bKAya1kff8CEiIiLqBn7ng4iIiHTFxQcRERHpiosPIiIi0hUXH0RERKQrLj6IiIhIV1x8EBERka767UfG1q5diyeffBK1tbWYNm0ann32WcycOfOs24XDYdTU1CAlJaVXExaJ6NxpmobW1lYUFBTEzB/pT73NDYDZQTTQepQb/fHjIRs3btSsVqv2X//1X9r+/fu1b3/721p6erpWV1d31m2rqqo0ADzxxFMCnKqqqvojIuI6l9zQNGYHTzwlyqk7udEvPzI2a9YszJgxI/L7++FwGEVFRVi1ahUeeOAB5bZutxvp6elY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", + "image/png": "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46KLLsIjjzyCdevWYenSpYjFYnjwwQfb7ted/fj73/8eTz/9NP75z3/it7/9LQDg4osvBnDsE6tnn30WN910E+6++268/fbbKCkpwYcffoi1a9d22Ka9e/fi1ltvxdy5c/Htb38bY8eO7VG9WbJkCZ599lmUlpZi5MiR4nN/8803EQqFMHr0aNx000144YUXkEgkMHHiRCxfvvzkOlnWUI+tXLnSADDr1683VVVVpqyszKxevdpkZ2cbn89nDh06ZIwxZvbs2QaAuffeezss//e//90AMM8991yH29etW9fh9iNHjhi3222uvfZak0gk2u533333GQBm9uzZbbe98cYbBoB54403jDHGxGIxU1xcbIqKikxtbW2Hx2m/rnnz5hnpMABgli5d2vbvmTNnGrfbbfbv39922+HDh01aWpq57LLLOu2fqVOndnisu+66yzgcDlNXV5f08Vo1Nzd3uu0Pf/iDAWA2b97c6TmvWbOmw33POussM3ny5E7reOihh0xKSor56KOPOtx+7733GofDYQ4ePGiMMaa0tNQAMOnp6ebIkSOd1gMg6fqPd84555gxY8aYWCzWdls4HDYjRowwAMyf/vSnLtdBJxfWhhNbG1r324IFCzps87XXXmvcbrepqqoyxnR/P7auMyUlpcP9tm/fbgCYb33rWx1uv+eeewwA8/rrr7fdVlRUZACYdevWdbhvd+tN++dVWlqqPv/HHnvMADDZ2dnmwgsvNM8995x56qmnTH5+vsnMzDSHDx9Wlx9I+LXL5zB16lTk5uaisLAQt9xyC1JTU7F27VoMGzasw/3uvPPODv9es2YNAoEArrrqKlRXV7f9jB8/HqmpqXjjjTcAAOvXr0ckEsGCBQs6fOS5cOHCLrft/fffR2lpKRYuXNjpnIj26+queDyOV199FTNnzsRpp53WdvuQIUPw1a9+FW+++Sbq6+s7LHP77bd3eKxLL70U8XgcBw4cUB+r/acFoVAI1dXVbZ8QvPfeez3e9lZr1qzBpZdeiszMzA77ferUqYjH49i8eXOH+8+aNQu5ubmd1mOM6VZs8Tvf+Q4++ugjfPOb38Tu3buxc+dOfP3rX0d5eTmAYyft0eDE2nBiakOr+fPnd9jm+fPnIxKJYP369QC6vx8lL7/8MgBg0aJFHW6/++67AQB//etfO9xeXFyM6dOnd7itJ/Vm1apVMMaon3oAaPuq1mazYcOGDfjqV7+KO++8Ey+88AJqa2vbvio7GfBrl89h+fLlGDNmDJxOJ/Lz8zF27FjY7R3nc06nE8OHD+9w2759+xAMBpGXl5d0va0nUra+EU8//fQO47m5ucjMzFS3rfVj3rPPPrv7T0hRVVWF5ubmpAmNM888E4lEAmVlZTjrrLPabh8xYkSH+7Vu8/HfXR/v6NGjeOCBB7B69eq2fdEqGAz29ilg37592LFjR9IJBYBOj9X+ZK7euOOOO1BWVoZHH30Uzz77LADg/PPPx+LFi/HjH//4hFyvgAYG1oZj+ro2AMdOoG0/yQGAMWPGADh2vhbQ/f0oOXDgAOx2O0aPHt3h9oKCAmRkZHSaJCWrFT2tN93R+ofZ9ddf36F+XHTRRSguLsZbb73V43X2F04+PocLL7yw7Yx2icfj6VR0EokE8vLy8NxzzyVdRjpYTzYOhyPp7ea4E8OO9+UvfxlvvfUWvv/97+O8885DamoqEokErr766k4navVEIpHAVVddhcWLFycdby1grfribPUf//jHuOeee7Br1y4EAgGcc845uO+++5I+Hg0erA263taG7uqr/djdT4KS1Yqe1pvuGDp0KIB/ncfWXl5eXrcmbwMFJx/9YNSoUVi/fj0uueQS9RdcUVERgGMz6PYz/aqqqi4PslGjRgEAdu7cialTp4r36+6bKzc3F36/H3v37u00tmfPHtjtdhQWFnZrXZra2lps2LABDzzwAO6///622/ft29ftdUjPadSoUWhsbFT3x4mQmZmJSZMmtf17/fr1GD58OM444wxLt4MGPtaGriUSCXzyyScdfnl/9NFHAND2tUV396OkqKgIiUQC+/btw5lnntl2e2VlJerq6tr2v+ZE1Jvx48cDAD777LNOY4cPHz6pagrP+egHX/7ylxGPx/HQQw91GovFYqirqwNw7Htjl8uFJ598ssNfBMenMpL54he/iOLiYixbtqxtfa3ar6v1ugLH3+d4DocD06ZNw4svvtj20SZw7M34/PPPY9KkSUhPT+9yu7rS+hfR8X8Bdec5t0pJSUn6fL785S9jy5YteOWVVzqN1dXVIRaLdWv93Y3aJvPHP/4R77zzDhYuXNjpr14i1obu+eUvf9lhm3/5y1/C5XLhyiuvBND9/Si55pprAHTen4899hgA4Nprr+1yG3tSb7obtR07dizGjRuHF198EdXV1W23v/rqqygrK8NVV13V5XYNFPzkox9MnjwZc+fORUlJCbZv345p06bB5XJh3759WLNmDZ544gncdNNNyM3NxT333IOSkhJcd911uOaaa/D+++/jb3/7G3JyctTHsNvtWLFiBa6//nqcd955uO222zBkyBDs2bMHu3btantDtM6kv/vd72L69OlwOBy45ZZbkq7z4YcfxmuvvYZJkybhO9/5DpxOJ379618jHA7jkUce6ZN9k56ejssuuwyPPPIIotEohg0bhldffbXt+gjdMX78eKxYsQIPP/wwRo8ejby8PFxxxRX4/ve/j//5n//Bddddhzlz5mD8+PFoamrCBx98gD/96U/49NNPu9yvQPejtps3b8aDDz6IadOmITs7G1u3bsXKlStx9dVX43vf+163nw+dOlgbuub1erFu3TrMnj0bEyZMwN/+9jf89a9/xX333df2dUp396Nk3LhxmD17Np5++mnU1dW1XZX42WefxcyZM3H55Zd3uZ09qTfdjdoCwOOPP46rrroKkyZNwty5cxEMBvHYY49hzJgxnU5gHtD6K2ZzMmuNi73zzjvq/ZJFuNp7+umnzfjx443P5zNpaWnmnHPOMYsXL+4Ql4rH4+aBBx4wQ4YMMT6fz0yZMsXs3LnTFBUVqXG6Vm+++aa56qqrTFpamklJSTHnnnuuefLJJ9vGY7GYWbBggcnNzTU2m61DtA7HxemMMea9994z06dPN6mpqcbv95vLL7/cvPXWW93aP9I2Hu/QoUPmxhtvNBkZGSYQCJibb77ZHD58uNP2SFHbiooKc+2115q0tLROsdiGhgazZMkSM3r0aON2u01OTo65+OKLzc9//nMTiUSMMf+K2j766KNJt+/4dUo+/vhjM23aNJOTk2M8Ho8544wzTElJiQmHw10uSycn1oYTWxta99v+/fvNtGnTjN/vN/n5+Wbp0qUmHo/3aj9Kr0U0GjUPPPCAKS4uNi6XyxQWFpolS5aYUCjU4X5FRUXm2muvTbq93ak3rduAbkRtW7322mvmoosuMl6v12RlZZl///d/N+Xl5d1adqCwGdNHZ/gQERERdQO/dCYiIiJLcfJBREREluLkg4iIiCzFyQcRERFZipMPIiIishQnH0RERGSpE3aRseXLl+PRRx9FRUUFxo0bhyeffBIXXnhhl8slEgkcPnwYaWlpveqwSESfnzEGDQ0NGDp0qKVXYu1t3QBYO4j6W4/qxom4eMjq1auN2+02//mf/2l27dplvv3tb5uMjAxTWVnZ5bJlZWUGAH/4w58B8FNWVnYiSkRSn6duGMPawR/+DJSf7tSNE3KRsQkTJuCCCy5ou/5+IpFAYWEhFixYgHvvvVddNhgMIiMjAyu/fhH87s4fzHx09Ki47D92d2620yrF7xXHvjiyQBwLROXdYxqbxLEo5O6rrjR5WwCoM8aGBvkx3W63stLkXSQBoD4UlseUXgNxl0cc86bKl3iubZZ7qFQerRHH0CRvS5pDee7KH8FRm/z6tsQi4phHOZ4AIBaT15uIxMWxFLe8T3OUVumHqqrFsaao/Hg2JN/OWDyB9fvLUFdXh0AgIC7flz5P3QDa1Y47ZsDvcXUa/6iqSlz2HztLxbEUn18c++KoYeJYwMjvY9PcIo5Fjfx6uVI+T+1oFMfcHu39o9SOlpA8FpbrStwpP543NUscq22S35OV1fLri5Bcc9Kcyj5VakdMqfHNMfm5e7x6o7tYTF5vIqbVDvl55GTK+/RQ1RFxrCki19xkuyYWj2P9h/u7VTf6/GuXSCSCbdu2YcmSJW232e12TJ06FVu2bOl0/3A4jHC7g7ShoQEA4Hc7k04+vC75jeByyEeKyyG/KbV1+oTiDADGKS+n7ViX8niAXkCiTnnMo61XmXxEYvI6w0oBjSvP3+OS94C78++FNtrrBGXMLbToBqAWEJtNfqPHlOfu0h4PgE2Z0ycc8pj2PDxOeZ9q2+NKyI8nTT7axi36+qKndQNQaofHlXTy4U1ST1ppx51Lec9p6/Rpk4+ovJxTeUlcyuMBXdQOpT5o71e9dshj4YQ81vvaofxRp6wT2ntOW045/O3KYNQo70ft8QDYlPUqb2X1eWj7VK0dDnl/a5WhO3Wjz7/Mra6uRjweR35+fofb8/PzUVFR0en+JSUlCAQCbT992XqZiE4OPa0bAGsH0cms39MuS5YsQTAYbPspKyvr700iopMAawfRyavPv3bJycmBw+FAZWVlh9srKytRUND53AqPxwOPR/6em4gGv57WDYC1g+hk1ueTD7fbjfHjx2PDhg2YOXMmgGMnjm3YsAHz58/v9nocqQE4k3xvG/lMPql0/Jjh4lhWRoo4lmaTT+JBUB4zKaniWEaKfFJRIt4sPx6AeFx+TJ9b/n7OBnm5WIt8glu6drKmcj5Ik3LSnMNWL47ZQvJJYy7lHIywcn5CVPmO0aWd16Ccm+Ey8jobjwbldQJIKCeNBdLk4ybZuQqtbAl5nSnKCYNOl7zOhEm+zqhyDJ4IfVU3AMCZkgaXt/P+iBw8KC4z/oyR4lhWhvx6pWlf3zcqtUM5iVWvHfJ7Duiidnjkcq+e+6SckJ6uHFtQtqUpLNcAh0M+qd4Wkk9wdSuf44e02iEvBuXZ6bVD+VKhsbaL2hHXakeaOOZXaoBNeJ8DQIpXnsBrtcMkWWdUOSG207q7fc8eWLRoEWbPno3zzz8fF154IZYtW4ampibcdtttJ+LhiGgQYN0gOnWckMnHV77yFVRVVeH+++9HRUUFzjvvPKxbt67TyWRERK1YN4hOHSfsCqfz58/v8celRHRqY90gOjX0e9qFiIiITi2cfBAREZGlOPkgIiIiS52wcz4+r4TDibij8+ZlB+Rr1BcMkfuJRMJyX4NIUI6FNobl2JfDI8ee4srlmhPK9fIBwKteu0COMsVjcv8CuxY1C8nP0a9cJli56jTcNnlbonb5+R9RtqVJTvzBYZMjYdolqf0uOdboVC47nNbVa6hcztiuXXpYie+FlX3jUHrU2OPytjptwovY9y2fLBO3OxBLcknw7AytduSKYxGlBkTqG8SxxrAcqXe45eh/3K5cXjsiv6+ArmqHHLdUa4fWGyksR3/9ygW4nUrxcCuXQo865edQpezvppBcN9XaoUTffUrtSNNqh6+L2qH0n+h97VCORe0S8gntuOj8GvakavCTDyIiIrIUJx9ERERkKU4+iIiIyFKcfBAREZGlOPkgIiIiS3HyQURERJYasFHbaCKGaKJzBigvP3l7bQDwepTOpg6vOJZoUjpFKt0efT559xkj50KdWrYJgE/pMhiPyTEtt1OOd7mVdTbWyzHkeFzp3OiRO3M2BGvFsTS7POe1xeTXoqFJjsvZlEPZZXrXKdbpkrtEZnjlmB2gd5mNKfG1uNJ9sq5BjoTHovJyGanp4phNeC3CPehOOdBE4zFE452fl1475GNSrR3NcpdVvXZo3ULljq/9Ujt88vNvbOhl7XDL75+G+jpxLM0ur9MWl2tuQ5P8Oqm1Q4kn25Roq1o7/HLdBIAUJS4dV2pHTKsd9VrtkN/rGany5STsSWpHWIlsd1q+2/ckIiIi6gOcfBAREZGlOPkgIiIiS3HyQURERJbi5IOIiIgsxckHERERWWrARm2RiApNGOUYUm19UBxzueUoWSQux9d8PvnxUn3yckZJxDmccnQNAIzShTTVLy+rNTyMReUIq9sv75tQs9KBMSGP5aXLcTKX8vyKhspxyJqY/PpGInLMTGmuCaPE5Rpq5Xhawq1ELAF40lLFMbtLnvMrTYThUbrzGiPH5ZxKPNEhjBllmQHPxACTbB/L8dbaoNydVq8d8mb4lIhqqvKeM0pvUEdcj3gbJYqZmiIvq9cO+Vh3K5cbCDXLkWEYeTvzAvJ7xxWV47RFw4aIY9XhKnEsokRNtdqhdZFtqFNqh0dpzw3Aky7HWx1KN2DlCgZd1A55Oa1zebLG7YkefJzBTz6IiIjIUpx8EBERkaU4+SAiIiJLcfJBREREluLkg4iIiCzFyQcRERFZasBGbd0+P9zeztG4cESeL1VWNYljQ/MyxTGPEl+Na136ehlRsilRSwCAXe6ICCVSqXWE1bJ0bqXDZEuLHIutj8iPl5kTEMeyjRxfTtjlmF3cLr9O1VVyVLIwU37tXS75LXC0qk5eTol8A0BM6SBqtylRW+XvAZ9bfv5el/z6JhJKd1GH8Py1rPgA5/b54PZ2fg+FI/JzqqyUj5+h+VnimEeJ08bjSoRTqx1K51qblokFALscJ1Zrh9IRVq8d8vNvaZGjtvWhZnEsM0/e39kJuTaadPk9GbPJy1VXybHYwuxsccyt1I4arXYo2wLotSOh1AeTLPv6f3wepXa4e1c73M7Ox5qtB3Wjzz/5+NGPfgSbzdbh54wzzujrhyGiQYR1g+jUckI++TjrrLOwfv36fz2Ic8B+wEJEAwTrBtGp44S8u51OJwoK5CtVEhEdj3WD6NRxQk443bdvH4YOHYrTTjsNX/va13Dw4EHxvuFwGPX19R1+iOjU05O6AbB2EJ3M+nzyMWHCBKxatQrr1q3DihUrUFpaiksvvRQNDclP6CopKUEgEGj7KSws7OtNIqIBrqd1A2DtIDqZ9fnkY8aMGbj55ptx7rnnYvr06Xj55ZdRV1eH//qv/0p6/yVLliAYDLb9lJWV9fUmEdEA19O6AbB2EJ3MTvgZXRkZGRgzZgw+/vjjpOMejwceT+eIlD8jGylJ4nLlpfJHsZGE/HS8XrnLajwsd200KfJySMixopjSfdHnV+JwAGIOOTLmhhyXSyhdfd2uFPkBHUqHTTn5ikhI/qs0qMTFPErr1iy/HO0aPyxdHKv1Kc9B6XibcMnb2aKMRaJK+1kAsMvHRlOTHAm3K6+FTzkW7VJkFoDDKa/TJQzF+7mpbVd1A1BqR3oWUpJ0oy4vPSCuK6K041RrR1SOk/a+dsjr9Pm7iGkqMX23TXkfNDbKy7mV56EcW0qyF5Fm+SuyYESunR6bfJxneeXXcHxRjjhWmybHUE1UfiMYpzzW7JafvNpFF1Cjzb2uHX6tdsjLabUjWSQ8phzXnR632/fspcbGRuzfvx9DhsjtjomI2mPdIBrc+nzycc8992DTpk349NNP8dZbb+HGG2+Ew+HArbfe2tcPRUSDBOsG0amlz792OXToEG699VbU1NQgNzcXkyZNwtatW5Gbm9vXD0VEgwTrBtGppc8nH6tXr+7rVRLRIMe6QXRqYWM5IiIishQnH0RERGSpAds8IRRNwOHoHA07cFDO8hcVjRTHwi1ynNaekCNodiX2ZIy8nM8vd4p1evWYponIES6tl6pN6WgZhRLti8nRrxSXHN0LG/k5JpRInFGixC4jz4edSgTPoezT0qNH5MdLlyNoWvPJUFjpIAzAYeSFG1rkZZNFR1u5lS6pSvNJuFzycREXMrWJ/s7afg7haBxOZ+d9dUC5YupJUzs8n6N2KNtjc8jHa69rh1s+lsMJ+X2XsCnxXa12KH9LO5Tu5A4lvlz6WYU45k6VXyebcjWFUKiL2pGQF25olrsBq7VDGUsYpeu1Wjs6H8OJJLdJ+MkHERERWYqTDyIiIrIUJx9ERERkKU4+iIiIyFKcfBAREZGlOPkgIiIiSw3YqO1nhyrh83SO+RTkyY2mHJAjQ02NckQp1SHPwRIJubOp1BEUAGJGiXZ1sdsdRu5qGW6Qu0+6lJhTIsm+bNUckaNf8YjS2VWJaEWUqG2Dss6AR34Ofrs8luaTY29ZuZnyOnMyxLEWZ604drRF7ugLAHEl2peRJW+PFpczyv522pV4orLcYHToswr4PJ3jk3rtkKm1w6XVDvkYcCXpCNoqpizXZe2AvGy4QX4eLiUynHDLj9nr2qHUqojyHBuicuw54JVrnF95gdXakSO/V1OyA+JYs71GHDvaXCdvDE6d2sFPPoiIiMhSnHwQERGRpTj5ICIiIktx8kFERESW4uSDiIiILMXJBxEREVmKkw8iIiKy1IC9zkfC7kYiSYt4u13OQDfWBcWxvPRUccythfwd8qALco69oVG+Hkesi+h0qlO+BoA/PUUci8q7Bg02uYV1OC63lE5AbmPvS5Hz8fGonOOvr64Wx6L18nUD8lPl5+6Iy/Nol8srj/nkdXrlGD9aDuvX+fA55WsOuLzy/oZdfu0TCfnAsSnXqomG5evGOJTj+2RlbC6YJD3NHVrtCCq1I5AujrmV9yocyjWCbHIrer126MUjVbn4kF475PU2xOVjOezWrnMiH3e+9CxxLB6RX6f6avn6GdGgfA2Q/PQ0ccwRl19DtXZ45ZrqTZefQ8sh+fpBQBe1I8n1a9qcZLWDn3wQERGRpTj5ICIiIktx8kFERESW4uSDiIiILMXJBxEREVmKkw8iIiKyVI+jtps3b8ajjz6Kbdu2oby8HGvXrsXMmTPbxo0xWLp0KX7zm9+grq4Ol1xyCVasWIHTTz+9R49z9Gg9vElaOR8p2y8uM+7M0eKY1y1HpmJhudW0X2knjbgcQ8oIyNEu2ORtAQC3Td6esJEjXEGlNXKNXYmpOuVWzL40Ob6VNaRAHHM1VIljzUpb7IYqOdrrknc3WmxytDfmkONpdfXy49U2yVHJKiUSDADD0+XHbGhuEscSSmtzl0t+nZIkS9u4XfKglM5TUnu9YlXdAICao0F43Z2f85FDpeIy474wRhxTa4fSUt7vUV6UuNI2Xa0d8jEAAG67fDyrtUM+7FADpXb45W31pch/22YV5ItjrgY5TtscUWpH9VF5nSE52txi5Pd5zC7X/7p6eVtqG+XXoSoov/8BYHiGXDsaldoRV2uHvE6bkt7Wa0fnIpHsNnH5bt/z/zQ1NWHcuHFYvnx50vFHHnkEv/jFL/CrX/0Kb7/9NlJSUjB9+nSEQvILRUSDG+sGEbXX408+ZsyYgRkzZiQdM8Zg2bJl+I//+A/ccMMNAIDf/e53yM/PxwsvvIBbbrnl820tEZ2UWDeIqL0+PeejtLQUFRUVmDp1atttgUAAEyZMwJYtW5IuEw6HUV9f3+GHiE4dvakbAGsH0cmsTycfFRUVAID8/I7f5+Xn57eNHa+kpASBQKDtp7CwsC83iYgGuN7UDYC1g+hk1u9plyVLliAYDLb9lJWV9fcmEdFJgLWD6OTVp5OPgoJj6YfKysoOt1dWVraNHc/j8SA9Pb3DDxGdOnpTNwDWDqKTWZ92tS0uLkZBQQE2bNiA8847DwBQX1+Pt99+G3feeWeP1vX65q1wJsn7DcuUY2+BVDn2VX1cYWuvuVH+rnhEYa44lu6Tt0VpIgiT0Hf7UeW765jS1NCZXySOFY64QBxrrpNjYYf3fSJvS0iOdqUpr4UnVe6GW98gd4pM+DPEsZCR59HxqJzRramSu9Pu3H9Qfry43tFRaeoLt12Z8yvHTczIccFYTI5ROowcf5MitVrkt6/1Zd0AgDc2vwVnkn08NEuOjAbSlNpx5Ig41twoHz8jCvPEsXS/XDu0xrWJLmuHvK0xJfnrzBkqjhUOPU8caw4qtWO/HG2OKTH2NL/8OnmUTtr1DUo99smvr1475O08ekTuhLxzn/zcQzE9jhrVOtBqGXgl5hpLnIja0XmsJ3Wjx5OPxsZGfPzxx23/Li0txfbt25GVlYURI0Zg4cKFePjhh3H66aejuLgYP/zhDzF06NAOmX4iOrWwbhBRez2efLz77ru4/PLL2/69aNEiAMDs2bOxatUqLF68GE1NTbj99ttRV1eHSZMmYd26dfB69QtrEdHgxbpBRO31ePIxZcoUGOVzQZvNhgcffBAPPvjg59owIho8WDeIqL1+T7sQERHRqYWTDyIiIrIUJx9ERERkqT6N2valD480J40BDi8aIS6TGUgVxxxxuftkyuhicSw9XV5nQ73cRTEckiNo8bgeR6qOKF1mU+TIWEamHJdLVZZrrqoWx5wOuYvi+9vkizrV1MiRv5FDM8WxsJHzgE63vF/SU5TXSel2Wdskv04Jmxz5SyixVwCoaJKPtwyPPOf3Kd15AS0rKe8b7XhLCOdhhGP68xvIdpcdTVo7ho3Qaof8/nAk5GMkZVRva0etOKbWji6ijNUhOQLu88rbk5EhX08lNVW+fkpzzafimNMhNwV8/73t4lhNjdwRe+SwbHEsHJffV06H/KtOrR018utU2yKfw5SAHAlOKF10AaCiQa65GV75efi0jxKM8qvepUSN1drR+XmEldju8fjJBxEREVmKkw8iIiKyFCcfREREZClOPoiIiMhSnHwQERGRpTj5ICIiIksN2KhtXiAdjiR5OY9Xjj9W1MgdJl2Qu/OlZmaIY+GIHIsyTjlO5VK6VtY2yjFUAAhDbl1bkDtcHHM75Y6wwTK5y2KkWo7MZnjl/XbG6NPEsf9VukFmDysUx6ToJwBEInIE0ZUmHxctVTXiWH1I7ngbUVJj4UgXUVSl+6RfibF6HHK0zW6Xj4twVF5nVBlzOJNHM8Pxkzdqm5edBUeSrrYer/z+qKyWO5S6lEaiqRkBcUytHQ45Gu3yya9zbUMXtUOJVBYonWvdSi0LfiZ3d44cLRfHMnxy7PeM0aPEsf9V9lv2ELn+aZfvD2u1I1U+LlqUyxDUt8jrjMS0bekijqp0vfYrUVaPU+lAa5dj+uGovM5oTK5HyWpHTyL6/OSDiIiILMXJBxEREVmKkw8iIiKyFCcfREREZClOPoiIiMhSnHwQERGRpQZs1PbiscVwJ4nypHnlCOt72/eJY184XY5oxSJynEiLKYZa5JimxydH17xKl0gAKEiX43tZWTniWFSJt9YfOiCOxRvlzo2B7HxxLKdI3qc5w+Tl0gLya1hfXy+Oud1yBLGmQu6EaXPKc2yXV448wqFE3tLkeB4A2CHH15wuOYaXmiJH4lpC8nEaUWKGWmdK6dEiJ3HU9uKzTofb2bm0pfnl12zb9r3i2BfGyN1w8y2vHXL3XQAoSJNrS69rx2E5ahtvkiPKgew8cSwnX47b5wzVaoe8b3pdOyqV2qHUAJdHXqcatVeivccWlY8bp9KBNjVVrqstIXmdEaVTclyJ9rqS1JwIo7ZEREQ0UHHyQURERJbi5IOIiIgsxckHERERWYqTDyIiIrIUJx9ERERkqR5HbTdv3oxHH30U27ZtQ3l5OdauXYuZM2e2jc+ZMwfPPvtsh2WmT5+OdevW9ehxigI+eF2dN6/8iNyhtCUqR4YSNjlSabfL3RfdLnm5ZrSIYzVH68Sx1OxMcQwAUlLlDq0utxw18zjl6FfmcLmjZU2FHNN0+eRYmNMnx8mcTvk5RGNyzDCQliqO2ZVuj01e+bkPGTZMHKsLyTFCr1/e1wklRgkAkRb52PCly89x2LACcSxYL6/zYLncfVNp6AybLfk+jdnkY6I3rKobAFCUmQavq3OIuPyIvI9alC7FCaXL9ImpHXL0PTUrQxwDuqodchRTrR0j5Eh9TaX8/F1+eVucSsdbZ4r8/hhItSPYIseT1drRRVfbSCgkjvmULsrDtG2tbxbHDh7WOyVLbEkKS0wrNsfp8ScfTU1NGDduHJYvXy7e5+qrr0Z5eXnbzx/+8IeePgwRDSKsG0TUXo8/+ZgxYwZmzJih3sfj8aCgQP4LjohOLawbRNTeCTnnY+PGjcjLy8PYsWNx5513oqZG/qokHA6jvr6+ww8RnXp6UjcA1g6ik1mfTz6uvvpq/O53v8OGDRvws5/9DJs2bcKMGTMQFy7XXFJSgkAg0PZTWChfdpeIBqee1g2AtYPoZNbnvV1uueWWtv8/55xzcO6552LUqFHYuHEjrrzyyk73X7JkCRYtWtT27/r6ehYRolNMT+sGwNpBdDI74VHb0047DTk5Ofj444+Tjns8HqSnp3f4IaJTW1d1A2DtIDqZnfCutocOHUJNTQ2GDBnSo+VSEjH4kiRnh6TIEabKRjnC1NwcFsdCITm+pXUE1brh1tTK3R7tGXqRzFaiZh6v/Pwbjh4Vx1wOOWbnsMuRuHCL/LG3JyHvU9Msx8VMRI6oxZXurK4k8clWeRlyfDmRkOfYDU2N4lhzSI5DVh6VX18A8CnvLH+K3O3Tq3RtTs/IFccO1TSIY0fr5G3NSUl+LMbQt1Hbnupt3QCAFBvgSxIVHqJEMSvr5WO5WTmWQyF5ObV2KFHto0rtcCgxbQDI9svjXrV2yPFet0OODDvs8jojLXI99mTINcAoUdMTUjsys8SxE1I7aurEMQDwuZSOuCny+0GvHXJH40PV8vZox2JOWueIck+itj2efDQ2Nnb4a6S0tBTbt29HVlYWsrKy8MADD2DWrFkoKCjA/v37sXjxYowePRrTp0/v6UMR0SDBukFE7fV48vHuu+/i8ssvb/t363eus2fPxooVK7Bjxw48++yzqKurw9ChQzFt2jQ89NBD8Hjk2TMRDW6sG0TUXo8nH1OmTIFRPt565ZVXPtcGEdHgw7pBRO2xtwsRERFZipMPIiIishQnH0RERGSpEx617S1XwsCVJKqW6ZEjU16fHJnKSpO7ARojx4NcbvmEt0CmvC0HjlSIY/XNTeIYAKSky9v64f/uEMeqy+XuhGeNGiuO2d0Z4lhTrdwJtGrvTnHM5pJjX6l+ORbb1CTvG+1qlw0ROS69r0K+THfpQbmrbWWtHKVrielRVLtPPjYSCTmCqSVcPcqxmJ6TLY6VVcvP392cPBIYVWKiA50rYeBKdN6RmT55/3l9GeJYVro81uvakaHUjopycSyovD8AYKxyrZPdOz4Qx9TacfoZ4pjdJT9eo1I7jny0SxyzOeX9lurPEMd6XTvCclx6n9LxtfSAXDsqjsqX+m/poiO23S8//xNSO7KV2qF0gnY3de6UG1X28/H4yQcRERFZipMPIiIishQnH0RERGQpTj6IiIjIUpx8EBERkaU4+SAiIiJLDdiorc/pgd/VefNiSbpVtjraIMebYJfjRG4l2hqNy7soFpKjmKGw3H3x4H45SgcAZ58px5UatS6DqXJ32sxcOYZ8aH+ZOPaeEu0NDJHXWVMpxzvzcoeKY9VNckfLgzVy5836Fjlqe/gzOS7X0iwv503xi2Nw61HbgF+OINqicrfP9ID8GiJV7iCamSt3yo3s+kgcC9qSb0tMi/QNcD6XB3535yhrXMki1gblrsA2pXZ40uTXORKX/7aLheRYqFY7yj4+JI4BwDlfOE8cU2tHepo4lpWj1I5Pelk78uW4fc0RuXbka7WjsXP0s9XBKnmdQaVrsV475Iiu1y+/V2F3yGMAAkKnaQCwxeTfDWrtUOK7mTlyt+xIfI84FkxyeYNYDyL6/OSDiIiILMXJBxEREVmKkw8iIiKyFCcfREREZClOPoiIiMhSnHwQERGRpQZs1NZpt8Fp79wxMhiSo5G1tUfFsdxQjjgWtSnRp1R5OadDnrsFMuV43l/+tlV+PABjij4Rx0aNPF0cizcoUdQ6ed/U1chxsoyUDHHssonTxLGyj+SI1p49cvTzcDB5l1UA2F8jxyEjNrlLaCwux8wKAnLkz5cmL1feUCeOAYBf6czpghxHczjkOGjGsGHiWDAhP15c6bwaDCePGcZP4qit026H0975vRkUOvgCwFGlduQotSMCed9C6d6cbPtaBTLlaOtfXtosPx6A00fKHWhHjRwtjsWb5MsUBJXaUXu0ShzLSM0Qxy67+CpxrOxjuT6otaNGfg4fH5FrYwRy/Y/F5bpSkJkhjvlS5a7e5UF5fwKAX+kI7lLi4g7l11jGUDmiHIzJ0wAtORsMdX4/9aRu8JMPIiIishQnH0RERGQpTj6IiIjIUpx8EBERkaU4+SAiIiJLcfJBRERElupR1LakpAR//vOfsWfPHvh8Plx88cX42c9+hrFjx7bdJxQK4e6778bq1asRDocxffp0PPXUU8jPz+/RhtkcDtiSZIf8XrnT6IjCQnHM45CjiDGli6TNI3cRTMTl7qQ2u1scO1ReLY4BwK9+v0Ycu/6qS8WxnAy5q6GvWu7cGPxM6QZcJ++b+o8/E8eGpcpxwSp/qjj24YFKccxWL3cRzioYIo5B6TDpi8vRNTUSG5L3JwA0xuvEsXi23EXS7ZKP01SvHMEbMkzuapuVJ0c+qyqS72+b8tx7w9raYYctSQze7+td7fAqselYRH5/2N29qx12uxzvPHRYjrYCwK+eXS2OXT99sjiWkyF3tfUdkd93wc/q5I1pUGrHp3Jn72Hp8mUKqlLk7dxTelgcsykdb7PylOMrRampSmNrl9J93ZGkG2x7jcE6cSyeK9cytXb45OV6Xzs6X6LBpkSBj9ejTz42bdqEefPmYevWrXjttdcQjUYxbdo0NDX9qz30XXfdhb/85S9Ys2YNNm3ahMOHD+NLX/pSTx6GiAYZ1g4iaq9Hn3ysW7euw79XrVqFvLw8bNu2DZdddhmCwSCeeeYZPP/887jiiisAACtXrsSZZ56JrVu34qKLLuq7LSeikwZrBxG197nO+QgGgwCArKxjH7Fv27YN0WgUU6dObbvPGWecgREjRmDLli1J1xEOh1FfX9/hh4gGN9YOolNbrycfiUQCCxcuxCWXXIKzzz4bAFBRUQG3242MjIwO983Pz0dFRUXS9ZSUlCAQCLT9FCrfvRLRyY+1g4h6PfmYN28edu7cidWr5ROcumPJkiUIBoNtP2VlZZ9rfUQ0sLF2EFGvGsvNnz8fL730EjZv3ozhw4e33V5QUIBIJIK6uroOf8FUVlaioKAg6bo8Hg88HvksXSIaPFg7iAjo4eTDGIMFCxZg7dq12LhxI4qLizuMjx8/Hi6XCxs2bMCsWbMAAHv37sXBgwcxceLEHm2Y1+eF19U5cmZTOnS21MldT7WxaIscm4zb68Sx4JHkHwcDQNnBQ+KY06Z/4FR9VP7u+r9e2iCOBQJyhDU/Q45M5Rp5e+w1cgfG5iY5vpaeny6OVbU0iWMJnxwzDNfK0b3mOjmCaBzyYa5FbYdkyM8hJ13e1wBgnHLUOhqTI5gNDfKxmBsKi2N+r9zSMjNbjifWHhYij4nuR+a6w/La4e68/21KerilVn7PNQflqGm0RX5N4giKY8EquXYc1GqH0g0XAKqPyo/5X//zqjgWCMjHSL7SZTfXIb9f7XXytqi1I1epHU1yHU945Pd52Ci1o1arHfL7yqf8LhqSGRDHcpR9fewx5X2q1w65a3NuWI73+r3yfsvMkl+L2vIkMX3T/brRo8nHvHnz8Pzzz+PFF19EWlpa23exgUAAPp8PgUAA3/zmN7Fo0SJkZWUhPT0dCxYswMSJE3m2OtEpjLWDiNrr0eRjxYoVAIApU6Z0uH3lypWYM2cOAODxxx+H3W7HrFmzOlwoiIhOXawdRNRej7926YrX68Xy5cuxfPnyXm8UEQ0urB1E1B57uxAREZGlOPkgIiIiS3HyQURERJbq1XU+rGB3u2B3d44cmZAcNdIiszY5MYWGmlpxLJGQH0+7nHNNldyd9awRcldTAAjkyF0GDx2W11tdJ2/PgWY52hZWOgXnuuRDpClFjpN+WC53mNxfLcd3bcq2BN3yixiJylEy0yKPxcNyVDKSkON5w5XoMgA47XIMLyo3NMUnn8gXysrJGyaO2TLk/ZaZKl8LwyWci2HrQWRuoHG4XHAkqR0IyTs+qnQp1mpH49E6cSyRrnR1VWtH526hrc4aqXRvBhBQOiYfOizHe6tr5VisWjtS5Mh5rls+7po98k7dU3ZAHNtfKXcEt3nkrs/1ymsYCcuvvZHLP6qU2hGNy6/9sCw5ugzocepoTH5ffvLJQXEsJ2+oOGZLl/dbZprcDTdZIFiuep3xkw8iIiKyFCcfREREZClOPoiIiMhSnHwQERGRpTj5ICIiIktx8kFERESWGrBR23g8jni889yovq5OXCbVL8e+XC45FtpYI6/T6ZXnZwZy7GnkMDnaNGaE0l4TQPlnchTV65cjlWdm5IhjDqXzuInKsbCMNLkD45F6OZ63u1yOxB1UOrcaI3e8TRqf/D8uu/wEnXZ5ufqEvC1NSnS5SekSCQB5Ljnb5x+avEU8AFQrse/SD/eIY8VnnSaODWvXov54e4WunQ6tBewAF0vEEYt3zkgGe1s7knTIbdWgRG2VxsZ67RguR6rHFOkR6PLDNeKYN13uUHpmTr445nDLAUoT02qH/HhHgnXi2K5D8uUEDtbJHYaNkdfpSNIhvZXLIb9Qau1QOsw2Kd3AG5Xu1ACQ55W3xz9MjlqrtWPPXnGs+AtK7ciSLymw19m5djgS3Q/b8pMPIiIishQnH0RERGQpTj6IiIjIUpx8EBERkaU4+SAiIiJLcfJBRERElhqwUdujtUfRkqSjau1ROd45fOhwcSygdCE90FAljtUdlruzFp02WhzLHVEojlV/+oE4BgCf7Za7TxalyjFNh9KB0W+Xo59RuxyrrA/K0bZEWI7ZZQXk7prNNrlLZiQir1MbMzE54tWUULqZKjFKuOS5eWVLi7wcgPyUDGW9ciy4qqJcHDOhD8Uxr19+ffOVTqdjRieP2UVicWw6LEf3BrJjtaNzRLJWicX2unbUyR1o68rl17KoeJQ4ljuySByrPigfAwDw2V45jl0UUOK0CTlS6vfIvyaiUfm4q2+U3+d67ZAvGdBs5PdOVKkPYa12RJXaoXSnjTnlfWbTakeTvF8AID8tRV6vkt+uqpR/b5iwVjvk1zc/M1scGzO68zEcicWwqVQ+7tvjJx9ERERkKU4+iIiIyFKcfBAREZGlOPkgIiIiS3HyQURERJbi5IOIiIgs1aPJR0lJCS644AKkpaUhLy8PM2fOxN69HbvlTZkyBTabrcPPHXfc0acbTUQnF9YOImqvR9f52LRpE+bNm4cLLrgAsVgM9913H6ZNm4bdu3cjJeVf2eRvf/vbePDBB9v+7VfawEvs//ff8Ybkypl7j02+9kJTUL6Wh8cu57yD1fJ1RSpxQBxzF8rX40gdJl9TAACKLpAv2JGXIV+z4WiZfM2BioNyq+1Ut5ydD6TI89NEXN5v9pCcgZeblwNBJVdfE5Jf3+aIcpGTsHydD8Qi4pDP5RXHXB55nwFAzCsvW97YJI5V1crXVYkY+ZoKoR37xbERI+V9WjQ8+bEYikQBvCcu11MDonbkZYnLeOzycdBUL793PDb5/RFUritSaTsojrkL5bbpqUOGimMAUPT/yc8jL1OpHZ/J9bGirFreHuU9EvDJYwm/Ujt8Su2wy/u7Pio/9+pm+T3XHFHqQ0h+7yCu1A67UjuU2gAAMeXaQ+X1DeLYkRr5d1VEaXUf2r5XHBsxcoQ4VlTYuXaElOupHK9Hk49169Z1+PeqVauQl5eHbdu24bLLLmu73e/3o6BA/uVLRKcW1g4iau9znfMRDB6baWVldfyL4rnnnkNOTg7OPvtsLFmyBM3N8hXdwuEw6uvrO/wQ0eDG2kF0auv15dUTiQQWLlyISy65BGeffXbb7V/96ldRVFSEoUOHYseOHfjBD36AvXv34s9//nPS9ZSUlOCBBx7o7WYQ0UmGtYOIej35mDdvHnbu3Ik333yzw+2333572/+fc845GDJkCK688krs378fo0Z1vhb8kiVLsGjRorZ/19fXo7BQ7otCRCc31g4i6tXkY/78+XjppZewefNmDBdOWGs1YcIEAMDHH3+ctIB4PB54ujh5j4gGB9YOIgJ6OPkwxmDBggVYu3YtNm7ciOLi4i6X2b59OwBgyBD5DG4iGtxYO4iovR5NPubNm4fnn38eL774ItLS0lBRcayFbyAQgM/nw/79+/H888/jmmuuQXZ2Nnbs2IG77roLl112Gc4999webprj/346Mg75HNmQtjo5aYTsQIY45k+X2xsfOipH0LaUyTHcL048X94YADGn/Jjv7pJbZqcZed/EnHJMMzM/TxzzKzFkR4Mc7TUmLI7ZM+TtTI/LsbeMmE8cSzjk59fcrER0m+QIXvsI6PEcyuMBQDQinygZCcvbk5+dLo4Ny5d/CecPkyOYu3fvFMeGZGYkvT0SU6LLvWBt7bAj2bn0Rolpho1SIGxGHMrOyBDH1NpRLb93trwlx3DHX9RF7XDIMc5tO3eLY6k2+VdBTKm5mXlyfNfvlJdzBOV9apTXwq7UOC1qG0iTI9sJ5bjon9ohP2a4Sa6r+TkZ4tiwArk+5A+V68ru3bvEsSFZnS97EYkpseXj9GjysWLFCgDHLgbU3sqVKzFnzhy43W6sX78ey5YtQ1NTEwoLCzFr1iz8x3/8R08ehogGGdYOImqvx1+7aAoLC7Fp06bPtUFENPiwdhBRe+ztQkRERJbi5IOIiIgsxckHERERWYqTDyIiIrJUr69weqLFYnHEbJ0jV8Ytxy0rg3L0yWOTY1jpAblTrj0hnyiX5pZjbbVKc78Duz+VBwFkDskXxxKNcgQyZhLimNchd4q0J+SNtSeUmJ1NvsDT0ZgcNU33yV0bM11y1DShRPBCSsfbkENezpYuR/DS0+VtiSf0KGpTSN432smXLqVLalqKHNFThpDikl/7REvy90wiLh9LA92x2pEkaqt0YK2slbuFepQ/0Yp7Wzs8ch2rjdWKY5/u+VTeGOix+UNNSu1QksZep1I7jByttMeVeL9Tfv5H43IdT/fL76sspXbEta6uWu3wyM/dliU/3ueqHcJ7Euiidtjl/Z2WItfcFCUSnaJ02E0k2W+JHkT0+ckHERERWYqTDyIiIrIUJx9ERERkKU4+iIiIyFKcfBAREZGlOPkgIiIiSw3YqK3H54PH1XnzonZ5k2sb5chUhkeOIYVDcj/c+vo6cayxsVEcy1QiwbaI3udi/wd7xbGAS46GFuXIEd3mJjm+ZxJyp8SEkfe3W+mEmemTn39Eia85IY8118n726dEvJw+eTtdSgzV75PHolo2EUDEo0Xt5BhrQolLNzYGxbFPKuQuqflZcufRkXk5SW9vicaAHaXicgOZx+uD1935tYvY5BpQ2yBHwzOU40CtHcE6cayxUY72Znrljqi2aBe1Y5dSOzzyeovyCsSx5qY6ccwk5EsYJIy839xKHc/0yzUukuR3QiuXTX68pqBSO8QRwJkqx7PV2uGX1xrtovNrRLkUQe9rh3y8ffKhUjsyk9cHABhZ0DnW3RKJAv+Uu2i3x08+iIiIyFKcfBAREZGlOPkgIiIiS3HyQURERJbi5IOIiIgsxckHERERWWrARm2rj1TC6+wcjfOkBsRlclPljocF2VniWCQkR01dUDoz+lLFMTjkeZ0nQ45hHltUjtN5lHirF1pHQTmGpYX3Qsr01Kl0YPUpcTFbQo6atSiRx2iTHKVOT5NjhF6vvM9sDvn19dqVbrg+OYIHAC1huVNw3CmvN6btG+WVyg7Ix1ROIEMcSxXigkqT3AGv+kglvEkimZ4UeR/lpsvRyIKcbHFMrR1KtDfTnyaOqbUjXVlOXxQeJd7qtSlVQFmnscl1JQT5PeBUVurzyXXcFpfXGWqsF8eizb2sHT55O212eSzZ76625ZLEwNvTaofSnBdRtXbIsgPy79ScTLlrc2qSjrcO6JcgaI+ffBAREZGlOPkgIiIiS3HyQURERJbi5IOIiIgsxckHERERWYqTDyIiIrJUj6K2K1aswIoVK/Dpp58CAM466yzcf//9mDFjBgAgFArh7rvvxurVqxEOhzF9+nQ89dRTyM+Xu61KfH4ffEniSukp8ianKfFHt0eOfh6tk+Nybof8eA6nHJnSOgyamNwJEwByAnJXR59DfkyXEtGCEolrjMsRreqovM5YixztTVM61yZi8v52KBE1X0COQxqHHPGyO5WorRKnNVqUzqNHbZVEIGLKeuNxOfLoT5Fjllr3YZeRX6dIU1Py26N6582esrx2JInapqfKNSBN6ULqVl7ro7VyV1e3ctw5XPK2qLUjLr93ACAnQ46N+pzyY7qiSkxf+RO1MS4//2olhhwLKbXDq+ybmPx4DqcS31Wi1GrtUOq/Wjts8liXtUN568WV9cbU2iFfFiJh5JrrUuL9kebOl0WIKL8vjtejTz6GDx+On/70p9i2bRveffddXHHFFbjhhhuwa9cuAMBdd92Fv/zlL1izZg02bdqEw4cP40tf+lJPHoKIBiHWDiJqr0effFx//fUd/v3jH/8YK1aswNatWzF8+HA888wzeP7553HFFVcAAFauXIkzzzwTW7duxUUXXdR3W01EJxXWDiJqr9fnfMTjcaxevRpNTU2YOHEitm3bhmg0iqlTp7bd54wzzsCIESOwZcsWcT3hcBj19fUdfoho8GLtIKIeTz4++OADpKamwuPx4I477sDatWvxhS98ARUVFXC73cjIyOhw//z8fFRUVIjrKykpQSAQaPspLCzs8ZMgooGPtYOIWvV48jF27Fhs374db7/9Nu68807Mnj0bu3fv7vUGLFmyBMFgsO2nrKys1+siooGLtYOIWvW4sZzb7cbo0aMBAOPHj8c777yDJ554Al/5ylcQiURQV1fX4S+YyspKFBQUiOvzeDzweORGQkQ0OLB2EFGrz93VNpFIIBwOY/z48XC5XNiwYQNmzZoFANi7dy8OHjyIiRMn9ni9Hq8XniRxuVQlMuR0yzGk+ha5W+ohpRtifV2DOJajdLVNV+KyjpDWRxaobKwSx/x+OYbmScjrtStxqqgSwYs0y9G2usZGccxE5TiZX4k9e33yfovF5QiiTenKqcWsjZGXc2oRXSXyBgAOpb1oSMnhJusU2TamRPQiSpxW6zRphNiz0fJ+feSE1o4knUP12iG/XvUtyePIAHCovk5eTqsdSmw6PSDHZR1h/cPqyvoacczvlydqHq2pbUKpHQ6ldkTlXqp1DfK+MTE5FutXJpten7xcNDZIakdUrsepyr5J9Sq1I6HUDqVzuUkSezbaNQaO06PJx5IlSzBjxgyMGDECDQ0NeP7557Fx40a88sorCAQC+OY3v4lFixYhKysL6enpWLBgASZOnMiz1YlOcawdRNRejyYfR44cwde//nWUl5cjEAjg3HPPxSuvvIKrrroKAPD444/Dbrdj1qxZHS4URESnNtYOImqvR5OPZ555Rh33er1Yvnw5li9f/rk2iogGF9YOImqPvV2IiIjIUpx8EBERkaU+d9qlr7WeQdwiNLZqjshn0zqVs/qblUZZoZg8Fo7LZwJry7mUx3Mk9DlfKCY/pk1Zb0I+oRt2pemQfP60vi1hJX2iLWd3yGMx5fnFlSeonUDuVNapnbEeU46nWBfz9rDymC1KkkTpKQYoZ57raRf5ORrhGG59/bT9M9D8q3YkrxHNEflIdxp532o1J6S8zmGlPmjLuZTH05IQXa3XFpVTK0pQDnblfRdRapm+b3pXV+12+TnEnfJysV6mXZzK/jbK+yqm7M+Y0dMuYeX1b4nJY/pbVX5MtXYoDUlNkm1pfc27UzdsZoBVl0OHDvFKhUQDRFlZGYYPH97fm9EtrB1EA0N36saAm3wkEgkcPnwYaWlpsNlsqK+vR2FhIcrKypCent7fmzdgcL/IuG+S68l+McagoaEBQ4cOhd1+cnw72752NDQ08BgQ8P2RHPeLrLv7pid1Y8B97WK325POmNLT03lAJMH9IuO+Sa67+yUQCFiwNX2nfe1ovZATjwEZ901y3C+y7uyb7taNk+NPGiIiIho0OPkgIiIiSw34yYfH48HSpUvZQOo43C8y7pvkTqX9cio9157ivkmO+0V2IvbNgDvhlIiIiAa3Af/JBxEREQ0unHwQERGRpTj5ICIiIktx8kFERESW4uSDiIiILDWgJx/Lly/HyJEj4fV6MWHCBPzzn//s702y3ObNm3H99ddj6NChsNlseOGFFzqMG2Nw//33Y8iQIfD5fJg6dSr27dvXPxtroZKSElxwwQVIS0tDXl4eZs6cib1793a4TygUwrx585CdnY3U1FTMmjULlZWV/bTF1lmxYgXOPffctqsRTpw4EX/729/axk+F/cLawdohYe1Izuq6MWAnH3/84x+xaNEiLF26FO+99x7GjRuH6dOn48iRI/29aZZqamrCuHHjsHz58qTjjzzyCH7xi1/gV7/6Fd5++22kpKRg+vTpCIVCFm+ptTZt2oR58+Zh69ateO211xCNRjFt2jQ0NTW13eeuu+7CX/7yF6xZswabNm3C4cOH8aUvfakft9oaw4cPx09/+lNs27YN7777Lq644grccMMN2LVrF4DBv19YO45h7UiOtSM5y+uGGaAuvPBCM2/evLZ/x+NxM3ToUFNSUtKPW9W/AJi1a9e2/TuRSJiCggLz6KOPtt1WV1dnPB6P+cMf/tAPW9h/jhw5YgCYTZs2GWOO7QeXy2XWrFnTdp8PP/zQADBbtmzpr83sN5mZmea3v/3tKbFfWDs6Y+2QsXbITmTdGJCffEQiEWzbtg1Tp05tu81ut2Pq1KnYsmVLP27ZwFJaWoqKiooO+ykQCGDChAmn3H4KBoMAgKysLADAtm3bEI1GO+ybM844AyNGjDil9k08Hsfq1avR1NSEiRMnDvr9wtrRPawd/8La0ZkVdWPAdbUFgOrqasTjceTn53e4PT8/H3v27OmnrRp4KioqACDpfmodOxUkEgksXLgQl1xyCc4++2wAx/aN2+1GRkZGh/ueKvvmgw8+wMSJExEKhZCamoq1a9fiC1/4ArZv3z6o9wtrR/ewdhzD2tGRlXVjQE4+iHpi3rx52LlzJ958883+3pQBY+zYsdi+fTuCwSD+9Kc/Yfbs2di0aVN/bxbRgMLa0ZGVdWNAfu2Sk5MDh8PR6UzayspKFBQU9NNWDTyt++JU3k/z58/HSy+9hDfeeAPDhw9vu72goACRSAR1dXUd7n+q7Bu3243Ro0dj/PjxKCkpwbhx4/DEE08M+v3C2tE9rB2sHclYWTcG5OTD7XZj/Pjx2LBhQ9ttiUQCGzZswMSJE/txywaW4uJiFBQUdNhP9fX1ePvttwf9fjLGYP78+Vi7di1ef/11FBcXdxgfP348XC5Xh32zd+9eHDx4cNDvm2QSiQTC4fCg3y+sHd3D2sHa0R0ntG70zTmxfW/16tXG4/GYVatWmd27d5vbb7/dZGRkmIqKiv7eNEs1NDSY999/37z//vsGgHnsscfM+++/bw4cOGCMMeanP/2pycjIMC+++KLZsWOHueGGG0xxcbFpaWnp5y0/se68804TCATMxo0bTXl5edtPc3Nz233uuOMOM2LECPP666+bd99910ycONFMnDixH7faGvfee6/ZtGmTKS0tNTt27DD33nuvsdls5tVXXzXGDP79wtpxDGtHcqwdyVldNwbs5MMYY5588kkzYsQI43a7zYUXXmi2bt3a35tkuTfeeMMA6PQze/ZsY8yxyNwPf/hDk5+fbzwej7nyyivN3r17+3ejLZBsnwAwK1eubLtPS0uL+c53vmMyMzON3+83N954oykvL++/jbbIN77xDVNUVGTcbrfJzc01V155ZVsBMebU2C+sHawdEtaO5KyuGzZjjOndZyZEREREPTcgz/kgIiKiwYuTDyIiIrIUJx9ERERkKU4+iIiIyFKcfBAREZGlOPkgIiIiS3HyQURERJbi5IOIiIgsxckHERERWYqTDyIiIrIUJx9ERERkqf8f/yizwvzIk3UAAAAASUVORK5CYII=", "text/plain": [ "
" ] @@ -258,14 +257,6 @@ "source": [ "visualise(x_test, x_test_adv, predictions_benign, predictions_adv, y_test)" ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f988fc1d-b74d-4968-a033-ea729bea788c", - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { From faaab20f03049757708a6094d35e5f935e9c31db Mon Sep 17 00:00:00 2001 From: Lei Hsiung Date: Sun, 17 Sep 2023 00:43:17 +0800 Subject: [PATCH 04/26] Fix Coding Style Signed-off-by: Lei Hsiung --- .../evasion/composite_adversarial_attack.py | 81 +++++++++---------- notebooks/composite-adversarial-attack.ipynb | 28 +++---- 2 files changed, 54 insertions(+), 55 deletions(-) diff --git a/art/attacks/evasion/composite_adversarial_attack.py b/art/attacks/evasion/composite_adversarial_attack.py index 7a1e8280d3..70c53c144f 100644 --- a/art/attacks/evasion/composite_adversarial_attack.py +++ b/art/attacks/evasion/composite_adversarial_attack.py @@ -27,7 +27,7 @@ import logging -from typing import Optional, Tuple, List, TYPE_CHECKING +from typing import Optional, Tuple, TYPE_CHECKING import numpy as np from tqdm.auto import tqdm @@ -84,12 +84,12 @@ def __init__( classifier: "PyTorchClassifier", enabled_attack: Tuple = (0, 1, 2, 3, 4, 5), # Default: Full Attacks; 0: Hue, 1: Saturation, 2: Rotation, 3: Brightness, 4: Contrast, 5: PGD (L-infinity) - hue_epsilon: List = [-np.pi, np.pi], - sat_epsilon: List = [0.7, 1.3], - rot_epsilon: List = [-10, 10], - bri_epsilon: List = [-0.2, 0.2], - con_epsilon: List = [0.7, 1.3], - pgd_epsilon: List = [-8 / 255, 8 / 255], # L-infinity + hue_epsilon: Tuple = (-np.pi, np.pi), + sat_epsilon: Tuple = (0.7, 1.3), + rot_epsilon: Tuple = (-10, 10), + bri_epsilon: Tuple = (-0.2, 0.2), + con_epsilon: Tuple = (0.7, 1.3), + pgd_epsilon: Tuple = (-8 / 255, 8 / 255), # L-infinity early_stop: bool = True, max_iter: int = 5, max_inner_iter: int = 10, @@ -108,19 +108,19 @@ def __init__( semantic attacks; `(0,1,2,3,4,5)` means the full attacks. :param hue_epsilon: The boundary of the hue perturbation. The value is expected to be in the interval `[-np.pi, np.pi]`. Perturbation of `0` means no shift and `-np.pi` and `np.pi` give a - complete reversal of the hue channel in the HSV colour space in the positive and negative + complete reversal of the hue channel in the HSV color space in the positive and negative directions, respectively. See `kornia.enhance.adjust_hue` for more details. :param sat_epsilon: The boundary of the saturation perturbation. The value is expected to be in the interval - `[0, infinity)`. Perturbation of `0` gives a black and white image, `1` gives the original - image, while `2` enhances the saturation by a factor of 2. See - `kornia.geometry.transform.rotate` for more details. + `[0, infinity]`. The perturbation of `0` gives a black-and-white image, `1` gives the + original image, and `2` enhances the saturation by a factor of 2. See + `kornia.geometry.transform.rotate` for more details. :param rot_epsilon: The boundary of the rotation perturbation (in degrees). Positive values mean counter-clockwise rotation. See `kornia.geometry.transform.rotate` for more details. :param bri_epsilon: The boundary of the brightness perturbation. The value is expected to be in the interval `[-1, 1]`. Perturbation of `0` means no shift, `-1` gives a complete black image, and `1` gives a complete white image. See `kornia.enhance.adjust_brightness` for more details. :param con_epsilon: The boundary of the contrast perturbation. The value is expected to be in the interval - `[0, infinity)`. Perturbation of `0` gives a complete black image, `1` does not modify the + `[0, infinity]`. Perturbation of `0` gives a complete black image, `1` does not modify the image, and any other value modifies the brightness by this factor. See `kornia.enhance.adjust_contrast` for more details. :param pgd_epsilon: The maximum perturbation that the attacker can introduce in the L-infinity ball. @@ -129,10 +129,10 @@ def __init__( :param max_iter: The maximum number of iterations for attack order optimization. :param max_inner_iter: The maximum number of iterations for each attack optimization. :param attack_order: Specify the scheduling type for composite adversarial attack. The value is expected to be - `fixed`, `random', or `scheduled`. `fixed` means the attack order is the same as specified - in `enabled_attack`. `random` means the attack order is randomly generated at each iteration. - `scheduled` means to enable the attack order optimization proposed in the paper. If only one - attack is enabled, `fixed` will be used. + `fixed`, `random`, or `scheduled`. `fixed` means the attack order is the same as specified + in `enabled_attack`. `random` means the attack order is randomly generated at each + iteration. `scheduled` means to enable the attack order optimization proposed in the paper. + If only one attack is enabled, `fixed` will be used. :param batch_size: The batch size to use during the generation of adversarial samples. :param verbose: Show progress bars. """ @@ -178,24 +178,24 @@ def _check_params(self) -> None: value in [0, 1, 2, 3, 4, 5] for value in self.enabled_attack): raise ValueError( "The parameter `enabled_attack` must be a tuple specifying the attack to launch. For simplicity, we use" - + " the following abbreviations to specify each attack types. 0: Hue, 1: Saturation, 2: Rotation, 3: Br" - + "ightness, 4: Contrast, 5: PGD(L-infinity). Therefore, `(0,1,2)` means that the attack combines hue, " - + "saturation, and rotation; `(0,1,2,3,4)` means the all semantic attacks; `(0,1,2,3,4,5)` means the fu" - + "ll attacks.") - _epsilons_range = [["hue_epsilon", [-np.pi, np.pi], "[-np.pi, np.pi]"], - ["sat_epsilon", [0, np.inf], "[0, np.inf]"], ["rot_epsilon", [-360, 360], "[-360, 360]"], - ["bri_epsilon", [-1, 1], "[-1, 1]"], ["con_epsilon", [0, np.inf], "[0, np.inf]"], - ["pgd_epsilon", [-1, 1], "[-1, 1]"]] + + " the following abbreviations to specify each attack types. 0: Hue, 1: Saturation, 2: Rotation," + + " 3: Brightness, 4: Contrast, 5: PGD(L-infinity). Therefore, `(0,1,2)` means that the attack combines" + + " hue, saturation, and rotation; `(0,1,2,3,4)` means the all semantic attacks; `(0,1,2,3,4,5)` means" + + " the full attacks.") + _epsilons_range = [["hue_epsilon", (-np.pi, np.pi), "(-np.pi, np.pi)"], + ["sat_epsilon", (0, np.inf), "(0, np.inf)"], ["rot_epsilon", (-360, 360), "(-360, 360)"], + ["bri_epsilon", (-1, 1), "(-1, 1)"], ["con_epsilon", (0, np.inf), "(0, np.inf)"], + ["pgd_epsilon", (-1, 1), "(-1, 1)"]] for i in range(6): - if (not isinstance(self.epsilons[i], list) or - not len(self.epsilons[i]) == 2 or - not _epsilons_range[i][1][0] <= self.epsilons[i][0] <= self.epsilons[i][1] <= _epsilons_range[i][1][1]): + if (not isinstance(self.epsilons[i], tuple) or not len(self.epsilons[i]) == 2 or + not (_epsilons_range[i][1][0] <= self.epsilons[i][0] <= + self.epsilons[i][1] <= _epsilons_range[i][1][1])): logger.info( "The argument `" + _epsilons_range[i][0] + "` must be an interval within " + _epsilons_range[i][2] - + " of type list.") + + " of type tuple.") raise ValueError( "The argument `" + _epsilons_range[i][0] + "` must be an interval within " + _epsilons_range[i][2] - + " of type list.") + + " of type tuple.") if not isinstance(self.early_stop, bool): logger.info("The flag `early_stop` has to be of type bool.") @@ -265,16 +265,16 @@ def _set_targets( def _setup_attack(self): import torch - hue_space = torch.rand(self.batch_size, device=self.device) * ( - self.eps_pool[0][1] - self.eps_pool[0][0]) + self.eps_pool[0][0] - sat_space = torch.rand(self.batch_size, device=self.device) * ( - self.eps_pool[1][1] - self.eps_pool[1][0]) + self.eps_pool[1][0] - rot_space = torch.rand(self.batch_size, device=self.device) * ( - self.eps_pool[2][1] - self.eps_pool[2][0]) + self.eps_pool[2][0] - bri_space = torch.rand(self.batch_size, device=self.device) * ( - self.eps_pool[3][1] - self.eps_pool[3][0]) + self.eps_pool[3][0] - con_space = torch.rand(self.batch_size, device=self.device) * ( - self.eps_pool[4][1] - self.eps_pool[4][0]) + self.eps_pool[4][0] + hue_space = torch.rand(self.batch_size, device=self.device) * (self.eps_pool[0][1] - self.eps_pool[0][0]) + \ + self.eps_pool[0][0] + sat_space = torch.rand(self.batch_size, device=self.device) * (self.eps_pool[1][1] - self.eps_pool[1][0]) + \ + self.eps_pool[1][0] + rot_space = torch.rand(self.batch_size, device=self.device) * (self.eps_pool[2][1] - self.eps_pool[2][0]) + \ + self.eps_pool[2][0] + bri_space = torch.rand(self.batch_size, device=self.device) * (self.eps_pool[3][1] - self.eps_pool[3][0]) + \ + self.eps_pool[3][0] + con_space = torch.rand(self.batch_size, device=self.device) * (self.eps_pool[4][1] - self.eps_pool[4][0]) + \ + self.eps_pool[4][0] pgd_space = 0.001 * torch.randn([self.batch_size, 3, 32, 32], device=self.device) self.adv_val_pool = [hue_space, sat_space, rot_space, bri_space, con_space, pgd_space] @@ -305,7 +305,6 @@ def generate( for (batch_id, batch_all) in enumerate( tqdm(data_loader, desc=self._description, leave=False, disable=not self.verbose) ): - self._batch_id = batch_id (batch_x, batch_targets, batch_mask) = batch_all[0], batch_all[1], None batch_index_1, batch_index_2 = batch_id * self.batch_size, (batch_id + 1) * self.batch_size @@ -339,7 +338,6 @@ def _generate_batch( """ import torch - self.batch_size = x.shape[0] self._setup_attack() self.is_attacked = torch.zeros(self.batch_size, device=self.device).bool() @@ -347,6 +345,7 @@ def _generate_batch( x, y = x.to(self.device), y.to(self.device) return self.caa_attack(x, y).cpu().detach().numpy() + def _comp_pgd( self, data: "torch.Tensor", diff --git a/notebooks/composite-adversarial-attack.ipynb b/notebooks/composite-adversarial-attack.ipynb index 3ce058827b..787108aa4c 100644 --- a/notebooks/composite-adversarial-attack.ipynb +++ b/notebooks/composite-adversarial-attack.ipynb @@ -91,7 +91,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Accuracy on the benign test set: 50.839999999999996%\n" + "Accuracy on the benign test set: 46.39%\n" ] } ], @@ -115,12 +115,12 @@ "\n", "`CompositeAdversarialAttack` has the following parameters:\n", "- `classifier`: A trained PyTorch classifier.\n", - "- `enabled_attack`: Attack pool selection, and attack order designation for `fixed` order. For simplicity, we use the following abbreviations to specify each attack types. 0: Hue, 1: Saturation, 2: Rotation, 3: Brightness, 4: Contrast, 5: PGD ($\\ell_\\infty$).\n", - "- `hue_epsilon`: The boundary of the hue perturbation. The value is expected to be in the interval `[-np.pi, np.pi]`. Perturbation of `0` means no shift and `-np.pi` and `np.pi` give a complete reversal of the hue channel in the HSV colour space in the positive and negative directions, respectively. See `kornia.enhance.adjust_hue` for more details.\n", - "- `sat_epsilon`: The boundary of the saturation perturbation. The value is expected to be in the interval `[0, infinity)`. Perturbation of `0` gives a black and white image, `1` gives the original image, while `2` enhances the saturation by a factor of 2. See `kornia.geometry.transform.rotate` for more details.\n", + "- `enabled_attack`: Attack pool selection, and attack order designation for `fixed` order. For simplicity, we use the following abbreviations to specify each attack type. 0: Hue, 1: Saturation, 2: Rotation, 3: Brightness, 4: Contrast, 5: PGD ($\\ell_\\infty$).\n", + "- `hue_epsilon`: The boundary of the hue perturbation. The value is expected to be in the interval `[-np.pi, np.pi]`. Perturbation of `0` means no shift and `-np.pi` and `np.pi` give a complete reversal of the hue channel in the HSV color space in the positive and negative directions, respectively. See `kornia.enhance.adjust_hue` for more details.\n", + "- `sat_epsilon`: The boundary of the saturation perturbation. The value is expected to be in the interval `[0, infinity]`. The perturbation of `0` gives a black-and-white image, `1` gives the original image, and `2` enhances the saturation by a factor of 2. See `kornia.geometry.transform.rotate` for more details.\n", "- `rot_epsilon`: The boundary of the rotation perturbation (in degrees). Positive values mean counter-clockwise rotation. See `kornia.geometry.transform.rotate` for more details.\n", "- `bri_epsilon`: The boundary of the brightness perturbation. The value is expected to be in the interval `[-1, 1]`. Perturbation of `0` means no shift, `-1` gives a complete black image, and `1` gives a complete white image. See `kornia.enhance.adjust_brightness` for more details.\n", - "- `con_epsilon`: The boundary of the contrast perturbation. The value is expected to be in the interval `[0, infinity)`. Perturbation of `0` gives a complete black image, `1` does not modify the image, and any other value modifies the brightness by this factor. See `kornia.enhance.adjust_contrast` for more details.\n", + "- `con_epsilon`: The boundary of the contrast perturbation. The value is expected to be in the interval `[0, infinity]`. Perturbation of `0` gives a complete black image, `1` does not modify the image, and any other value modifies the brightness by this factor. See `kornia.enhance.adjust_contrast` for more details.\n", "- `pgd_epsilon`: The maximum perturbation that the attacker can introduce in the L-infinity ball.\n", "- `early_stop`: When True, the attack will stop if the perturbed example is classified incorrectly by the classifier.\n", "- `max_iter`: The maximum number of iterations for attack order optimization.\n", @@ -161,12 +161,12 @@ "# Create the ART attacker.\n", "attack = CompositeAdversarialAttackPyTorch(classifier,\n", " enabled_attack = (0,1,2,3,4,5), # 0: Hue, 1: Saturation, 2: Rotation, 3: Brightness, 4: Contrast, 5: PGD (L-infinity)\n", - " hue_epsilon = [-np.pi, np.pi],\n", - " sat_epsilon = [0.7, 1.3],\n", - " rot_epsilon = [-10, 10],\n", - " bri_epsilon = [-0.2, 0.2],\n", - " con_epsilon = [0.7, 1.3],\n", - " pgd_epsilon = [-8 / 255, 8 / 255],\n", + " hue_epsilon = (-np.pi, np.pi),\n", + " sat_epsilon = (0.7, 1.3),\n", + " rot_epsilon = (-10, 10),\n", + " bri_epsilon = (-0.2, 0.2),\n", + " con_epsilon = (0.7, 1.3),\n", + " pgd_epsilon = (-8 / 255, 8 / 255),\n", " early_stop = True,\n", " max_iter = 5,\n", " max_inner_iter = 10,\n", @@ -225,7 +225,7 @@ "outputs": [ { "data": { - "image/png": "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", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAh8AAAEjCAYAAACSDWOaAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/OQEPoAAAACXBIWXMAAA9hAAAPYQGoP6dpAABNj0lEQVR4nO3deXRU9f0//ufsk0wmMwlJJgkJIYAibvgtCuKKiiBoP6Joq20/BbtoLdAqWj/ip5W6fBqrPS3WIq2tBdtTSkuP1NZaXFBCVUDZRECQJUAwZIEwWSaZ9b5/f/BLJMy83iQQbhaej3NyDsxr7sydO/e+887Mfd6XRSmlQERERGQSa0+vABEREZ1ZOPkgIiIiU3HyQURERKbi5IOIiIhMxckHERERmYqTDyIiIjIVJx9ERERkKk4+iIiIyFScfBAREZGpOPnoowYPHozp06e3/3/lypWwWCxYuXJltz2HxWLBj3/84257vNPhww8/xGWXXQaPxwOLxYJNmzb19CoR9aj+PDZMnz4dGRkZ3f64zzzzDIYMGQKbzYaLLrqo2x+fknHycRIWLVoEi8XS/uN2u3H22Wdj5syZqKmp6enV65LXXnut108wJLFYDLfffjvq6+vxi1/8An/84x9RUlKC559/HosWLerp1Wsf9FP9rFmzpqdXj04Djg19zxtvvIGHHnoIl19+ORYuXIif/OQnPb1KWvfffz++8IUvIDs7G+np6RgxYgR+/OMfo7m5uadXrUvsPb0Cfdnjjz+O0tJShMNhvPvuu1iwYAFee+01bNmyBenp6aauy1VXXYXW1lY4nc4uLffaa69h/vz5KQeZ1tZW2O29dxfZvXs39u3bh9/+9rf41re+1X77888/j5ycnA5//fWk733ve7jkkks63DZs2LAeWhsyA8eGvuPtt9+G1WrFiy++2OVt1BM+/PBDXHnllbjrrrvgdruxceNGPPXUU3jrrbewatUqWK194zOF/rH39JBJkybh4osvBgB861vfwoABA/Dzn/8cr7zyCu68886Uy4RCIXg8nm5fF6vVCrfb3a2P2d2P191qa2sBAH6//7Q/Vzweh2EYJzU4XXnllbjttttOw1pRb8Wxoe+ora1FWlpat008lFIIh8NIS0vrlsc73rvvvpt029ChQ/Hggw/igw8+wKWXXnpanre79Y0pUh9x7bXXAgAqKioAfP795O7duzF58mR4vV589atfBQAYhoF58+bhvPPOg9vtRiAQwD333IMjR450eEylFJ588kkUFRUhPT0d11xzDbZu3Zr03NL3umvXrsXkyZORlZUFj8eDCy+8EM8++2z7+s2fPx8AOnxU3CbV97obN27EpEmTkJmZiYyMDFx33XVJXyG0ffT83nvvYfbs2cjNzYXH48Ett9yCurq6E27HzZs3Y/r06RgyZAjcbjfy8/PxjW98A4cPH26/z/Tp03H11VcDAG6//XZYLBaMGzcOgwcPxtatW1FeXt7+esaNG9e+XDAYxH333Yfi4mK4XC4MGzYMP/3pT2EYRvt99u7dC4vFgp/97GeYN28ehg4dCpfLhW3btgEAtm/fjv3795/wdRyrqakJ8Xi8S8tQ/8Gx4ahTHRva7NmzBxMnToTH40FhYSEef/xxHN+gvTPb0WKxYOHChQiFQu2vse0r23g8jieeeKL9+B88eDAeeeQRRCKRDs8zePBg3HTTTXj99ddx8cUXIy0tDb/5zW8AdG68AYCDBw9i+/btiMVind4Gx69D2/P1Ffzkoxvt3r0bADBgwID22+LxOCZOnIgrrrgCP/vZz9o/cr3nnnuwaNEi3HXXXfje976HiooK/OpXv8LGjRvx3nvvweFwAAAeffRRPPnkk5g8eTImT56MDRs2YMKECYhGoydcnzfffBM33XQTCgoK8P3vfx/5+fn45JNP8Oqrr+L73/8+7rnnHlRVVeHNN9/EH//4xxM+3tatW3HllVciMzMTDz30EBwOB37zm99g3LhxKC8vx5gxYzrcf9asWcjKysLcuXOxd+9ezJs3DzNnzsRf/vKXE673nj17cNdddyE/Px9bt27FCy+8gK1bt2LNmjWwWCy45557MHDgQPzkJz9p/1ojEAggFAph1qxZyMjIwP/+7/8CAAKBAACgpaUFV199NT777DPcc889GDRoEN5//33MmTMHBw8exLx58zqsx8KFCxEOh3H33XfD5XIhOzsbADBixAhcffXVnT6B76677kJzczNsNhuuvPJKPPPMM+1/FdOZgWND94wNAJBIJHDDDTfg0ksvxdNPP43ly5dj7ty5iMfjePzxx9vv15nt+Mc//hEvvPACPvjgA/zud78DAFx22WUAjn5i9dJLL+G2227DAw88gLVr16KsrAyffPIJli1b1mGdduzYgTvvvBP33HMPvv3tb2P48OFdGm/mzJmDl156CRUVFe0TCZ14PI5gMIhoNIotW7bghz/8IbxeL0aPHn3CZXsNRV22cOFCBUC99dZbqq6uTlVWVqolS5aoAQMGqLS0NHXgwAGllFLTpk1TANTDDz/cYfn//Oc/CoD605/+1OH25cuXd7i9trZWOZ1OdeONNyrDMNrv98gjjygAatq0ae23vfPOOwqAeuedd5RSSsXjcVVaWqpKSkrUkSNHOjzPsY81Y8YMJe0GANTcuXPb/z9lyhTldDrV7t2722+rqqpSXq9XXXXVVUnbZ/z48R2e6/7771c2m00Fg8GUz9empaUl6bY///nPCoBatWpV0mteunRph/ued9556uqrr056jCeeeEJ5PB716aefdrj94YcfVjabTe3fv18ppVRFRYUCoDIzM1VtbW3S4wBI+fjHe++999TUqVPViy++qF555RVVVlamBgwYoNxut9qwYcMJl6e+h2PD6R0b2rbbrFmzOqzzjTfeqJxOp6qrq1NKdX47tj2mx+PpcL9NmzYpAOpb3/pWh9sffPBBBUC9/fbb7beVlJQoAGr58uUd7tvZ8ebY11VRUaF9/W1Wr16tALT/DB8+vP397Sv4tcspGD9+PHJzc1FcXIw77rgDGRkZWLZsGQYOHNjhfvfee2+H/y9duhQ+nw/XX389Dh061P4zatQoZGRk4J133gEAvPXWW4hGo5g1a1aHjzzvu+++E67bxo0bUVFRgfvuuy/pnIhjH6uzEokE3njjDUyZMgVDhgxpv72goABf+cpX8O6776KxsbHDMnfffXeH57ryyiuRSCSwb98+7XMd+11pOBzGoUOH2r/H3LBhQ5fXvc3SpUtx5ZVXIisrq8N2Hz9+PBKJBFatWtXh/lOnTkVubm7S4yilOvWpx2WXXYa//e1v+MY3voH/+q//wsMPP9z+yc2cOXNO+nVQ78ex4fSMDW1mzpzZYZ1nzpyJaDSKt956C0Dnt6PktddeAwDMnj27w+0PPPAAAOBf//pXh9tLS0sxceLEDrd1ZbxZtGgRlFKd+tQDAM4991y8+eab+Pvf/46HHnoIHo+HaZczyfz583H22WfDbrcjEAhg+PDhSWca2+12FBUVdbht586daGhoQF5eXsrHbTuRsu1APOusszrUc3NzkZWVpV23to95zz///M6/II26ujq0tLRg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", "text/plain": [ "
" ] @@ -235,7 +235,7 @@ }, { "data": { - "image/png": "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", + "image/png": "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", "text/plain": [ "
" ] @@ -245,7 +245,7 @@ }, { "data": { - "image/png": "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46KLLsIjjzyCdevWYenSpYjFYnjwwQfb7ted/fj73/8eTz/9NP75z3/it7/9LQDg4osvBnDsE6tnn30WN910E+6++268/fbbKCkpwYcffoi1a9d22Ka9e/fi1ltvxdy5c/Htb38bY8eO7VG9WbJkCZ599lmUlpZi5MiR4nN/8803EQqFMHr0aNx000144YUXkEgkMHHiRCxfvvzkOlnWUI+tXLnSADDr1683VVVVpqyszKxevdpkZ2cbn89nDh06ZIwxZvbs2QaAuffeezss//e//90AMM8991yH29etW9fh9iNHjhi3222uvfZak0gk2u533333GQBm9uzZbbe98cYbBoB54403jDHGxGIxU1xcbIqKikxtbW2Hx2m/rnnz5hnpMABgli5d2vbvmTNnGrfbbfbv39922+HDh01aWpq57LLLOu2fqVOndnisu+66yzgcDlNXV5f08Vo1Nzd3uu0Pf/iDAWA2b97c6TmvWbOmw33POussM3ny5E7reOihh0xKSor56KOPOtx+7733GofDYQ4ePGiMMaa0tNQAMOnp6ebIkSOd1gMg6fqPd84555gxY8aYWCzWdls4HDYjRowwAMyf/vSnLtdBJxfWhhNbG1r324IFCzps87XXXmvcbrepqqoyxnR/P7auMyUlpcP9tm/fbgCYb33rWx1uv+eeewwA8/rrr7fdVlRUZACYdevWdbhvd+tN++dVWlqqPv/HHnvMADDZ2dnmwgsvNM8995x56qmnTH5+vsnMzDSHDx9Wlx9I+LXL5zB16lTk5uaisLAQt9xyC1JTU7F27VoMGzasw/3uvPPODv9es2YNAoEArrrqKlRXV7f9jB8/HqmpqXjjjTcAAOvXr0ckEsGCBQs6fOS5cOHCLrft/fffR2lpKRYuXNjpnIj26+queDyOV199FTNnzsRpp53WdvuQIUPw1a9+FW+++Sbq6+s7LHP77bd3eKxLL70U8XgcBw4cUB+r/acFoVAI1dXVbZ8QvPfeez3e9lZr1qzBpZdeiszMzA77ferUqYjH49i8eXOH+8+aNQu5ubmd1mOM6VZs8Tvf+Q4++ugjfPOb38Tu3buxc+dOfP3rX0d5eTmAYyft0eDE2nBiakOr+fPnd9jm+fPnIxKJYP369QC6vx8lL7/8MgBg0aJFHW6/++67AQB//etfO9xeXFyM6dOnd7itJ/Vm1apVMMaon3oAaPuq1mazYcOGDfjqV7+KO++8Ey+88AJqa2vbvio7GfBrl89h+fLlGDNmDJxOJ/Lz8zF27FjY7R3nc06nE8OHD+9w2759+xAMBpGXl5d0va0nUra+EU8//fQO47m5ucjMzFS3rfVj3rPPPrv7T0hRVVWF5ubmpAmNM888E4lEAmVlZTjrrLPabh8xYkSH+7Vu8/HfXR/v6NGjeOCBB7B69eq2fdEqGAz29ilg37592LFjR9IJBYBOj9X+ZK7euOOOO1BWVoZHH30Uzz77LADg/PPPx+LFi/HjH//4hFyvgAYG1oZj+ro2AMdOoG0/yQGAMWPGADh2vhbQ/f0oOXDgAOx2O0aPHt3h9oKCAmRkZHSaJCWrFT2tN93R+ofZ9ddf36F+XHTRRSguLsZbb73V43X2F04+PocLL7yw7Yx2icfj6VR0EokE8vLy8NxzzyVdRjpYTzYOhyPp7ea4E8OO9+UvfxlvvfUWvv/97+O8885DamoqEokErr766k4navVEIpHAVVddhcWLFycdby1grfribPUf//jHuOeee7Br1y4EAgGcc845uO+++5I+Hg0erA263taG7uqr/djdT4KS1Yqe1pvuGDp0KIB/ncfWXl5eXrcmbwMFJx/9YNSoUVi/fj0uueQS9RdcUVERgGMz6PYz/aqqqi4PslGjRgEAdu7cialTp4r36+6bKzc3F36/H3v37u00tmfPHtjtdhQWFnZrXZra2lps2LABDzzwAO6///622/ft29ftdUjPadSoUWhsbFT3x4mQmZmJSZMmtf17/fr1GD58OM444wxLt4MGPtaGriUSCXzyyScdfnl/9NFHAND2tUV396OkqKgIiUQC+/btw5lnntl2e2VlJerq6tr2v+ZE1Jvx48cDAD777LNOY4cPHz6pagrP+egHX/7ylxGPx/HQQw91GovFYqirqwNw7Htjl8uFJ598ssNfBMenMpL54he/iOLiYixbtqxtfa3ar6v1ugLH3+d4DocD06ZNw4svvtj20SZw7M34/PPPY9KkSUhPT+9yu7rS+hfR8X8Bdec5t0pJSUn6fL785S9jy5YteOWVVzqN1dXVIRaLdWv93Y3aJvPHP/4R77zzDhYuXNjpr14i1obu+eUvf9lhm3/5y1/C5XLhyiuvBND9/Si55pprAHTen4899hgA4Nprr+1yG3tSb7obtR07dizGjRuHF198EdXV1W23v/rqqygrK8NVV13V5XYNFPzkox9MnjwZc+fORUlJCbZv345p06bB5XJh3759WLNmDZ544gncdNNNyM3NxT333IOSkhJcd911uOaaa/D+++/jb3/7G3JyctTHsNvtWLFiBa6//nqcd955uO222zBkyBDs2bMHu3btantDtM6kv/vd72L69OlwOBy45ZZbkq7z4YcfxmuvvYZJkybhO9/5DpxOJ379618jHA7jkUce6ZN9k56ejssuuwyPPPIIotEohg0bhldffbXt+gjdMX78eKxYsQIPP/wwRo8ejby8PFxxxRX4/ve/j//5n//Bddddhzlz5mD8+PFoamrCBx98gD/96U/49NNPu9yvQPejtps3b8aDDz6IadOmITs7G1u3bsXKlStx9dVX43vf+163nw+dOlgbuub1erFu3TrMnj0bEyZMwN/+9jf89a9/xX333df2dUp396Nk3LhxmD17Np5++mnU1dW1XZX42WefxcyZM3H55Zd3uZ09qTfdjdoCwOOPP46rrroKkyZNwty5cxEMBvHYY49hzJgxnU5gHtD6K2ZzMmuNi73zzjvq/ZJFuNp7+umnzfjx443P5zNpaWnmnHPOMYsXL+4Ql4rH4+aBBx4wQ4YMMT6fz0yZMsXs3LnTFBUVqXG6Vm+++aa56qqrTFpamklJSTHnnnuuefLJJ9vGY7GYWbBggcnNzTU2m61DtA7HxemMMea9994z06dPN6mpqcbv95vLL7/cvPXWW93aP9I2Hu/QoUPmxhtvNBkZGSYQCJibb77ZHD58uNP2SFHbiooKc+2115q0tLROsdiGhgazZMkSM3r0aON2u01OTo65+OKLzc9//nMTiUSMMf+K2j766KNJt+/4dUo+/vhjM23aNJOTk2M8Ho8544wzTElJiQmHw10uSycn1oYTWxta99v+/fvNtGnTjN/vN/n5+Wbp0qUmHo/3aj9Kr0U0GjUPPPCAKS4uNi6XyxQWFpolS5aYUCjU4X5FRUXm2muvTbq93ak3rduAbkRtW7322mvmoosuMl6v12RlZZl///d/N+Xl5d1adqCwGdNHZ/gQERERdQO/dCYiIiJLcfJBREREluLkg4iIiCzFyQcRERFZipMPIiIishQnH0RERGSpE3aRseXLl+PRRx9FRUUFxo0bhyeffBIXXnhh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", + "image/png": "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srIybN68GVOnToXL5cKOHTuwatUqPPzww7jmmmtQUFCA2267DWVlZbjiiitw2WWX4cMPP8TLL7+M/Px89TXsdjuWLVuGK6+8EqeffjpuuOEGDB48GNu2bcPWrVsTB8T48eMBAD/60Y8wbdo0OBwOMa51//3347XXXsN5552HH/7wh3A6nXj88ccRCoXwwAMPdMu2ycrKwqRJk/DAAw8gEolg6NChePXVVxPXR+iI8ePHY9myZbj//vsxZswYFBYW4qKLLsJPfvITPP/887jiiiswe/ZsjB8/Hn6/Hx999BH++te/Yvfu3e1uV6DjUds5c+agsbERkyZNwtChQ1FVVYWnnnoK27Ztw69//ese6VFB/RtrQ/u8Xi/WrFmDWbNmYcKECXj55Zfxj3/8A3feeWfi65SObkfJaaedhlmzZuGJJ55AfX09LrjgAvzrX//Ck08+iRkzZuDCCy9sdzk7U286GrW98sorMW7cONx7773Ys2cPzj77bHz++ed49NFHMXjwYHzve9/r3MbsTb2UsunXWuNi//73v9X7pYpwHe6JJ54w48ePN2lpaSYzM9Occsop5vbbbzcVFRWJ+8RiMXPPPfeYwYMHm7S0NDN58mTz8ccfmxEjRqhxulZvv/22ueSSS0xmZqZJT083p556qnnkkUcS49Fo1MyfP98UFBQYm82WFK3DEXE6Y4z54IMPzLRp00xGRobx+XzmwgsvNO+++26Hto+0jEfat2+fufrqq01OTo7Jzs421157ramoqGizPFLUtqqqylx++eUmMzOzTSy2qanJLFq0yIwZM8a43W6Tn59vzjnnHPPggw+acDhsjPlP1Hbx4sUpl+/I55Q888wzZsqUKaaoqMg4nU6Tm5trpkyZYp577rl2H0v9E2tDz9aG1u22c+dOM3XqVOPz+UxRUZG5++67TSwW69J2lN6LSCRi7rnnHlNaWmpcLpcpKSkxixYtMsFgMOl+I0aMMJdffnnK5e1IvWldBnQwaltbW2tuueUWc/zxxxuPx2Py8/PNddddZ7744ot2H9uX2IzppjN8iIiIiDqA53wQERGRpTj5ICIiIktx8kFERESW4uSDiIiILMXJBxEREVmKkw8iIiKyVI9dZGzp0qVYvHgxqqqqcNppp+GRRx7BWWed1e7j4vE4KioqkJmZyaZbRL3EGIOmpiYMGTKkTf+RntTV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", "text/plain": [ "
" ] From 9dd62846c01ef657efa1f1ed686d7be6556e7e2e Mon Sep 17 00:00:00 2001 From: abigailt Date: Tue, 19 Sep 2023 16:27:44 +0300 Subject: [PATCH 05/26] Support membership black box with no labels (fix #2154) Signed-off-by: abigailt --- .../membership_inference/black_box.py | 372 ++++++++++++------ .../membership_inference/test_black_box.py | 148 +++++-- 2 files changed, 366 insertions(+), 154 deletions(-) diff --git a/art/attacks/inference/membership_inference/black_box.py b/art/attacks/inference/membership_inference/black_box.py index 21758bbe05..3715e55329 100644 --- a/art/attacks/inference/membership_inference/black_box.py +++ b/art/attacks/inference/membership_inference/black_box.py @@ -98,6 +98,7 @@ def __init__( self.epochs = nn_model_epochs self.batch_size = nn_model_batch_size self.learning_rate = nn_model_learning_rate + self.use_label = True self._regressor_model = RegressorMixin in type(self.estimator).__mro__ @@ -108,67 +109,8 @@ def __init__( self.attack_model_type = "None" else: self.default_model = True - if self.attack_model_type == "nn": - import torch - from torch import nn - class MembershipInferenceAttackModel(nn.Module): - """ - Implementation of a pytorch model for learning a membership inference attack. - - The features used are probabilities/logits or losses for the attack training data along with - its true labels. - """ - - def __init__(self, num_classes, num_features=None): - - self.num_classes = num_classes - if num_features: - self.num_features = num_features - else: - self.num_features = num_classes - - super().__init__() - - self.features = nn.Sequential( - nn.Linear(self.num_features, 512), - nn.ReLU(), - nn.Linear(512, 100), - nn.ReLU(), - nn.Linear(100, 64), - nn.ReLU(), - ) - - self.labels = nn.Sequential( - nn.Linear(self.num_classes, 256), - nn.ReLU(), - nn.Linear(256, 64), - nn.ReLU(), - ) - - self.combine = nn.Sequential( - nn.Linear(64 * 2, 1), - ) - - self.output = nn.Sigmoid() - - def forward(self, x_1, label): - """Forward the model.""" - out_x1 = self.features(x_1) - out_l = self.labels(label) - is_member = self.combine(torch.cat((out_x1, out_l), 1)) - return self.output(is_member) - - if self.input_type == "prediction": - num_classes = estimator.nb_classes # type: ignore - self.attack_model = MembershipInferenceAttackModel(num_classes) - else: - if self._regressor_model: - self.attack_model = MembershipInferenceAttackModel(1, num_features=1) - else: - num_classes = estimator.nb_classes # type: ignore - self.attack_model = MembershipInferenceAttackModel(num_classes, num_features=1) - elif self.attack_model_type == "rf": + if self.attack_model_type == "rf": self.attack_model = RandomForestClassifier() elif self.attack_model_type == "gb": self.attack_model = GradientBoostingClassifier() @@ -180,13 +122,15 @@ def forward(self, x_1, label): self.attack_model = KNeighborsClassifier() elif self.attack_model_type == "svm": self.attack_model = SVC(probability=True) + elif attack_model_type != "nn": + raise ValueError("Illegal value for parameter `attack_model_type`.") def fit( # pylint: disable=W0613 self, - x: np.ndarray, - y: np.ndarray, - test_x: np.ndarray, - test_y: np.ndarray, + x: Optional[np.ndarray] = None, + y: Optional[np.ndarray] = None, + test_x: Optional[np.ndarray] = None, + test_y: Optional[np.ndarray] = None, pred: Optional[np.ndarray] = None, test_pred: Optional[np.ndarray] = None, **kwargs @@ -195,10 +139,10 @@ def fit( # pylint: disable=W0613 Train the attack model. :param x: Records that were used in training the target estimator. Can be None if supplying `pred`. - :param y: True labels for `x`. + :param y: True labels for `x`. If not supplied, attack will be based solely on model predictions. :param test_x: Records that were not used in training the target estimator. Can be None if supplying `test_pred`. - :param test_y: True labels for `test_x`. + :param test_y: True labels for `test_x`. If not supplied, attack will be based solely on model predictions. :param pred: Estimator predictions for the records, if not supplied will be generated by calling the estimators' `predict` function. Only relevant for input_type='prediction'. :param test_pred: Estimator predictions for the test records, if not supplied will be generated by calling the @@ -216,28 +160,30 @@ def fit( # pylint: disable=W0613 if test_x is not None and self.estimator.input_shape[0] != test_x.shape[1]: # pragma: no cover raise ValueError("Shape of test_x does not match input_shape of estimator") - if not self._regressor_model: + if y is not None and test_y is not None and not self._regressor_model: y = check_and_transform_label_format(y, nb_classes=self.estimator.nb_classes, return_one_hot=True) test_y = check_and_transform_label_format(test_y, nb_classes=self.estimator.nb_classes, return_one_hot=True) - if x is not None and y.shape[0] != x.shape[0]: # pragma: no cover + if x is not None and y is not None and y.shape[0] != x.shape[0]: # pragma: no cover raise ValueError("Number of rows in x and y do not match") - if pred is not None and y.shape[0] != pred.shape[0]: # pragma: no cover + if pred is not None and y is not None and y.shape[0] != pred.shape[0]: # pragma: no cover raise ValueError("Number of rows in pred and y do not match") - if test_x is not None and test_y.shape[0] != test_x.shape[0]: # pragma: no cover + if test_x is not None and test_y is not None and test_y.shape[0] != test_x.shape[0]: # pragma: no cover raise ValueError("Number of rows in test_x and test_y do not match") - if test_pred is not None and test_y.shape[0] != test_pred.shape[0]: # pragma: no cover + if test_pred is not None and test_y is not None and test_y.shape[0] != test_pred.shape[0]: # pragma: no cover raise ValueError("Number of rows in test_pred and test_y do not match") # Create attack dataset # uses final probabilities/logits - if pred is None: + x_len = 0 + test_len = 0 + if pred is None and x is not None: x_len = x.shape[0] - else: + elif pred is not None: x_len = pred.shape[0] - if test_pred is None: + if test_pred is None and test_x is not None: test_len = test_x.shape[0] - else: + elif test_pred is not None: test_len = test_pred.shape[0] if self.input_type == "prediction": @@ -253,6 +199,8 @@ def fit( # pylint: disable=W0613 test_features = test_pred.astype(np.float32) # only for models with loss elif self.input_type == "loss": + if y is None: + raise ValueError("Cannot compute loss values without y.") if x is not None: # members features = self.estimator.compute_loss(x, y).astype(np.float32).reshape(-1, 1) @@ -288,11 +236,14 @@ def fit( # pylint: disable=W0613 test_labels = np.zeros(test_len) x_1 = np.concatenate((features, test_features)) - x_2 = np.concatenate((y, test_y)) + x_2: Optional[np.ndarray] = None + if y is not None and test_y is not None: + x_2 = np.concatenate((y, test_y)) + if self._regressor_model and x_2 is not None: + x_2 = x_2.astype(np.float32).reshape(-1, 1) y_new = np.concatenate((labels, test_labels)) - - if self._regressor_model: - x_2 = x_2.astype(np.float32).reshape(-1, 1) + if x_2 is None: + self.use_label = False if self.default_model and self.attack_model_type == "nn": import torch @@ -301,37 +252,157 @@ def fit( # pylint: disable=W0613 from torch.utils.data import DataLoader from art.utils import to_cuda - loss_fn = nn.BCELoss() - optimizer = optim.Adam(self.attack_model.parameters(), lr=self.learning_rate) # type: ignore + if x_2 is not None: - attack_train_set = self._get_attack_dataset(f_1=x_1, f_2=x_2, label=y_new) - train_loader = DataLoader(attack_train_set, batch_size=self.batch_size, shuffle=True, num_workers=0) + class MembershipInferenceAttackModel(nn.Module): + """ + Implementation of a pytorch model for learning a membership inference attack. - self.attack_model = to_cuda(self.attack_model) # type: ignore - self.attack_model.train() # type: ignore + The features used are probabilities/logits or losses for the attack training data along with + its true labels. + """ - for _ in range(self.epochs): - for (input1, input2, targets) in train_loader: - input1, input2, targets = to_cuda(input1), to_cuda(input2), to_cuda(targets) - _, input2 = torch.autograd.Variable(input1), torch.autograd.Variable(input2) - targets = torch.autograd.Variable(targets) + def __init__(self, num_classes, num_features=None): - optimizer.zero_grad() - outputs = self.attack_model(input1, input2) # type: ignore - loss = loss_fn(outputs, targets.unsqueeze(1)) + self.num_classes = num_classes + if num_features: + self.num_features = num_features + else: + self.num_features = num_classes - loss.backward() - optimizer.step() - else: + super().__init__() + + self.features = nn.Sequential( + nn.Linear(self.num_features, 512), + nn.ReLU(), + nn.Linear(512, 100), + nn.ReLU(), + nn.Linear(100, 64), + nn.ReLU(), + ) + + self.labels = nn.Sequential( + nn.Linear(self.num_classes, 256), + nn.ReLU(), + nn.Linear(256, 64), + nn.ReLU(), + ) + + self.combine = nn.Sequential( + nn.Linear(64 * 2, 1), + ) + + self.output = nn.Sigmoid() + + def forward(self, x_1, label): + """Forward the model.""" + out_x1 = self.features(x_1) + out_l = self.labels(label) + is_member = self.combine(torch.cat((out_x1, out_l), 1)) + return self.output(is_member) + + if self.input_type == "prediction": + num_classes = self.estimator.nb_classes # type: ignore + self.attack_model = MembershipInferenceAttackModel(num_classes) + else: # loss + if self._regressor_model: + self.attack_model = MembershipInferenceAttackModel(1, num_features=1) + else: + num_classes = self.estimator.nb_classes # type: ignore + self.attack_model = MembershipInferenceAttackModel(num_classes, num_features=1) + + loss_fn = nn.BCELoss() + optimizer = optim.Adam(self.attack_model.parameters(), lr=self.learning_rate) # type: ignore + + attack_train_set = self._get_attack_dataset(f_1=x_1, f_2=x_2, label=y_new) + train_loader = DataLoader(attack_train_set, batch_size=self.batch_size, shuffle=True, num_workers=0) + + self.attack_model = to_cuda(self.attack_model) # type: ignore + self.attack_model.train() # type: ignore + + for _ in range(self.epochs): + for (input1, input2, targets) in train_loader: + input1, input2, targets = to_cuda(input1), to_cuda(input2), to_cuda(targets) + _, input2 = torch.autograd.Variable(input1), torch.autograd.Variable(input2) + targets = torch.autograd.Variable(targets) + + optimizer.zero_grad() + outputs = self.attack_model(input1, input2) # type: ignore + loss = loss_fn(outputs, targets.unsqueeze(1)) + + loss.backward() + optimizer.step() + else: # no label + + class MembershipInferenceAttackModelNoLabel(nn.Module): + """ + Implementation of a pytorch model for learning a membership inference attack. + + The features used are probabilities/logits or losses for the attack training data along with + its true labels. + """ + + def __init__(self, num_features): + + self.num_features = num_features + + super().__init__() + + self.features = nn.Sequential( + nn.Linear(self.num_features, 512), + nn.ReLU(), + nn.Linear(512, 100), + nn.ReLU(), + nn.Linear(100, 64), + nn.ReLU(), + nn.Linear(64, 1), + ) + + self.output = nn.Sigmoid() + + def forward(self, x_1): + """Forward the model.""" + out_x1 = self.features(x_1) + return self.output(out_x1) + + num_classes = self.estimator.nb_classes # type: ignore + self.attack_model = MembershipInferenceAttackModelNoLabel(num_classes) + + loss_fn = nn.BCELoss() + optimizer = optim.Adam(self.attack_model.parameters(), lr=self.learning_rate) # type: ignore + + attack_train_set = self._get_attack_dataset_no_label(f_1=x_1, label=y_new) + train_loader = DataLoader(attack_train_set, batch_size=self.batch_size, shuffle=True, num_workers=0) + + self.attack_model = to_cuda(self.attack_model) # type: ignore + self.attack_model.train() # type: ignore + + for _ in range(self.epochs): + for (input1, targets) in train_loader: + input1, targets = to_cuda(input1), to_cuda(targets) + input1 = torch.autograd.Variable(input1) + targets = torch.autograd.Variable(targets) + + optimizer.zero_grad() + outputs = self.attack_model(input1) # type: ignore + loss = loss_fn(outputs, targets.unsqueeze(1)) + + loss.backward() + optimizer.step() + + else: # not nn y_ready = check_and_transform_label_format(y_new, nb_classes=2, return_one_hot=False) - self.attack_model.fit(np.c_[x_1, x_2], y_ready.ravel()) # type: ignore + if x_2 is not None: + self.attack_model.fit(np.c_[x_1, x_2], y_ready.ravel()) # type: ignore + else: + self.attack_model.fit(x_1, y_ready.ravel()) # type: ignore def infer(self, x: np.ndarray, y: Optional[np.ndarray] = None, **kwargs) -> np.ndarray: """ Infer membership in the training set of the target estimator. :param x: Input records to attack. Can be None if supplying `pred`. - :param y: True labels for `x`. + :param y: True labels for `x`. If not supplied, attack will be based solely on model predictions. :param pred: Estimator predictions for the records, if not supplied will be generated by calling the estimators' `predict` function. Only relevant for input_type='prediction'. :param probabilities: a boolean indicating whether to return the predicted probabilities per class, or just @@ -349,24 +420,22 @@ def infer(self, x: np.ndarray, y: Optional[np.ndarray] = None, **kwargs) -> np.n else: probabilities = False - if y is None: # pragma: no cover - raise ValueError("MembershipInferenceBlackBox requires true labels `y`.") if x is None and pred is None: raise ValueError("Must supply either x or pred") + if y is None and self.use_label: + raise ValueError("y must be provided") + if self.estimator.input_shape is not None and x is not None: # pragma: no cover if self.estimator.input_shape[0] != x.shape[1]: raise ValueError("Shape of x does not match input_shape of estimator") - if not self._regressor_model: + if y is not None and not self._regressor_model: y = check_and_transform_label_format(y, nb_classes=self.estimator.nb_classes, return_one_hot=True) - if y is None: - raise ValueError("None value detected.") - - if x is not None and y.shape[0] != x.shape[0]: # pragma: no cover + if x is not None and y is not None and y.shape[0] != x.shape[0]: # pragma: no cover raise ValueError("Number of rows in x and y do not match") - if pred is not None and y.shape[0] != pred.shape[0]: # pragma: no cover + if pred is not None and y is not None and y.shape[0] != pred.shape[0]: # pragma: no cover raise ValueError("Number of rows in pred and y do not match") if self.input_type == "prediction": @@ -375,6 +444,8 @@ def infer(self, x: np.ndarray, y: Optional[np.ndarray] = None, **kwargs) -> np.n else: features = pred.astype(np.float32) elif self.input_type == "loss": + if y is None: + raise ValueError("Cannot compute loss values without y.") if x is not None: features = self.estimator.compute_loss(x, y).astype(np.float32).reshape(-1, 1) else: @@ -388,7 +459,7 @@ def infer(self, x: np.ndarray, y: Optional[np.ndarray] = None, **kwargs) -> np.n else: raise ValueError("Value of `input_type` not recognized.") - if self._regressor_model: + if y is not None and self._regressor_model: y = y.astype(np.float32).reshape(-1, 1) if self.default_model and self.attack_model_type == "nn": @@ -398,22 +469,39 @@ def infer(self, x: np.ndarray, y: Optional[np.ndarray] = None, **kwargs) -> np.n self.attack_model.eval() # type: ignore predictions: Optional[np.ndarray] = None - test_set = self._get_attack_dataset(f_1=features, f_2=y) - test_loader = DataLoader(test_set, batch_size=self.batch_size, shuffle=False, num_workers=0) - for input1, input2, _ in test_loader: - input1, input2 = to_cuda(input1), to_cuda(input2) - outputs = self.attack_model(input1, input2) # type: ignore - if not probabilities: - predicted = torch.round(outputs) - else: - predicted = outputs - predicted = from_cuda(predicted) - if predictions is None: - predictions = predicted.detach().numpy() - else: - predictions = np.vstack((predictions, predicted.detach().numpy())) + if y is not None and self.use_label: + test_set = self._get_attack_dataset(f_1=features, f_2=y) + test_loader = DataLoader(test_set, batch_size=self.batch_size, shuffle=False, num_workers=0) + for input1, input2, _ in test_loader: + input1, input2 = to_cuda(input1), to_cuda(input2) + outputs = self.attack_model(input1, input2) # type: ignore + if not probabilities: + predicted = torch.round(outputs) + else: + predicted = outputs + predicted = from_cuda(predicted) + + if predictions is None: + predictions = predicted.detach().numpy() + else: + predictions = np.vstack((predictions, predicted.detach().numpy())) + else: + test_set = self._get_attack_dataset_no_label(f_1=features) + test_loader = DataLoader(test_set, batch_size=self.batch_size, shuffle=False, num_workers=0) + for input1, _ in test_loader: + input1 = to_cuda(input1) + outputs = self.attack_model(input1) # type: ignore + if not probabilities: + predicted = torch.round(outputs) + else: + predicted = outputs + predicted = from_cuda(predicted) + if predictions is None: + predictions = predicted.detach().numpy() + else: + predictions = np.vstack((predictions, predicted.detach().numpy())) if predictions is not None: if not probabilities: inferred_return = np.round(predictions) @@ -423,13 +511,19 @@ def infer(self, x: np.ndarray, y: Optional[np.ndarray] = None, **kwargs) -> np.n raise ValueError("No data available.") elif not self.default_model: # assumes the predict method of the supplied model returns probabilities - inferred = self.attack_model.predict(np.c_[features, y]) # type: ignore + if y is not None and self.use_label: + inferred = self.attack_model.predict(np.c_[features, y]) # type: ignore + else: + inferred = self.attack_model.predict(features) # type: ignore if probabilities: inferred_return = inferred else: inferred_return = np.round(inferred) else: - inferred = self.attack_model.predict_proba(np.c_[features, y]) # type: ignore + if y is not None and self.use_label: + inferred = self.attack_model.predict_proba(np.c_[features, y]) # type: ignore + else: + inferred = self.attack_model.predict_proba(features) # type: ignore if probabilities: inferred_return = inferred[:, [1]] else: @@ -470,6 +564,38 @@ def __getitem__(self, idx): return AttackDataset(x_1=f_1, x_2=f_2, y=label) + def _get_attack_dataset_no_label(self, f_1, label=None): + from torch.utils.data.dataset import Dataset + + class AttackDataset(Dataset): + """ + Implementation of a pytorch dataset for membership inference attack. + + The features are probabilities/logits or losses for the attack training data (`x_1`) along with + its true labels (`x_2`). The labels (`y`) are a boolean representing whether this is a member. + """ + + def __init__(self, x_1, y=None): + import torch + + self.x_1 = torch.from_numpy(x_1.astype(np.float64)).type(torch.FloatTensor) + + if y is not None: + self.y = torch.from_numpy(y.astype(np.int8)).type(torch.FloatTensor) + else: + self.y = torch.zeros(x_1.shape[0]) + + def __len__(self): + return len(self.x_1) + + def __getitem__(self, idx): + if idx >= len(self.x_1): # pragma: no cover + raise IndexError("Invalid Index") + + return self.x_1[idx], self.y[idx] + + return AttackDataset(x_1=f_1, y=label) + def _check_params(self) -> None: if self.input_type not in ["prediction", "loss"]: raise ValueError("Illegal value for parameter `input_type`.") diff --git a/tests/attacks/inference/membership_inference/test_black_box.py b/tests/attacks/inference/membership_inference/test_black_box.py index db866c6e67..fb95c684ab 100644 --- a/tests/attacks/inference/membership_inference/test_black_box.py +++ b/tests/attacks/inference/membership_inference/test_black_box.py @@ -48,7 +48,38 @@ def test_black_box_image(art_warning, get_default_mnist_subset, image_dl_estimat @pytest.mark.parametrize("model_type", ["nn", "rf", "gb", "lr", "dt", "knn", "svm"]) -def test_black_box_tabular(art_warning, model_type, tabular_dl_estimator_for_attack, get_iris_dataset): +def test_black_box_tabular(art_warning, model_type, decision_tree_estimator, get_iris_dataset): + try: + classifier = decision_tree_estimator() + attack = MembershipInferenceBlackBox(classifier, attack_model_type=model_type) + backend_check_membership_accuracy(attack, get_iris_dataset, attack_train_ratio, 0.25) + except ARTTestException as e: + art_warning(e) + + +@pytest.mark.parametrize("model_type", ["nn", "rf", "gb", "lr", "dt", "knn", "svm"]) +def test_black_box_tabular_no_label(art_warning, model_type, decision_tree_estimator, get_iris_dataset): + try: + classifier = decision_tree_estimator() + attack = MembershipInferenceBlackBox(classifier, attack_model_type=model_type) + backend_check_membership_accuracy(attack, get_iris_dataset, attack_train_ratio, 0.25, False) + except ARTTestException as e: + art_warning(e) + + +@pytest.mark.parametrize("model_type", ["nn", "rf", "gb", "lr", "dt", "knn", "svm"]) +def test_black_box_loss_tabular(art_warning, model_type, decision_tree_estimator, get_iris_dataset): + try: + classifier = decision_tree_estimator() + if type(classifier).__name__ == "PyTorchClassifier" or type(classifier).__name__ == "TensorFlowV2Classifier": + attack = MembershipInferenceBlackBox(classifier, input_type="loss", attack_model_type=model_type) + backend_check_membership_accuracy(attack, get_iris_dataset, attack_train_ratio, 0.25) + except ARTTestException as e: + art_warning(e) + + +@pytest.mark.parametrize("model_type", ["nn", "rf", "gb", "lr", "dt", "knn", "svm"]) +def test_black_box_tabular_dl(art_warning, model_type, tabular_dl_estimator_for_attack, get_iris_dataset): try: classifier = tabular_dl_estimator_for_attack(MembershipInferenceBlackBox) attack = MembershipInferenceBlackBox(classifier, attack_model_type=model_type) @@ -58,7 +89,17 @@ def test_black_box_tabular(art_warning, model_type, tabular_dl_estimator_for_att @pytest.mark.parametrize("model_type", ["nn", "rf", "gb", "lr", "dt", "knn", "svm"]) -def test_black_box_loss_tabular(art_warning, model_type, tabular_dl_estimator_for_attack, get_iris_dataset): +def test_black_box_tabular_no_label_dl(art_warning, model_type, tabular_dl_estimator_for_attack, get_iris_dataset): + try: + classifier = tabular_dl_estimator_for_attack(MembershipInferenceBlackBox) + attack = MembershipInferenceBlackBox(classifier, attack_model_type=model_type) + backend_check_membership_accuracy(attack, get_iris_dataset, attack_train_ratio, 0.25, False) + except ARTTestException as e: + art_warning(e) + + +@pytest.mark.parametrize("model_type", ["nn", "rf", "gb", "lr", "dt", "knn", "svm"]) +def test_black_box_loss_tabular_dl(art_warning, model_type, tabular_dl_estimator_for_attack, get_iris_dataset): try: classifier = tabular_dl_estimator_for_attack(MembershipInferenceBlackBox) if type(classifier).__name__ == "PyTorchClassifier" or type(classifier).__name__ == "TensorFlowV2Classifier": @@ -115,55 +156,62 @@ def test_black_box_keras_loss(art_warning, get_iris_dataset): art_warning(e) -def test_black_box_tabular_rf(art_warning, tabular_dl_estimator_for_attack, get_iris_dataset): +@pytest.mark.skip_framework("tensorflow", "keras", "scikitlearn", "mxnet", "kerastf") +def test_black_box_with_model(art_warning, tabular_dl_estimator_for_attack, estimator_for_attack, get_iris_dataset): try: classifier = tabular_dl_estimator_for_attack(MembershipInferenceBlackBox) - attack = MembershipInferenceBlackBox(classifier, attack_model_type="rf") - backend_check_membership_accuracy(attack, get_iris_dataset, attack_train_ratio, 0.2) + attack_model = estimator_for_attack(num_features=2 * num_classes_iris) + attack = MembershipInferenceBlackBox(classifier, attack_model=attack_model) + backend_check_membership_accuracy(attack, get_iris_dataset, attack_train_ratio, 0.25) except ARTTestException as e: art_warning(e) -def test_black_box_tabular_gb(art_warning, tabular_dl_estimator_for_attack, get_iris_dataset): +@pytest.mark.parametrize("model_type", ["nn", "rf", "gb", "lr", "dt", "knn", "svm"]) +def test_black_box_tabular_prob(art_warning, decision_tree_estimator, get_iris_dataset, model_type): try: - classifier = tabular_dl_estimator_for_attack(MembershipInferenceBlackBox) - attack = MembershipInferenceBlackBox(classifier, attack_model_type="gb") - # train attack model using only attack_train_ratio of data - backend_check_membership_accuracy(attack, get_iris_dataset, attack_train_ratio, 0.25) + classifier = decision_tree_estimator() + attack = MembershipInferenceBlackBox(classifier, attack_model_type=model_type) + backend_check_membership_probabilities(attack, get_iris_dataset, attack_train_ratio) except ARTTestException as e: art_warning(e) -@pytest.mark.skip_framework("tensorflow", "keras", "scikitlearn", "mxnet", "kerastf") -def test_black_box_with_model(art_warning, tabular_dl_estimator_for_attack, estimator_for_attack, get_iris_dataset): +def test_black_box_with_model_prob(art_warning, decision_tree_estimator, estimator_for_attack, get_iris_dataset): try: - classifier = tabular_dl_estimator_for_attack(MembershipInferenceBlackBox) + classifier = decision_tree_estimator() attack_model = estimator_for_attack(num_features=2 * num_classes_iris) attack = MembershipInferenceBlackBox(classifier, attack_model=attack_model) - backend_check_membership_accuracy(attack, get_iris_dataset, attack_train_ratio, 0.25) + backend_check_membership_probabilities(attack, get_iris_dataset, attack_train_ratio) except ARTTestException as e: art_warning(e) -def test_black_box_tabular_prob_rf(art_warning, tabular_dl_estimator_for_attack, get_iris_dataset): +@pytest.mark.parametrize("model_type", ["nn", "rf", "gb", "lr", "dt", "knn", "svm"]) +def test_black_box_pred(art_warning, model_type, decision_tree_estimator, get_iris_dataset): try: - classifier = tabular_dl_estimator_for_attack(MembershipInferenceBlackBox) - attack = MembershipInferenceBlackBox(classifier, attack_model_type="rf") - backend_check_membership_probabilities(attack, get_iris_dataset, attack_train_ratio) + (x_train, _), (x_test, _) = get_iris_dataset + classifier = decision_tree_estimator() + attack = MembershipInferenceBlackBox(classifier, attack_model_type=model_type) + pred_x = classifier.predict(x_train) + test_pred_x = classifier.predict(x_test) + pred = (pred_x, test_pred_x) + backend_check_membership_accuracy_pred(attack, get_iris_dataset, pred, attack_train_ratio, 0.25) except ARTTestException as e: art_warning(e) -def test_black_box_tabular_prob_nn(art_warning, tabular_dl_estimator_for_attack, get_iris_dataset): +@pytest.mark.parametrize("model_type", ["nn", "rf", "gb", "lr", "dt", "knn", "svm"]) +def test_black_box_tabular_prob_dl(art_warning, tabular_dl_estimator_for_attack, get_iris_dataset, model_type): try: classifier = tabular_dl_estimator_for_attack(MembershipInferenceBlackBox) - attack = MembershipInferenceBlackBox(classifier, attack_model_type="nn") + attack = MembershipInferenceBlackBox(classifier, attack_model_type=model_type) backend_check_membership_probabilities(attack, get_iris_dataset, attack_train_ratio) except ARTTestException as e: art_warning(e) -def test_black_box_with_model_prob( +def test_black_box_with_model_prob_dl( art_warning, tabular_dl_estimator_for_attack, estimator_for_attack, get_iris_dataset ): try: @@ -176,7 +224,7 @@ def test_black_box_with_model_prob( @pytest.mark.parametrize("model_type", ["nn", "rf", "gb", "lr", "dt", "knn", "svm"]) -def test_black_box_pred(art_warning, model_type, tabular_dl_estimator_for_attack, get_iris_dataset): +def test_black_box_pred_dl(art_warning, model_type, tabular_dl_estimator_for_attack, get_iris_dataset): try: (x_train, _), (x_test, _) = get_iris_dataset classifier = tabular_dl_estimator_for_attack(MembershipInferenceBlackBox) @@ -207,7 +255,30 @@ def test_black_box_loss_regression_pred(art_warning, model_type, get_diabetes_da art_warning(e) -def test_errors(art_warning, tabular_dl_estimator_for_attack, get_iris_dataset): +def test_errors(art_warning, decision_tree_estimator, get_iris_dataset): + try: + classifier = decision_tree_estimator() + (x_train, y_train), (x_test, y_test) = get_iris_dataset + pred_test = classifier.predict(x_test) + with pytest.raises(ValueError): + MembershipInferenceBlackBox(classifier, attack_model_type="a") + with pytest.raises(ValueError): + MembershipInferenceBlackBox(classifier, input_type="a") + attack = MembershipInferenceBlackBox(classifier) + with pytest.raises(ValueError): + attack.fit(x_train, y_test, x_test, y_test) + with pytest.raises(ValueError): + attack.fit(x_train, y_train, x_test, y_train) + with pytest.raises(ValueError): + attack.infer(x_train, y_test) + attack.fit(x_train, y_train, x_test, y_test) + with pytest.raises(ValueError): + attack.infer(x_test, y_test=None) + except ARTTestException as e: + art_warning(e) + + +def test_errors_dl(art_warning, tabular_dl_estimator_for_attack, get_iris_dataset): try: classifier = tabular_dl_estimator_for_attack(MembershipInferenceBlackBox) (x_train, y_train), (x_test, y_test) = get_iris_dataset @@ -223,10 +294,17 @@ def test_errors(art_warning, tabular_dl_estimator_for_attack, get_iris_dataset): attack.fit(x_train, y_train, x_test, y_train) with pytest.raises(ValueError): attack.infer(x_train, y_test) + attack.fit(x_train, y_train, x_test, y_test) + with pytest.raises(ValueError): + attack.infer(x_test, y_test=None) attack = MembershipInferenceBlackBox(classifier, input_type="loss") + with pytest.raises(ValueError): + attack.fit(x_train, test_x=x_test) attack.fit(x_train, y_train, x_test, y_test) with pytest.raises(ValueError): attack.infer(None, y_test, pred=pred_test) + with pytest.raises(ValueError): + attack.infer(x_test, y_test=None) except ARTTestException as e: art_warning(e) @@ -240,19 +318,27 @@ def test_classifier_type_check_fail(art_warning): art_warning(e) -def backend_check_membership_accuracy(attack, dataset, attack_train_ratio, approx): +def backend_check_membership_accuracy(attack, dataset, attack_train_ratio, approx, use_label=True): (x_train, y_train), (x_test, y_test) = dataset attack_train_size = int(len(x_train) * attack_train_ratio) attack_test_size = int(len(x_test) * attack_train_ratio) # train attack model using only attack_train_ratio of data - attack.fit( - x_train[:attack_train_size], y_train[:attack_train_size], x_test[:attack_test_size], y_test[:attack_test_size] - ) - - # infer attacked feature on remainder of data - inferred_train = attack.infer(x_train[attack_train_size:], y_train[attack_train_size:]) - inferred_test = attack.infer(x_test[attack_test_size:], y_test[attack_test_size:]) + if use_label: + attack.fit( + x_train[:attack_train_size], + y_train[:attack_train_size], + x_test[:attack_test_size], + y_test[:attack_test_size], + ) + # infer attacked feature on remainder of data + inferred_train = attack.infer(x_train[attack_train_size:], y_train[attack_train_size:]) + inferred_test = attack.infer(x_test[attack_test_size:], y_test[attack_test_size:]) + else: + attack.fit(x_train[:attack_train_size], test_x=x_test[:attack_test_size]) + # infer attacked feature on remainder of data + inferred_train = attack.infer(x_train[attack_train_size:]) + inferred_test = attack.infer(x_test[attack_test_size:]) # check accuracy backend_check_accuracy(inferred_train, inferred_test, approx) From e55f3889bc103c7366e0a740ec5c9282bc268390 Mon Sep 17 00:00:00 2001 From: abigailt Date: Wed, 20 Sep 2023 09:47:22 +0300 Subject: [PATCH 06/26] Fix tests Signed-off-by: abigailt --- .../inference/attribute_inference/test_true_label_baseline.py | 2 +- tests/attacks/inference/membership_inference/test_black_box.py | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/attacks/inference/attribute_inference/test_true_label_baseline.py b/tests/attacks/inference/attribute_inference/test_true_label_baseline.py index 67d84f8116..cc6c77e7bd 100644 --- a/tests/attacks/inference/attribute_inference/test_true_label_baseline.py +++ b/tests/attacks/inference/attribute_inference/test_true_label_baseline.py @@ -605,7 +605,7 @@ def transform_other_feature(x): baseline_inferred_test ) - expected_train_acc = {"nn": 0.81, "rf": 0.95, "gb": 0.95, "lr": 0.81, "dt": 0.94, "knn": 0.87, "svm": 0.81} + expected_train_acc = {"nn": 0.81, "rf": 0.93, "gb": 0.95, "lr": 0.81, "dt": 0.94, "knn": 0.87, "svm": 0.81} expected_test_acc = {"nn": 0.88, "rf": 0.82, "gb": 0.8, "lr": 0.88, "dt": 0.74, "knn": 0.86, "svm": 0.88} assert expected_train_acc[model_type] <= baseline_train_acc diff --git a/tests/attacks/inference/membership_inference/test_black_box.py b/tests/attacks/inference/membership_inference/test_black_box.py index fb95c684ab..c15e46c8b7 100644 --- a/tests/attacks/inference/membership_inference/test_black_box.py +++ b/tests/attacks/inference/membership_inference/test_black_box.py @@ -259,7 +259,6 @@ def test_errors(art_warning, decision_tree_estimator, get_iris_dataset): try: classifier = decision_tree_estimator() (x_train, y_train), (x_test, y_test) = get_iris_dataset - pred_test = classifier.predict(x_test) with pytest.raises(ValueError): MembershipInferenceBlackBox(classifier, attack_model_type="a") with pytest.raises(ValueError): From a5087db207aaa1bf66f6091b751c3141bf4cdb21 Mon Sep 17 00:00:00 2001 From: abigailt Date: Wed, 20 Sep 2023 14:49:54 +0300 Subject: [PATCH 07/26] Fix assert Signed-off-by: abigailt --- .../inference/attribute_inference/test_true_label_baseline.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/attacks/inference/attribute_inference/test_true_label_baseline.py b/tests/attacks/inference/attribute_inference/test_true_label_baseline.py index cc6c77e7bd..2ee742f089 100644 --- a/tests/attacks/inference/attribute_inference/test_true_label_baseline.py +++ b/tests/attacks/inference/attribute_inference/test_true_label_baseline.py @@ -606,7 +606,7 @@ def transform_other_feature(x): ) expected_train_acc = {"nn": 0.81, "rf": 0.93, "gb": 0.95, "lr": 0.81, "dt": 0.94, "knn": 0.87, "svm": 0.81} - expected_test_acc = {"nn": 0.88, "rf": 0.82, "gb": 0.8, "lr": 0.88, "dt": 0.74, "knn": 0.86, "svm": 0.88} + expected_test_acc = {"nn": 0.88, "rf": 0.78, "gb": 0.8, "lr": 0.88, "dt": 0.74, "knn": 0.86, "svm": 0.88} assert expected_train_acc[model_type] <= baseline_train_acc assert expected_test_acc[model_type] <= baseline_test_acc From 57d8ed05d704ab9362ef45653c69eb1882e809fc Mon Sep 17 00:00:00 2001 From: Lei Hsiung Date: Wed, 20 Sep 2023 23:37:15 +0800 Subject: [PATCH 08/26] Fix Coding Style Signed-off-by: Lei Hsiung --- .../evasion/composite_adversarial_attack.py | 296 ++++++++++-------- 1 file changed, 157 insertions(+), 139 deletions(-) diff --git a/art/attacks/evasion/composite_adversarial_attack.py b/art/attacks/evasion/composite_adversarial_attack.py index 70c53c144f..c5ac0469e5 100644 --- a/art/attacks/evasion/composite_adversarial_attack.py +++ b/art/attacks/evasion/composite_adversarial_attack.py @@ -36,11 +36,7 @@ from art.config import ART_NUMPY_DTYPE from art.estimators.estimator import BaseEstimator, LossGradientsMixin from art.estimators.classification.classifier import ClassifierMixin -from art.utils import ( - compute_success, - check_and_transform_label_format, - get_labels_np_array -) +from art.utils import compute_success, check_and_transform_label_format, get_labels_np_array if TYPE_CHECKING: # pylint: disable=C0412 @@ -80,22 +76,22 @@ class CompositeAdversarialAttackPyTorch(EvasionAttack): _estimator_requirements = (BaseEstimator, LossGradientsMixin, ClassifierMixin) # type: ignore def __init__( - self, - classifier: "PyTorchClassifier", - enabled_attack: Tuple = (0, 1, 2, 3, 4, 5), - # Default: Full Attacks; 0: Hue, 1: Saturation, 2: Rotation, 3: Brightness, 4: Contrast, 5: PGD (L-infinity) - hue_epsilon: Tuple = (-np.pi, np.pi), - sat_epsilon: Tuple = (0.7, 1.3), - rot_epsilon: Tuple = (-10, 10), - bri_epsilon: Tuple = (-0.2, 0.2), - con_epsilon: Tuple = (0.7, 1.3), - pgd_epsilon: Tuple = (-8 / 255, 8 / 255), # L-infinity - early_stop: bool = True, - max_iter: int = 5, - max_inner_iter: int = 10, - attack_order: str = "scheduled", - batch_size: int = 1, - verbose: bool = True, + self, + classifier: "PyTorchClassifier", + enabled_attack: Tuple = (0, 1, 2, 3, 4, 5), + # Default: Full Attacks; 0: Hue, 1: Saturation, 2: Rotation, 3: Brightness, 4: Contrast, 5: PGD (L-infinity) + hue_epsilon: Tuple = (-np.pi, np.pi), + sat_epsilon: Tuple = (0.7, 1.3), + rot_epsilon: Tuple = (-10, 10), + bri_epsilon: Tuple = (-0.2, 0.2), + con_epsilon: Tuple = (0.7, 1.3), + pgd_epsilon: Tuple = (-8 / 255, 8 / 255), # L-infinity + early_stop: bool = True, + max_iter: int = 5, + max_inner_iter: int = 10, + attack_order: str = "scheduled", + batch_size: int = 1, + verbose: bool = True, ) -> None: """ Create an instance of the :class:`.CompositeAdversarialAttackPyTorch`. @@ -147,7 +143,7 @@ def __init__( self.epsilons = [hue_epsilon, sat_epsilon, rot_epsilon, bri_epsilon, con_epsilon, pgd_epsilon] self.early_stop = early_stop self.attack_order = attack_order - self.max_iter = max_iter if self.attack_order == 'scheduled' else 1 + self.max_iter = max_iter if self.attack_order == "scheduled" else 1 self.max_inner_iter = max_inner_iter self.targeted = False self.batch_size = batch_size @@ -155,47 +151,79 @@ def __init__( self._check_params() import kornia + self.seq_num = len(self.enabled_attack) # attack_num self.linf_idx = self.enabled_attack.index(5) if 5 in self.enabled_attack else None self.attack_pool = ( - self.caa_hue, self.caa_saturation, self.caa_rotation, self.caa_brightness, self.caa_contrast, self.caa_linf) + self.caa_hue, + self.caa_saturation, + self.caa_rotation, + self.caa_brightness, + self.caa_contrast, + self.caa_linf, + ) self.eps_pool = torch.tensor(self.epsilons, device=self.device) self.attack_pool_base = ( - kornia.enhance.adjust_hue, kornia.enhance.adjust_saturation, kornia.geometry.transform.rotate, - kornia.enhance.adjust_brightness, kornia.enhance.adjust_contrast, self.get_linf_perturbation) + kornia.enhance.adjust_hue, + kornia.enhance.adjust_saturation, + kornia.geometry.transform.rotate, + kornia.enhance.adjust_brightness, + kornia.enhance.adjust_contrast, + self.get_linf_perturbation, + ) self.attack_dict = tuple([self.attack_pool[i] for i in self.enabled_attack]) - self.step_size_pool = [2.5 * ((eps[1] - eps[0]) / 2) / self.max_inner_iter for eps in - self.eps_pool] # 2.5 * ε-test / num_steps + self.step_size_pool = [ + 2.5 * ((eps[1] - eps[0]) / 2) / self.max_inner_iter for eps in self.eps_pool + ] # 2.5 * ε-test / num_steps self._description = "Composite Adversarial Attack" self._is_scheduling = False - self.adv_val_pool = self.eps_space = self.adv_val_space = self.curr_dsm = \ - self.curr_seq = self.is_attacked = self.is_not_attacked = None + self.adv_val_pool = ( + self.eps_space + ) = self.adv_val_space = self.curr_dsm = self.curr_seq = self.is_attacked = self.is_not_attacked = None def _check_params(self) -> None: super()._check_params() if not isinstance(self.enabled_attack, tuple) or not all( - value in [0, 1, 2, 3, 4, 5] for value in self.enabled_attack): + value in [0, 1, 2, 3, 4, 5] for value in self.enabled_attack + ): raise ValueError( "The parameter `enabled_attack` must be a tuple specifying the attack to launch. For simplicity, we use" + " the following abbreviations to specify each attack types. 0: Hue, 1: Saturation, 2: Rotation," + " 3: Brightness, 4: Contrast, 5: PGD(L-infinity). Therefore, `(0,1,2)` means that the attack combines" + " hue, saturation, and rotation; `(0,1,2,3,4)` means the all semantic attacks; `(0,1,2,3,4,5)` means" - + " the full attacks.") - _epsilons_range = [["hue_epsilon", (-np.pi, np.pi), "(-np.pi, np.pi)"], - ["sat_epsilon", (0, np.inf), "(0, np.inf)"], ["rot_epsilon", (-360, 360), "(-360, 360)"], - ["bri_epsilon", (-1, 1), "(-1, 1)"], ["con_epsilon", (0, np.inf), "(0, np.inf)"], - ["pgd_epsilon", (-1, 1), "(-1, 1)"]] + + " the full attacks." + ) + _epsilons_range = [ + ["hue_epsilon", (-np.pi, np.pi), "(-np.pi, np.pi)"], + ["sat_epsilon", (0, np.inf), "(0, np.inf)"], + ["rot_epsilon", (-360, 360), "(-360, 360)"], + ["bri_epsilon", (-1, 1), "(-1, 1)"], + ["con_epsilon", (0, np.inf), "(0, np.inf)"], + ["pgd_epsilon", (-1, 1), "(-1, 1)"], + ] for i in range(6): - if (not isinstance(self.epsilons[i], tuple) or not len(self.epsilons[i]) == 2 or - not (_epsilons_range[i][1][0] <= self.epsilons[i][0] <= - self.epsilons[i][1] <= _epsilons_range[i][1][1])): + if ( + not isinstance(self.epsilons[i], tuple) + or not len(self.epsilons[i]) == 2 + or not ( + _epsilons_range[i][1][0] <= self.epsilons[i][0] <= self.epsilons[i][1] <= _epsilons_range[i][1][1] + ) + ): logger.info( - "The argument `" + _epsilons_range[i][0] + "` must be an interval within " + _epsilons_range[i][2] - + " of type tuple.") + "The argument `" + + _epsilons_range[i][0] + + "` must be an interval within " + + _epsilons_range[i][2] + + " of type tuple." + ) raise ValueError( - "The argument `" + _epsilons_range[i][0] + "` must be an interval within " + _epsilons_range[i][2] - + " of type tuple.") + "The argument `" + + _epsilons_range[i][0] + + "` must be an interval within " + + _epsilons_range[i][2] + + " of type tuple." + ) if not isinstance(self.early_stop, bool): logger.info("The flag `early_stop` has to be of type bool.") @@ -213,7 +241,7 @@ def _check_params(self) -> None: logger.info("The argument `max_inner_iter` must be positive of type int.") raise TypeError("The argument `max_inner_iter` must be positive of type int.") - if self.attack_order not in ('fixed', 'random', 'scheduled'): + if self.attack_order not in ("fixed", "random", "scheduled"): logger.info("The argument `attack_order` should be either `fixed`, `random`, or `scheduled`.") raise ValueError("The argument `attack_order` should be either `fixed`, `random`, or `scheduled`.") @@ -225,12 +253,7 @@ def _check_params(self) -> None: logger.info("The argument `verbose` has to be a Boolean.") raise ValueError("The argument `verbose` has to be a Boolean.") - def _set_targets( - self, - x: np.ndarray, - y: Optional[np.ndarray], - classifier_mixin: bool = True - ) -> np.ndarray: + def _set_targets(self, x: np.ndarray, y: Optional[np.ndarray], classifier_mixin: bool = True) -> np.ndarray: """ Check and set up targets. @@ -265,28 +288,33 @@ def _set_targets( def _setup_attack(self): import torch - hue_space = torch.rand(self.batch_size, device=self.device) * (self.eps_pool[0][1] - self.eps_pool[0][0]) + \ - self.eps_pool[0][0] - sat_space = torch.rand(self.batch_size, device=self.device) * (self.eps_pool[1][1] - self.eps_pool[1][0]) + \ - self.eps_pool[1][0] - rot_space = torch.rand(self.batch_size, device=self.device) * (self.eps_pool[2][1] - self.eps_pool[2][0]) + \ - self.eps_pool[2][0] - bri_space = torch.rand(self.batch_size, device=self.device) * (self.eps_pool[3][1] - self.eps_pool[3][0]) + \ - self.eps_pool[3][0] - con_space = torch.rand(self.batch_size, device=self.device) * (self.eps_pool[4][1] - self.eps_pool[4][0]) + \ - self.eps_pool[4][0] + hue_space = ( + torch.rand(self.batch_size, device=self.device) * (self.eps_pool[0][1] - self.eps_pool[0][0]) + + self.eps_pool[0][0] + ) + sat_space = ( + torch.rand(self.batch_size, device=self.device) * (self.eps_pool[1][1] - self.eps_pool[1][0]) + + self.eps_pool[1][0] + ) + rot_space = ( + torch.rand(self.batch_size, device=self.device) * (self.eps_pool[2][1] - self.eps_pool[2][0]) + + self.eps_pool[2][0] + ) + bri_space = ( + torch.rand(self.batch_size, device=self.device) * (self.eps_pool[3][1] - self.eps_pool[3][0]) + + self.eps_pool[3][0] + ) + con_space = ( + torch.rand(self.batch_size, device=self.device) * (self.eps_pool[4][1] - self.eps_pool[4][0]) + + self.eps_pool[4][0] + ) pgd_space = 0.001 * torch.randn([self.batch_size, 3, 32, 32], device=self.device) self.adv_val_pool = [hue_space, sat_space, rot_space, bri_space, con_space, pgd_space] self.eps_space = [self.eps_pool[i] for i in self.enabled_attack] self.adv_val_space = [self.adv_val_pool[i] for i in self.enabled_attack] - def generate( - self, - x: np.ndarray, - y: Optional[np.ndarray] = None, - **kwargs - ) -> np.ndarray: + def generate(self, x: np.ndarray, y: Optional[np.ndarray] = None, **kwargs) -> np.ndarray: import torch targets = self._set_targets(x, y) @@ -302,8 +330,8 @@ def generate( x_adv = x.copy().astype(ART_NUMPY_DTYPE) # Compute perturbations with batching. - for (batch_id, batch_all) in enumerate( - tqdm(data_loader, desc=self._description, leave=False, disable=not self.verbose) + for batch_id, batch_all in enumerate( + tqdm(data_loader, desc=self._description, leave=False, disable=not self.verbose) ): (batch_x, batch_targets, batch_mask) = batch_all[0], batch_all[1], None batch_index_1, batch_index_2 = batch_id * self.batch_size, (batch_id + 1) * self.batch_size @@ -321,12 +349,7 @@ def generate( return x_adv - def _generate_batch( - self, - x: "torch.Tensor", - y: "torch.Tensor", - mask: "torch.Tensor" - ) -> np.ndarray: + def _generate_batch(self, x: "torch.Tensor", y: "torch.Tensor", mask: "torch.Tensor") -> np.ndarray: """ Generate a batch of adversarial samples and return them in a NumPy array. @@ -347,12 +370,12 @@ def _generate_batch( return self.caa_attack(x, y).cpu().detach().numpy() def _comp_pgd( - self, - data: "torch.Tensor", - labels: "torch.Tensor", - attack_idx: "torch.Tensor", - attack_parameter: "torch.Tensor", - ori_is_attacked: "torch.Tensor" + self, + data: "torch.Tensor", + labels: "torch.Tensor", + attack_idx: "torch.Tensor", + attack_parameter: "torch.Tensor", + ori_is_attacked: "torch.Tensor", ) -> Tuple["torch.Tensor", "torch.Tensor"]: import torch import torch.nn.functional as F @@ -363,96 +386,101 @@ def _comp_pgd( if not self._is_scheduling and self.early_stop: cur_pred = outputs.max(1, keepdim=True)[1].squeeze() - self.is_attacked = torch.logical_or(ori_is_attacked, - cur_pred != labels.max(1, keepdim=True)[1].squeeze()) + self.is_attacked = torch.logical_or( + ori_is_attacked, cur_pred != labels.max(1, keepdim=True)[1].squeeze() + ) with torch.enable_grad(): cost = F.cross_entropy(outputs, labels) _grad = torch.autograd.grad(cost, attack_parameter)[0] if not self._is_scheduling: _grad[self.is_attacked] = 0 - attack_parameter = torch.clamp(attack_parameter + torch.sign(_grad) * self.step_size_pool[attack_idx], - self.eps_pool[attack_idx][0], - self.eps_pool[attack_idx][1]).detach().requires_grad_() + attack_parameter = ( + torch.clamp( + attack_parameter + torch.sign(_grad) * self.step_size_pool[attack_idx], + self.eps_pool[attack_idx][0], + self.eps_pool[attack_idx][1], + ) + .detach() + .requires_grad_() + ) adv_data = self.attack_pool_base[attack_idx](data, attack_parameter) return adv_data, attack_parameter def caa_hue( - self, - data: "torch.Tensor", - hue: "torch.Tensor", - labels: "torch.Tensor" + self, data: "torch.Tensor", hue: "torch.Tensor", labels: "torch.Tensor" ) -> Tuple["torch.Tensor", "torch.Tensor"]: hue = hue.detach().clone() hue[self.is_attacked] = 0 hue.requires_grad_() sur_data = data.detach().requires_grad_() - return self._comp_pgd(data=sur_data, labels=labels, attack_idx=0, attack_parameter=hue, - ori_is_attacked=self.is_attacked.clone()) + return self._comp_pgd( + data=sur_data, labels=labels, attack_idx=0, attack_parameter=hue, ori_is_attacked=self.is_attacked.clone() + ) def caa_saturation( - self, - data: "torch.Tensor", - saturation: "torch.Tensor", - labels: "torch.Tensor" + self, data: "torch.Tensor", saturation: "torch.Tensor", labels: "torch.Tensor" ) -> Tuple["torch.Tensor", "torch.Tensor"]: saturation = saturation.detach().clone() saturation[self.is_attacked] = 1 saturation.requires_grad_() sur_data = data.detach().requires_grad_() - return self._comp_pgd(data=sur_data, labels=labels, attack_idx=1, attack_parameter=saturation, - ori_is_attacked=self.is_attacked.clone()) + return self._comp_pgd( + data=sur_data, + labels=labels, + attack_idx=1, + attack_parameter=saturation, + ori_is_attacked=self.is_attacked.clone(), + ) def caa_rotation( - self, - data: "torch.Tensor", - theta: "torch.Tensor", - labels: "torch.Tensor" + self, data: "torch.Tensor", theta: "torch.Tensor", labels: "torch.Tensor" ) -> Tuple["torch.Tensor", "torch.Tensor"]: theta = theta.detach().clone() theta[self.is_attacked] = 0 theta.requires_grad_() sur_data = data.detach().requires_grad_() - return self._comp_pgd(data=sur_data, labels=labels, attack_idx=2, attack_parameter=theta, - ori_is_attacked=self.is_attacked.clone()) + return self._comp_pgd( + data=sur_data, labels=labels, attack_idx=2, attack_parameter=theta, ori_is_attacked=self.is_attacked.clone() + ) def caa_brightness( - self, - data: "torch.Tensor", - brightness: "torch.Tensor", - labels: "torch.Tensor" + self, data: "torch.Tensor", brightness: "torch.Tensor", labels: "torch.Tensor" ) -> Tuple["torch.Tensor", "torch.Tensor"]: brightness = brightness.detach().clone() brightness[self.is_attacked] = 0 brightness.requires_grad_() sur_data = data.detach().requires_grad_() - return self._comp_pgd(data=sur_data, labels=labels, attack_idx=3, attack_parameter=brightness, - ori_is_attacked=self.is_attacked.clone()) + return self._comp_pgd( + data=sur_data, + labels=labels, + attack_idx=3, + attack_parameter=brightness, + ori_is_attacked=self.is_attacked.clone(), + ) def caa_contrast( - self, - data: "torch.Tensor", - contrast: "torch.Tensor", - labels: "torch.Tensor" + self, data: "torch.Tensor", contrast: "torch.Tensor", labels: "torch.Tensor" ) -> Tuple["torch.Tensor", "torch.Tensor"]: contrast = contrast.detach().clone() contrast[self.is_attacked] = 1 contrast.requires_grad_() sur_data = data.detach().requires_grad_() - return self._comp_pgd(data=sur_data, labels=labels, attack_idx=4, attack_parameter=contrast, - ori_is_attacked=self.is_attacked.clone()) + return self._comp_pgd( + data=sur_data, + labels=labels, + attack_idx=4, + attack_parameter=contrast, + ori_is_attacked=self.is_attacked.clone(), + ) - def caa_linf( - self, - data: "torch.Tensor", - labels: "torch.Tensor" - ) -> "torch.Tensor": + def caa_linf(self, data: "torch.Tensor", labels: "torch.Tensor") -> "torch.Tensor": import torch import torch.nn.functional as F @@ -464,8 +492,9 @@ def caa_linf( if not self._is_scheduling and self.early_stop: cur_pred = outputs.max(1, keepdim=True)[1].squeeze() - self.is_attacked = torch.logical_or(ori_is_attacked, - cur_pred != labels.max(1, keepdim=True)[1].squeeze()) + self.is_attacked = torch.logical_or( + ori_is_attacked, cur_pred != labels.max(1, keepdim=True)[1].squeeze() + ) with torch.enable_grad(): cost = F.cross_entropy(outputs, labels) @@ -474,24 +503,17 @@ def caa_linf( _grad[self.is_attacked] = 0 adv_data = adv_data + self.step_size_pool[5] * torch.sign(_grad) eta = torch.clamp(adv_data - sur_data, min=self.eps_pool[5][0], max=self.eps_pool[5][1]) - adv_data = torch.clamp(sur_data + eta, min=0., max=1.).detach_().requires_grad_() + adv_data = torch.clamp(sur_data + eta, min=0.0, max=1.0).detach_().requires_grad_() return adv_data - def get_linf_perturbation( - self, - data: "torch.Tensor", - noise: "torch.Tensor" - ) -> "torch.Tensor": + def get_linf_perturbation(self, data: "torch.Tensor", noise: "torch.Tensor") -> "torch.Tensor": import torch return torch.clamp(data + noise, 0.0, 1.0) def update_attack_order( - self, - images: "torch.Tensor", - labels: "torch.Tensor", - adv_val: Optional["torch.Tensor"] = None + self, images: "torch.Tensor", labels: "torch.Tensor", adv_val: Optional["torch.Tensor"] = None ) -> None: import torch import torch.nn.functional as F @@ -512,13 +534,13 @@ def sinkhorn_normalization(ori_dsm, n_iters=20): ori_dsm /= ori_dsm.sum(dim=1, keepdim=True) return ori_dsm - if self.attack_order == 'fixed': + if self.attack_order == "fixed": if self.curr_seq is None: self.fixed_order = tuple([self.enabled_attack.index(i) for i in self.fixed_order]) self.curr_seq = torch.tensor(self.fixed_order, device=self.device) - elif self.attack_order == 'random': + elif self.attack_order == "random": self.curr_seq = torch.randperm(self.seq_num) - elif self.attack_order == 'scheduled': + elif self.attack_order == "scheduled": if self.curr_dsm is None: self.curr_dsm = sinkhorn_normalization(torch.rand((self.seq_num, self.seq_num))) self.curr_seq = hungarian(self.curr_dsm) @@ -553,11 +575,7 @@ def sinkhorn_normalization(ori_dsm, n_iters=20): else: raise ValueError() - def caa_attack( - self, - images: "torch.Tensor", - labels: "torch.Tensor" - ) -> "torch.Tensor": + def caa_attack(self, images: "torch.Tensor", labels: "torch.Tensor") -> "torch.Tensor": import torch attack = self.attack_dict From 35281858823a2cbbe6500a940469ab69b92ee3d1 Mon Sep 17 00:00:00 2001 From: Lei Hsiung Date: Sat, 14 Oct 2023 13:00:27 +0800 Subject: [PATCH 09/26] Fix Coding Style and Add Unit test Signed-off-by: Lei Hsiung --- .../evasion/composite_adversarial_attack.py | 244 ++++++++++-------- notebooks/composite-adversarial-attack.ipynb | 25 +- .../test_composite_adversarial_attack.py | 192 ++++++++++++++ 3 files changed, 340 insertions(+), 121 deletions(-) create mode 100644 tests/attacks/test_composite_adversarial_attack.py diff --git a/art/attacks/evasion/composite_adversarial_attack.py b/art/attacks/evasion/composite_adversarial_attack.py index c5ac0469e5..0b6b5d9ca7 100644 --- a/art/attacks/evasion/composite_adversarial_attack.py +++ b/art/attacks/evasion/composite_adversarial_attack.py @@ -27,7 +27,7 @@ import logging -from typing import Optional, Tuple, TYPE_CHECKING +from typing import Optional, Tuple, List, TYPE_CHECKING import numpy as np from tqdm.auto import tqdm @@ -36,7 +36,7 @@ from art.config import ART_NUMPY_DTYPE from art.estimators.estimator import BaseEstimator, LossGradientsMixin from art.estimators.classification.classifier import ClassifierMixin -from art.utils import compute_success, check_and_transform_label_format, get_labels_np_array +from art.utils import compute_success, check_and_transform_label_format if TYPE_CHECKING: # pylint: disable=C0412 @@ -50,8 +50,8 @@ class CompositeAdversarialAttackPyTorch(EvasionAttack): """ Implementation of the composite adversarial attack on image classifiers in PyTorch. The attack is constructed by adversarially perturbing the hue component of the inputs. It uses order scheduling to search for the attack sequence - and uses the iterative gradient sign method to optimize the perturbations in semantic space and Lp-ball (see - `FastGradientMethod` and `BasicIterativeMethod`). + and uses the iterative gradient sign method to optimize the perturbations in semantic space and Lp-ball (see + `FastGradientMethod` and `BasicIterativeMethod`). Note that this attack is intended for only PyTorch image classifiers with RGB images in the range [0, 1] as inputs. @@ -80,12 +80,12 @@ def __init__( classifier: "PyTorchClassifier", enabled_attack: Tuple = (0, 1, 2, 3, 4, 5), # Default: Full Attacks; 0: Hue, 1: Saturation, 2: Rotation, 3: Brightness, 4: Contrast, 5: PGD (L-infinity) - hue_epsilon: Tuple = (-np.pi, np.pi), - sat_epsilon: Tuple = (0.7, 1.3), - rot_epsilon: Tuple = (-10, 10), - bri_epsilon: Tuple = (-0.2, 0.2), - con_epsilon: Tuple = (0.7, 1.3), - pgd_epsilon: Tuple = (-8 / 255, 8 / 255), # L-infinity + hue_epsilon: Tuple[float, float] = (-np.pi, np.pi), + sat_epsilon: Tuple[float, float] = (0.7, 1.3), + rot_epsilon: Tuple[float, float] = (-10.0, 10.0), + bri_epsilon: Tuple[float, float] = (-0.2, 0.2), + con_epsilon: Tuple[float, float] = (0.7, 1.3), + pgd_epsilon: Tuple[float, float] = (-8 / 255, 8 / 255), # L-infinity early_stop: bool = True, max_iter: int = 5, max_inner_iter: int = 10, @@ -145,7 +145,6 @@ def __init__( self.attack_order = attack_order self.max_iter = max_iter if self.attack_order == "scheduled" else 1 self.max_inner_iter = max_inner_iter - self.targeted = False self.batch_size = batch_size self.verbose = verbose self._check_params() @@ -169,20 +168,25 @@ def __init__( kornia.geometry.transform.rotate, kornia.enhance.adjust_brightness, kornia.enhance.adjust_contrast, - self.get_linf_perturbation, ) - self.attack_dict = tuple([self.attack_pool[i] for i in self.enabled_attack]) + self.attack_dict = tuple(self.attack_pool[i] for i in self.enabled_attack) self.step_size_pool = [ 2.5 * ((eps[1] - eps[0]) / 2) / self.max_inner_iter for eps in self.eps_pool ] # 2.5 * ε-test / num_steps self._description = "Composite Adversarial Attack" - self._is_scheduling = False - self.adv_val_pool = ( - self.eps_space - ) = self.adv_val_space = self.curr_dsm = self.curr_seq = self.is_attacked = self.is_not_attacked = None + self._is_scheduling: bool = False + self.eps_space: List = [] + self.adv_val_space: List = [] + self.curr_dsm: "torch.Tensor" = torch.zeros((len(self.enabled_attack), len(self.enabled_attack))) + self.curr_seq: "torch.Tensor" = torch.zeros(len(self.enabled_attack)) + self.is_attacked: "torch.Tensor" = torch.zeros(self.batch_size, device=self.device).bool() + self.is_not_attacked: "torch.Tensor" = torch.ones(self.batch_size, device=self.device).bool() def _check_params(self) -> None: + """ + Check validity of parameters. + """ super()._check_params() if not isinstance(self.enabled_attack, tuple) or not all( value in [0, 1, 2, 3, 4, 5] for value in self.enabled_attack @@ -194,14 +198,14 @@ def _check_params(self) -> None: + " hue, saturation, and rotation; `(0,1,2,3,4)` means the all semantic attacks; `(0,1,2,3,4,5)` means" + " the full attacks." ) - _epsilons_range = [ - ["hue_epsilon", (-np.pi, np.pi), "(-np.pi, np.pi)"], - ["sat_epsilon", (0, np.inf), "(0, np.inf)"], - ["rot_epsilon", (-360, 360), "(-360, 360)"], - ["bri_epsilon", (-1, 1), "(-1, 1)"], - ["con_epsilon", (0, np.inf), "(0, np.inf)"], - ["pgd_epsilon", (-1, 1), "(-1, 1)"], - ] + _epsilons_range = ( + ("hue_epsilon", (-np.pi, np.pi), "(-np.pi, np.pi)"), + ("sat_epsilon", (0.0, np.inf), "(0.0, np.inf)"), + ("rot_epsilon", (-360.0, 360.0), "(-360.0, 360.0)"), + ("bri_epsilon", (-1.0, 1.0), "(-1.0, 1.0)"), + ("con_epsilon", (0.0, np.inf), "(0.0, np.inf)"), + ("pgd_epsilon", (-1.0, 1.0), "(-1.0, 1.0)"), + ) for i in range(6): if ( not isinstance(self.epsilons[i], tuple) @@ -210,29 +214,13 @@ def _check_params(self) -> None: _epsilons_range[i][1][0] <= self.epsilons[i][0] <= self.epsilons[i][1] <= _epsilons_range[i][1][1] ) ): - logger.info( - "The argument `" - + _epsilons_range[i][0] - + "` must be an interval within " - + _epsilons_range[i][2] - + " of type tuple." - ) - raise ValueError( - "The argument `" - + _epsilons_range[i][0] - + "` must be an interval within " - + _epsilons_range[i][2] - + " of type tuple." - ) + logger.info("The argument `%s` must be an interval within %s of type tuple.", _epsilons_range[i][0], _epsilons_range[i][2]) + raise ValueError("The argument `{}` must be an interval within {} of type tuple.".format(_epsilons_range[i][0], _epsilons_range[i][2])) if not isinstance(self.early_stop, bool): logger.info("The flag `early_stop` has to be of type bool.") raise ValueError("The flag `early_stop` has to be of type bool.") - if not isinstance(self.targeted, bool): - logger.info("The flag `targeted` has to be of type bool.") - raise ValueError("The flag `targeted` has to be of type bool.") - if not isinstance(self.max_iter, int) or self.max_iter <= 0: logger.info("The argument `max_iter` must be positive of type int.") raise ValueError("The argument `max_iter` must be positive of type int.") @@ -253,39 +241,10 @@ def _check_params(self) -> None: logger.info("The argument `verbose` has to be a Boolean.") raise ValueError("The argument `verbose` has to be a Boolean.") - def _set_targets(self, x: np.ndarray, y: Optional[np.ndarray], classifier_mixin: bool = True) -> np.ndarray: + def _setup_attack(self): """ - Check and set up targets. - - :param x: An array with all the original inputs. - :param y: Target values (class labels) one-hot-encoded of shape `(nb_samples, nb_classes)` or indices of shape - `(nb_samples,)`. Only provide this parameter if you'd like to use true labels when crafting - adversarial samples. Otherwise, model predictions are used as labels to avoid the "label leaking" - effect (explained in this paper: https://arxiv.org/abs/1611.01236). Default is `None`. - :param classifier_mixin: Whether the estimator is of type `ClassifierMixin`. - :return: The targets. + Set up the initial parameter for each attack component. """ - if classifier_mixin: - if y is not None: - y = check_and_transform_label_format(y, nb_classes=self.estimator.nb_classes) - - if y is None: - # Throw an error if the attack is targeted, but no targets are provided. - if self.targeted: # pragma: no cover - raise ValueError("Target labels `y` need to be provided for a targeted attack.") - - # Use the model predictions as correct outputs. - if classifier_mixin: - targets = get_labels_np_array(self.estimator.predict(x, batch_size=self.batch_size)) - else: - targets = self.estimator.predict(x, batch_size=self.batch_size) - - else: - targets = y - - return targets - - def _setup_attack(self): import torch hue_space = ( @@ -309,15 +268,26 @@ def _setup_attack(self): + self.eps_pool[4][0] ) pgd_space = 0.001 * torch.randn([self.batch_size, 3, 32, 32], device=self.device) - self.adv_val_pool = [hue_space, sat_space, rot_space, bri_space, con_space, pgd_space] self.eps_space = [self.eps_pool[i] for i in self.enabled_attack] - self.adv_val_space = [self.adv_val_pool[i] for i in self.enabled_attack] + self.adv_val_space = [ + [hue_space, sat_space, rot_space, bri_space, con_space, pgd_space][i] for i in self.enabled_attack + ] def generate(self, x: np.ndarray, y: Optional[np.ndarray] = None, **kwargs) -> np.ndarray: + """ + Generate the composite adversarial samples and return them in a Numpy array. + + :param x: An array with the original inputs to be attacked. + :param y: An array with the original labels to be predicted. + :return: An array holding the composite adversarial examples. + """ + if y is None: + raise ValueError("The argument `y` must be provided.") + import torch - targets = self._set_targets(x, y) + y = check_and_transform_label_format(y, nb_classes=self.estimator.nb_classes) dataset = torch.utils.data.TensorDataset( torch.from_numpy(x.astype(ART_NUMPY_DTYPE)), torch.from_numpy(y.astype(ART_NUMPY_DTYPE)), @@ -333,31 +303,25 @@ def generate(self, x: np.ndarray, y: Optional[np.ndarray] = None, **kwargs) -> n for batch_id, batch_all in enumerate( tqdm(data_loader, desc=self._description, leave=False, disable=not self.verbose) ): - (batch_x, batch_targets, batch_mask) = batch_all[0], batch_all[1], None + (batch_x, batch_y) = batch_all[0], batch_all[1] batch_index_1, batch_index_2 = batch_id * self.batch_size, (batch_id + 1) * self.batch_size - x_adv[batch_index_1:batch_index_2] = self._generate_batch( - x=batch_x, - y=batch_targets, - mask=batch_mask, - ) + x_adv[batch_index_1:batch_index_2] = self._generate_batch(x=batch_x, y=batch_y) logger.info( "Success rate of attack: %.2f%%", - 100 * compute_success(self.estimator, x, targets, x_adv, self.targeted, batch_size=self.batch_size), + 100 * compute_success(self.estimator, x, y, x_adv, batch_size=self.batch_size), ) return x_adv - def _generate_batch(self, x: "torch.Tensor", y: "torch.Tensor", mask: "torch.Tensor") -> np.ndarray: + def _generate_batch(self, x: "torch.Tensor", y: "torch.Tensor") -> np.ndarray: """ - Generate a batch of adversarial samples and return them in a NumPy array. + Generate a batch of composite adversarial examples and return them in a NumPy array. - :param x: Original inputs. - :param y: Target values (class labels) one-hot-encoded of shape `(nb_samples, nb_classes)`. - :param mask: A 1D array of masks defining which samples to perturb. Shape needs to be `(nb_samples,)`. - Samples for which the mask is zero will not be adversarially perturbed. - :return: Adversarial examples. + :param x: A tensor of a batch of original inputs to be attacked. + :param y: A tensor of a batch of the original labels to be predicted. + :return: An array holding the composite adversarial examples. """ import torch @@ -373,10 +337,20 @@ def _comp_pgd( self, data: "torch.Tensor", labels: "torch.Tensor", - attack_idx: "torch.Tensor", + attack_idx: int, attack_parameter: "torch.Tensor", ori_is_attacked: "torch.Tensor", ) -> Tuple["torch.Tensor", "torch.Tensor"]: + """ + Compute the adversarial examples for each attack component. + :param data: A tensor of a batch of original inputs to be attacked. + :param labels: A tensor of a batch of the original labels to be predicted. + :param attack_idx: The index of the attack component (one of the enabled attacks) in the attack pool. + :param attack_parameter: Specify the parameter of the attack component. For example, hue shift angle, saturation + factor, etc. + :param ori_is_attacked: Specify whether the perturbed data is already attacked. + :return: The perturbed data and the corresponding attack parameter. + """ import torch import torch.nn.functional as F @@ -411,6 +385,13 @@ def _comp_pgd( def caa_hue( self, data: "torch.Tensor", hue: "torch.Tensor", labels: "torch.Tensor" ) -> Tuple["torch.Tensor", "torch.Tensor"]: + """ + Compute the adversarial examples for hue component. + :param data: A tensor of a batch of original inputs to be attacked. + :param hue: Specify the hue shift angle. + :param labels: A tensor of a batch of the original labels to be predicted. + :return: The perturbed data and the corresponding hue shift angle. + """ hue = hue.detach().clone() hue[self.is_attacked] = 0 hue.requires_grad_() @@ -423,6 +404,13 @@ def caa_hue( def caa_saturation( self, data: "torch.Tensor", saturation: "torch.Tensor", labels: "torch.Tensor" ) -> Tuple["torch.Tensor", "torch.Tensor"]: + """ + Compute the adversarial examples for saturation component. + :param data: A tensor of a batch of original inputs to be attacked. + :param saturation: Specify the saturation factor. + :param labels: A tensor of a batch of the original labels to be predicted. + :return: The perturbed data and the corresponding saturation factor. + """ saturation = saturation.detach().clone() saturation[self.is_attacked] = 1 saturation.requires_grad_() @@ -439,6 +427,13 @@ def caa_saturation( def caa_rotation( self, data: "torch.Tensor", theta: "torch.Tensor", labels: "torch.Tensor" ) -> Tuple["torch.Tensor", "torch.Tensor"]: + """ + Compute the adversarial examples for rotation component. + :param data: A tensor of a batch of original inputs to be attacked. + :param theta: Specify the rotation angle. + :param labels: A tensor of a batch of the original labels to be predicted. + :return: The perturbed data and the corresponding rotation angle. + """ theta = theta.detach().clone() theta[self.is_attacked] = 0 theta.requires_grad_() @@ -451,6 +446,13 @@ def caa_rotation( def caa_brightness( self, data: "torch.Tensor", brightness: "torch.Tensor", labels: "torch.Tensor" ) -> Tuple["torch.Tensor", "torch.Tensor"]: + """ + Compute the adversarial examples for brightness component. + :param data: A tensor of a batch of original inputs to be attacked. + :param brightness: Specify the brightness factor. + :param labels: A tensor of a batch of the original labels to be predicted. + :return: The perturbed data and the corresponding brightness factor. + """ brightness = brightness.detach().clone() brightness[self.is_attacked] = 0 brightness.requires_grad_() @@ -467,6 +469,13 @@ def caa_brightness( def caa_contrast( self, data: "torch.Tensor", contrast: "torch.Tensor", labels: "torch.Tensor" ) -> Tuple["torch.Tensor", "torch.Tensor"]: + """ + Compute the adversarial examples for contrast component. + :param data: A tensor of a batch of original inputs to be attacked. + :param contrast: Specify the contrast factor. + :param labels: A tensor of a batch of the original labels to be predicted. + :return: The perturbed data and the corresponding contrast factor. + """ contrast = contrast.detach().clone() contrast[self.is_attacked] = 1 contrast.requires_grad_() @@ -480,7 +489,16 @@ def caa_contrast( ori_is_attacked=self.is_attacked.clone(), ) - def caa_linf(self, data: "torch.Tensor", labels: "torch.Tensor") -> "torch.Tensor": + def caa_linf( + self, data: "torch.Tensor", eta: "torch.Tensor", labels: "torch.Tensor" + ) -> Tuple["torch.Tensor", "torch.Tensor"]: + """ + Compute the adversarial examples for L-infinity (PGD) component. + :param data: A tensor of a batch of original inputs to be attacked. + :param labels: A tensor of a batch of the original labels to be predicted. + :param eta: The perturbation in the L-infinity ball. + :return: The perturbed data. + """ import torch import torch.nn.functional as F @@ -505,16 +523,17 @@ def caa_linf(self, data: "torch.Tensor", labels: "torch.Tensor") -> "torch.Tenso eta = torch.clamp(adv_data - sur_data, min=self.eps_pool[5][0], max=self.eps_pool[5][1]) adv_data = torch.clamp(sur_data + eta, min=0.0, max=1.0).detach_().requires_grad_() - return adv_data - - def get_linf_perturbation(self, data: "torch.Tensor", noise: "torch.Tensor") -> "torch.Tensor": - import torch - - return torch.clamp(data + noise, 0.0, 1.0) + return adv_data, eta def update_attack_order( - self, images: "torch.Tensor", labels: "torch.Tensor", adv_val: Optional["torch.Tensor"] = None + self, images: "torch.Tensor", labels: "torch.Tensor", adv_val: List ) -> None: + """ + Update the specified attack ordering. + :param images: A tensor of a batch of original inputs to be attacked. + :param labels: A tensor of a batch of the original labels to be predicted. + :param adv_val: Optional; A list of a batch of current attack parameters. + """ import torch import torch.nn.functional as F @@ -535,13 +554,13 @@ def sinkhorn_normalization(ori_dsm, n_iters=20): return ori_dsm if self.attack_order == "fixed": - if self.curr_seq is None: - self.fixed_order = tuple([self.enabled_attack.index(i) for i in self.fixed_order]) + if self.curr_seq.sum() == 0: + self.fixed_order = tuple(self.enabled_attack.index(i) for i in self.fixed_order) self.curr_seq = torch.tensor(self.fixed_order, device=self.device) elif self.attack_order == "random": self.curr_seq = torch.randperm(self.seq_num) elif self.attack_order == "scheduled": - if self.curr_dsm is None: + if self.curr_seq.sum() == 0: self.curr_dsm = sinkhorn_normalization(torch.rand((self.seq_num, self.seq_num))) self.curr_seq = hungarian(self.curr_dsm) self.curr_dsm = self.curr_dsm.detach().requires_grad_() @@ -553,11 +572,8 @@ def sinkhorn_normalization(ori_dsm, n_iters=20): prev_img = adv_img.clone() adv_img = torch.zeros_like(adv_img) for idx in range(self.seq_num): - if idx == self.linf_idx: - adv_img = adv_img + self.curr_dsm[tdx][idx] * self.attack_dict[idx](prev_img, labels) - else: - _adv_img, _ = self.attack_dict[idx](prev_img, adv_val[idx], labels) - adv_img = adv_img + self.curr_dsm[tdx][idx] * _adv_img + _adv_img, _ = self.attack_dict[idx](prev_img, adv_val[idx], labels) + adv_img = adv_img + self.curr_dsm[tdx][idx] * _adv_img self._is_scheduling = False self.max_inner_iter = original_iter_num outputs = self.model(adv_img) @@ -576,6 +592,12 @@ def sinkhorn_normalization(ori_dsm, n_iters=20): raise ValueError() def caa_attack(self, images: "torch.Tensor", labels: "torch.Tensor") -> "torch.Tensor": + """ + The main algorithm to generate the adversarial examples for composite adversarial attack. + :param images: A tensor of a batch of original inputs to be attacked. + :param labels: A tensor of a batch of the original labels to be predicted. + :return: The perturbed data. + """ import torch attack = self.attack_dict @@ -601,10 +623,8 @@ def caa_attack(self, images: "torch.Tensor", labels: "torch.Tensor") -> "torch.T for tdx in range(self.seq_num): idx = self.curr_seq[tdx] - if idx == self.linf_idx: - adv_img = attack[idx](adv_img, labels) - else: - adv_img, adv_val_updated = attack[idx](adv_img, adv_val[idx], labels) + adv_img, adv_val_updated = attack[idx](adv_img, adv_val[idx], labels) + if idx != self.linf_idx: adv_val[idx] = adv_val_updated outputs = self.model(adv_img) diff --git a/notebooks/composite-adversarial-attack.ipynb b/notebooks/composite-adversarial-attack.ipynb index 787108aa4c..89156d743b 100644 --- a/notebooks/composite-adversarial-attack.ipynb +++ b/notebooks/composite-adversarial-attack.ipynb @@ -28,7 +28,6 @@ "import numpy as np\n", "import torch.nn as nn\n", "import torch.optim as optim\n", - "\n", "from art.attacks.evasion import CompositeAdversarialAttackPyTorch\n", "from art.estimators.classification import PyTorchClassifier\n", "from art.utils import load_cifar10\n", @@ -91,7 +90,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Accuracy on the benign test set: 46.39%\n" + "Accuracy on the benign test set: 60.440000000000005%\n" ] } ], @@ -117,10 +116,10 @@ "- `classifier`: A trained PyTorch classifier.\n", "- `enabled_attack`: Attack pool selection, and attack order designation for `fixed` order. For simplicity, we use the following abbreviations to specify each attack type. 0: Hue, 1: Saturation, 2: Rotation, 3: Brightness, 4: Contrast, 5: PGD ($\\ell_\\infty$).\n", "- `hue_epsilon`: The boundary of the hue perturbation. The value is expected to be in the interval `[-np.pi, np.pi]`. Perturbation of `0` means no shift and `-np.pi` and `np.pi` give a complete reversal of the hue channel in the HSV color space in the positive and negative directions, respectively. See `kornia.enhance.adjust_hue` for more details.\n", - "- `sat_epsilon`: The boundary of the saturation perturbation. The value is expected to be in the interval `[0, infinity]`. The perturbation of `0` gives a black-and-white image, `1` gives the original image, and `2` enhances the saturation by a factor of 2. See `kornia.geometry.transform.rotate` for more details.\n", + "- `sat_epsilon`: The boundary of the saturation perturbation. The value is expected to be in the interval `[0.0, infinity]`. The perturbation of `0.0` gives a black-and-white image, `1.0` gives the original image, and `2.0` enhances the saturation by a factor of 2. See `kornia.geometry.transform.rotate` for more details.\n", "- `rot_epsilon`: The boundary of the rotation perturbation (in degrees). Positive values mean counter-clockwise rotation. See `kornia.geometry.transform.rotate` for more details.\n", - "- `bri_epsilon`: The boundary of the brightness perturbation. The value is expected to be in the interval `[-1, 1]`. Perturbation of `0` means no shift, `-1` gives a complete black image, and `1` gives a complete white image. See `kornia.enhance.adjust_brightness` for more details.\n", - "- `con_epsilon`: The boundary of the contrast perturbation. The value is expected to be in the interval `[0, infinity]`. Perturbation of `0` gives a complete black image, `1` does not modify the image, and any other value modifies the brightness by this factor. See `kornia.enhance.adjust_contrast` for more details.\n", + "- `bri_epsilon`: The boundary of the brightness perturbation. The value is expected to be in the interval `[-1.0, 1.0]`. Perturbation of `0.0` means no shift, `-1.0` gives a complete black image, and `1.0` gives a complete white image. See `kornia.enhance.adjust_brightness` for more details.\n", + "- `con_epsilon`: The boundary of the contrast perturbation. The value is expected to be in the interval `[0.0, infinity]`. Perturbation of `0.0` gives a complete black image, `1` does not modify the image, and any other value modifies the brightness by this factor. See `kornia.enhance.adjust_contrast` for more details.\n", "- `pgd_epsilon`: The maximum perturbation that the attacker can introduce in the L-infinity ball.\n", "- `early_stop`: When True, the attack will stop if the perturbed example is classified incorrectly by the classifier.\n", "- `max_iter`: The maximum number of iterations for attack order optimization.\n", @@ -143,7 +142,7 @@ "version_minor": 0 }, "text/plain": [ - "Composite Adversarial Attack: 0%| | 0/157 [00:00" ] @@ -235,7 +234,7 @@ }, { "data": { - "image/png": "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", + "image/png": "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4Pf7B/xx4djRORw7OHZ0Ro+OG93zndjut27dOuVwONTatWvVZ599pu666y6Vnp6uqqure3vTDNXY2Kh27NihduzYoQCoX/ziF2rHjh3qyJEjSimlfvazn6n09HT18ssvq127dqmbb75ZlZSUqJaWll7e8p519913q7S0NLV582ZVVVUVvTU3N0cf893vflcNHTpUvfPOO+rjjz9WU6ZMUVOmTOnFrTbGAw88oMrKylR5ebnatWuXeuCBB5TJZFJvvvmmUmrgHxeOHadx7IiPY0d8Ro8bfXbyoZRSTz31lBo6dKiy2+3qkksuUVu3bu3tTTLcu+++qwC0u82bN08pdToy9+Mf/1jl5eUph8OhrrnmGrVv377e3WgDxDsmANSaNWuij2lpaVHf+973VEZGhkpOTla33HKLqqqq6r2NNsi3vvUtNWzYMGW321VOTo665pprogOIUoPjuHDs4Ngh4dgRn9Hjhkkppbr2mQkRERFR4vrkdz6IiIho4OLkg4iIiAzFyQcREREZipMPIiIiMhQnH0RERGQoTj6IiIjIUJx8EBERkaE4+SAiIiJDcfJBREREhuLkg4iIiAzFyQcREREZ6v8HcWTehkygWVcAAAAASUVORK5CYII=", "text/plain": [ "
" ] @@ -245,7 +244,7 @@ }, { "data": { - "image/png": "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srIybN68GVOnToXL5cKOHTuwatUqPPzww7jmmmtQUFCA2267DWVlZbjiiitw2WWX4cMPP8TLL7+M/Px89TXsdjuWLVuGK6+8EqeffjpuuOEGDB48GNu2bcPWrVsTB8T48eMBAD/60Y8wbdo0OBwOMa51//3347XXXsN5552HH/7wh3A6nXj88ccRCoXwwAMPdMu2ycrKwqRJk/DAAw8gEolg6NChePXVVxPXR+iI8ePHY9myZbj//vsxZswYFBYW4qKLLsJPfvITPP/887jiiiswe/ZsjB8/Hn6/Hx999BH++te/Yvfu3e1uV6DjUds5c+agsbERkyZNwtChQ1FVVYWnnnoK27Ztw69//ese6VFB/RtrQ/u8Xi/WrFmDWbNmYcKECXj55Zfxj3/8A3feeWfi65SObkfJaaedhlmzZuGJJ55AfX09LrjgAvzrX//Ck08+iRkzZuDCCy9sdzk7U286GrW98sorMW7cONx7773Ys2cPzj77bHz++ed49NFHMXjwYHzve9/r3MbsTb2UsunXWuNi//73v9X7pYpwHe6JJ54w48ePN2lpaSYzM9Occsop5vbbbzcVFRWJ+8RiMXPPPfeYwYMHm7S0NDN58mTz8ccfmxEjRqhxulZvv/22ueSSS0xmZqZJT083p556qnnkkUcS49Fo1MyfP98UFBQYm82WFK3DEXE6Y4z54IMPzLRp00xGRobx+XzmwgsvNO+++26Hto+0jEfat2+fufrqq01OTo7Jzs421157ramoqGizPFLUtqqqylx++eUmMzOzTSy2qanJLFq0yIwZM8a43W6Tn59vzjnnHPPggw+acDhsjPlP1Hbx4sUpl+/I55Q888wzZsqUKaaoqMg4nU6Tm5trpkyZYp577rl2H0v9E2tDz9aG1u22c+dOM3XqVOPz+UxRUZG5++67TSwW69J2lN6LSCRi7rnnHlNaWmpcLpcpKSkxixYtMsFgMOl+I0aMMJdffnnK5e1IvWldBnQwaltbW2tuueUWc/zxxxuPx2Py8/PNddddZ7744ot2H9uX2IzppjN8iIiIiDqA53wQERGRpTj5ICIiIktx8kFERESW4uSDiIiILMXJBxEREVmKkw8iIiKyVI9dZGzp0qVYvHgxqqqqcNppp+GRRx7BWWed1e7j4vE4KioqkJmZyaZbRL3EGIOmpiYMGTKkTf+RntTV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", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAh8AAAEjCAYAAACSDWOaAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/OQEPoAAAACXBIWXMAAA9hAAAPYQGoP6dpAABL2ElEQVR4nO3deZRU5bU+/qfmqq6eoelmaKABQcWACSriBCqCqLli0ESTtS6YRI0BEkXjFb+JRHSlE/EmGEUSk1wwWTHkkisxGsUBBa8RiSL8UBREZuiBsXqorvm8vz+83aHo2rsHuk8PPJ+1ei2tXXWmOmfXyzlnn+0wxhgQERER2cTZ1QtAREREpxcOPoiIiMhWHHwQERGRrTj4ICIiIltx8EFERES24uCDiIiIbMXBBxEREdmKgw8iIiKyFQcfREREZCsOPnqooUOHYtasWU3/v3btWjgcDqxdu7bD5uFwOPDjH/+4w6bXGd577z1cdNFFCAaDcDgc2Lx5c1cvElGX6s25YdasWcjOzu7w6S5atAjDhg2Dy+XCueee2+HTp+Y4+GiH5cuXw+FwNP35/X6MHDkSc+bMQXV1dVcvXpu89NJL3X6AIUkkErjppptw7Ngx/OIXv8Af/vAHDBkyBE899RSWL1/e1YuH+vp6LFiwAFdffTUKCwvhcDi6xXJR52Fu6HleffVV3Hfffbj44ouxbNky/OQnP+nqRVJFo1GUl5fj7LPPRlZWFgYOHIibbroJW7du7epFaxN3Vy9AT7Zw4UKUlZUhGo3i7bffxtKlS/HSSy/ho48+QlZWlq3LctlllyESicDr9bbpcy+99BKWLFmSMclEIhG43d13F9m5cyf27t2L3/zmN/j2t7/d9PpTTz2Fvn37pv3rryscOXIECxcuxODBgzF27NgO/ZcndW/MDT3HG2+8AafTid/97ndt3kZd4Rvf+Ab+9re/4bbbbsOXvvQlVFRUYMmSJZgwYQI+/PBDDBkypKsXsVV6x97TRaZNm4bzzjsPAPDtb38bffr0wc9//nM8//zzuOWWWzJ+JhwOIxgMdviyOJ1O+P3+Dp1mR0+vox06dAgAkJ+f3+nzSiaTsCyrTcmpf//+qKysRElJCd5//32cf/75nbiE1J0wN/Qchw4dQiAQ6LCBhzEG0WgUgUCgQ6Z3ooMHD+K5557Dvffei0WLFjW9fumll+KKK67Ac889h7vvvrvD59sZeNmlA11xxRUAgN27dwP41/XJnTt34pprrkFOTg6+8Y1vAAAsy8LixYsxevRo+P1+FBcX44477sDx48fTpmmMwSOPPIJBgwYhKysLl19+ecbTa9J13Q0bNuCaa65BQUEBgsEgxowZg8cff7xp+ZYsWQIAaaeKG2W6rrtp0yZMmzYNubm5yM7OxpVXXol333037T2Np57/8Y9/YN68eSgqKkIwGMQNN9yAw4cPt7gdt2zZglmzZmHYsGHw+/0oKSnBN7/5TRw9erTpPbNmzcLEiRMBADfddBMcDgcmTZqEoUOHYuvWrVi3bl3T+kyaNKnpc6FQCHfddRdKS0vh8/kwYsQI/OxnP4NlWU3v2bNnDxwOBx577DEsXrwYw4cPh8/nw8cffwwA2LZtG/bt29fievh8PpSUlLT4Pur9mBs+d6q5odGuXbswdepUBINBDBgwAAsXLsTJDdpbsx0dDgeWLVuGcDjctI6Nl0aTySQefvjhpuN/6NCheOCBBxCLxdLmM3ToUFx33XV45ZVXcN555yEQCODXv/41gNblGwCorKzEtm3bkEgk1PWuq6sDABQXF6e93r9/fwDolAFPZ+GZjw60c+dOAECfPn2aXksmk5g6dSouueQSPPbYY02nXO+44w4sX74ct956K773ve9h9+7dePLJJ7Fp0yb84x//gMfjAQA8+OCDeOSRR3DNNdfgmmuuwQcffIApU6YgHo+3uDyvvfYarrvuOvTv3x/f//73UVJSgk8++QQvvvgivv/97+OOO+5ARUUFXnvtNfzhD39ocXpbt27FpZdeitzcXNx3333weDz49a9/jUmTJmHdunUYP3582vvnzp2LgoICLFiwAHv27MHixYsxZ84c/PnPf25xuXft2oVbb70VJSUl2Lp1K55++mls3boV7777LhwOB+644w4MHDgQP/nJT/C9730P559/PoqLixEOhzF37lxkZ2fj//2//wfgXwdqQ0MDJk6ciIMHD+KOO+7A4MGD8c4772D+/PmorKzE4sWL05Zj2bJliEajuP322+Hz+VBYWAgAOOusszBx4kReRqFWY27omNwAAKlUCldffTUuvPBCPProo1i9ejUWLFiAZDKJhQsXNr2vNdvxD3/4A55++mn885//xG9/+1sAwEUXXQTg8zNWzzzzDG688Ubcc8892LBh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Rre87NK3b1+4XK5md9JWV1ejpKSki5aq+2ncFqfzdpozZw5efPFFvPnmmxg0aFDT6yUlJYjH4wiFQmnvP122jdfrxYgRIzBu3DiUl5dj7NixePzxx3v9dmHuaB3mDuaOTOzMG91y8OH1ejFu3DisWbOm6TXLsrBmzRpMmDChC5eseykrK0NJSUnadqqtrcWGDRt6/XYyxmDOnDlYtWoV3njjDZSVlaXFx40bB4/Hk7Zttm/fjn379vX6bZOJZVmIxWK9frswd7QOcwdzR2t0at7omHtiO96KFSuMz+czy5cvNx9//LG5/fbbTX5+vqmqqurqRbNVXV2d2bRpk9m0aZMBYH7+85+bTZs2mb179xpjjPnpT39q8vPzzfPPP2+2bNlirr/+elNWVmYikUgXL3nnuvPOO01eXp5Zu3atqaysbPpraGhoes93vvMdM3jwYPPGG2+Y999/30yYMMFMmDChC5faHvfff79Zt26d2b17t9myZYu5//77jcPhMK+++qoxpvdvF+aOzzF3ZMbckZndeaPbDj6MMeaJJ54wgwcPNl6v11xwwQXm3Xff7epFst2bb75pADT7mzlzpjHm85K5H/3oR6a4uNj4fD5z5ZVXmu3bt3ftQtsg0zYBYJYtW9b0nkgkYr773e+agoICk5WVZW644QZTWVnZdQttk29+85tmyJAhxuv1mqKiInPllVc2JRBjTo/twtzB3CFh7sjM7rzhMMaY9p0zISIiImq7bnnPBxEREfVeHHwQERGRrTj4ICIiIltx8EFERES24uCDiIiIbMXBBxEREdmKgw8iIiKyFQcfREREZCsOPoiIiMhWHHwQERGRrTj4ICIiIlv9//uLpd07WEAMAAAAAElFTkSuQmCC", "text/plain": [ "
" ] @@ -257,6 +256,14 @@ "source": [ "visualise(x_test, x_test_adv, predictions_benign, predictions_adv, y_test)" ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7eab976f-84ab-4a4e-927a-a0761907517b", + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { diff --git a/tests/attacks/test_composite_adversarial_attack.py b/tests/attacks/test_composite_adversarial_attack.py new file mode 100644 index 0000000000..769b195546 --- /dev/null +++ b/tests/attacks/test_composite_adversarial_attack.py @@ -0,0 +1,192 @@ +# MIT License +# +# Copyright (C) The Adversarial Robustness Toolbox (ART) Authors 2023 +# +# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated +# documentation files (the "Software"), to deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit +# persons to whom the Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the +# Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +import logging + +import numpy as np +import pytest +import torch + +from art.attacks.evasion import CompositeAdversarialAttackPyTorch +from art.estimators.estimator import BaseEstimator, LossGradientsMixin +from art.estimators.classification.classifier import ClassifierMixin + +from tests.attacks.utils import backend_test_classifier_type_check_fail +from tests.utils import ARTTestException, get_cifar10_image_classifier_pt + +logger = logging.getLogger(__name__) + + +@pytest.fixture() +def fix_get_cifar10_subset(get_cifar10_dataset): + (x_train_cifar10, y_train_cifar10), (x_test_cifar10, y_test_cifar10) = get_cifar10_dataset + n_train = 100 + n_test = 11 + yield x_train_cifar10[:n_train], y_train_cifar10[:n_train], x_test_cifar10[:n_test], y_test_cifar10[:n_test] + + +@pytest.mark.skip_framework( + "tensorflow1", "tensorflow2", "tensorflow2v1", "keras", "non_dl_frameworks", "mxnet", "kerastf" +) +def test_generate(art_warning, fix_get_cifar10_subset): + print("test_generate") + try: + (x_train, y_train, x_test, y_test) = fix_get_cifar10_subset + + classifier = get_cifar10_image_classifier_pt(from_logits=False, load_init=True) + attack = CompositeAdversarialAttackPyTorch(classifier) + + x_train_adv = attack.generate(x=x_test, y=y_test) + + assert x_train.shape == x_train_adv.shape + assert np.min(x_train_adv) >= 0.0 + assert np.max(x_train_adv) <= 1.0 + + except ARTTestException as e: + art_warning(e) + + +@pytest.mark.skip_framework( + "tensorflow1", "tensorflow2", "tensorflow2v1", "keras", "non_dl_frameworks", "mxnet", "kerastf" +) +def test_check_params(art_warning): + try: + classifier = get_cifar10_image_classifier_pt(from_logits=False, load_init=True) + + with pytest.raises(TypeError): + _ = CompositeAdversarialAttackPyTorch(classifier, enabled_attack=[0, 1, 2, 3, 4]) + with pytest.raises(ValueError): + _ = CompositeAdversarialAttackPyTorch(classifier, enabled_attack=(0, 1, 2, 3, 4, 5, 6, 7)) + + with pytest.raises(ValueError): + _ = CompositeAdversarialAttackPyTorch(classifier, hue_epsilon=(-10.0, 0.0)) + with pytest.raises(ValueError): + _ = CompositeAdversarialAttackPyTorch(classifier, hue_epsilon=(0.0, 10.0)) + with pytest.raises(ValueError): + _ = CompositeAdversarialAttackPyTorch(classifier, hue_epsilon=(-1, 2.0)) + with pytest.raises(ValueError): + _ = CompositeAdversarialAttackPyTorch(classifier, hue_epsilon=3.14) + with pytest.raises(ValueError): + _ = CompositeAdversarialAttackPyTorch(classifier, hue_epsilon=(0.0, 10.0, 20.0)) + with pytest.raises(ValueError): + _ = CompositeAdversarialAttackPyTorch(classifier, hue_epsilon=("1.0", 2.0)) + + with pytest.raises(ValueError): + _ = CompositeAdversarialAttackPyTorch(classifier, sat_epsilon=(-10.0, 0.0)) + with pytest.raises(ValueError): + _ = CompositeAdversarialAttackPyTorch(classifier, sat_epsilon=(0.0, -10.0)) + with pytest.raises(ValueError): + _ = CompositeAdversarialAttackPyTorch(classifier, sat_epsilon=(1, 2.0)) + with pytest.raises(ValueError): + _ = CompositeAdversarialAttackPyTorch(classifier, sat_epsilon=2.0) + with pytest.raises(ValueError): + _ = CompositeAdversarialAttackPyTorch(classifier, sat_epsilon=(0.0, 10.0, 20.0)) + with pytest.raises(ValueError): + _ = CompositeAdversarialAttackPyTorch(classifier, sat_epsilon=("1.0", 2.0)) + + with pytest.raises(ValueError): + _ = CompositeAdversarialAttackPyTorch(classifier, rot_epsilon=(-450.0, 359)) + with pytest.raises(ValueError): + _ = CompositeAdversarialAttackPyTorch(classifier, rot_epsilon=(10.0, -10.0)) + with pytest.raises(ValueError): + _ = CompositeAdversarialAttackPyTorch(classifier, rot_epsilon=(1.0, 2)) + with pytest.raises(ValueError): + _ = CompositeAdversarialAttackPyTorch(classifier, rot_epsilon=10) + with pytest.raises(ValueError): + _ = CompositeAdversarialAttackPyTorch(classifier, rot_epsilon=(0.0, 10.0, 20.0)) + with pytest.raises(ValueError): + _ = CompositeAdversarialAttackPyTorch(classifier, rot_epsilon=("10", 20.0)) + + with pytest.raises(ValueError): + _ = CompositeAdversarialAttackPyTorch(classifier, bri_epsilon=(-10.0, 0.0)) + with pytest.raises(ValueError): + _ = CompositeAdversarialAttackPyTorch(classifier, bri_epsilon=(0.0, 10.0)) + with pytest.raises(ValueError): + _ = CompositeAdversarialAttackPyTorch(classifier, bri_epsilon=(-1, 1.0)) + with pytest.raises(ValueError): + _ = CompositeAdversarialAttackPyTorch(classifier, bri_epsilon=1.0) + with pytest.raises(ValueError): + _ = CompositeAdversarialAttackPyTorch(classifier, bri_epsilon=(0.0, 10.0, 20.0)) + with pytest.raises(ValueError): + _ = CompositeAdversarialAttackPyTorch(classifier, bri_epsilon=("1.0", 2.0)) + + with pytest.raises(ValueError): + _ = CompositeAdversarialAttackPyTorch(classifier, con_epsilon=(-10.0, 10.0)) + with pytest.raises(ValueError): + _ = CompositeAdversarialAttackPyTorch(classifier, con_epsilon=(0.0, -10.0)) + with pytest.raises(ValueError): + _ = CompositeAdversarialAttackPyTorch(classifier, con_epsilon=(1, 2.0)) + with pytest.raises(ValueError): + _ = CompositeAdversarialAttackPyTorch(classifier, con_epsilon=2.0) + with pytest.raises(ValueError): + _ = CompositeAdversarialAttackPyTorch(classifier, con_epsilon=(0.0, 10.0, 20.0)) + with pytest.raises(ValueError): + _ = CompositeAdversarialAttackPyTorch(classifier, con_epsilon=("1.0", 2.0)) + + with pytest.raises(ValueError): + _ = CompositeAdversarialAttackPyTorch(classifier, pgd_epsilon=(-0.5, 0)) + with pytest.raises(ValueError): + _ = CompositeAdversarialAttackPyTorch(classifier, pgd_epsilon=(8 / 255, -8 / 255)) + with pytest.raises(ValueError): + _ = CompositeAdversarialAttackPyTorch(classifier, pgd_epsilon=(-2, 1)) + with pytest.raises(ValueError): + _ = CompositeAdversarialAttackPyTorch(classifier, pgd_epsilon=8 / 255) + with pytest.raises(ValueError): + _ = CompositeAdversarialAttackPyTorch(classifier, pgd_epsilon=(0.0, 10.0, 20.0)) + with pytest.raises(ValueError): + _ = CompositeAdversarialAttackPyTorch(classifier, pgd_epsilon=("2/255", 3 / 255)) + + with pytest.raises(ValueError): + _ = CompositeAdversarialAttackPyTorch(classifier, early_stop="true") + with pytest.raises(ValueError): + _ = CompositeAdversarialAttackPyTorch(classifier, early_stop=1) + + with pytest.raises(ValueError): + _ = CompositeAdversarialAttackPyTorch(classifier, max_iter="max") + with pytest.raises(ValueError): + _ = CompositeAdversarialAttackPyTorch(classifier, max_iter=-5) + with pytest.raises(ValueError): + _ = CompositeAdversarialAttackPyTorch(classifier, max_iter=2.5) + + with pytest.raises(ValueError): + _ = CompositeAdversarialAttackPyTorch(classifier, max_inner_iter="max") + with pytest.raises(ValueError): + _ = CompositeAdversarialAttackPyTorch(classifier, max_inner_iter=-5) + with pytest.raises(ValueError): + _ = CompositeAdversarialAttackPyTorch(classifier, max_inner_iter=2.5) + + with pytest.raises(ValueError): + _ = CompositeAdversarialAttackPyTorch(classifier, attack_order="schedule") + + with pytest.raises(ValueError): + _ = CompositeAdversarialAttackPyTorch(classifier, batch_size=-1) + + with pytest.raises(ValueError): + _ = CompositeAdversarialAttackPyTorch(classifier, verbose="true") + + except ARTTestException as e: + art_warning(e) + + +@pytest.mark.framework_agnostic +def test_classifier_type_check_fail(art_warning): + try: + backend_test_classifier_type_check_fail( + CompositeAdversarialAttackPyTorch, [BaseEstimator, LossGradientsMixin, ClassifierMixin] + ) + except ARTTestException as e: + art_warning(e) From 03aaeb7630838af1607590e5ff3026a7c9335717 Mon Sep 17 00:00:00 2001 From: Lei Hsiung Date: Mon, 16 Oct 2023 23:23:57 +0800 Subject: [PATCH 10/26] Fix style check and unit test Signed-off-by: Lei Hsiung --- .../evasion/composite_adversarial_attack.py | 46 +++++++++--- .../test_composite_adversarial_attack.py | 74 ++++++++++--------- 2 files changed, 74 insertions(+), 46 deletions(-) diff --git a/art/attacks/evasion/composite_adversarial_attack.py b/art/attacks/evasion/composite_adversarial_attack.py index 0b6b5d9ca7..b28d94f74b 100644 --- a/art/attacks/evasion/composite_adversarial_attack.py +++ b/art/attacks/evasion/composite_adversarial_attack.py @@ -211,17 +211,42 @@ def _check_params(self) -> None: not isinstance(self.epsilons[i], tuple) or not len(self.epsilons[i]) == 2 or not ( + isinstance(self.epsilons[i][0], float) and isinstance(self.epsilons[i][1], float) + ) + ): + logger.info( + "The argument `%s` must be an interval within %s of type tuple.", + _epsilons_range[i][0], + _epsilons_range[i][2], + ) + raise TypeError( + f"The argument `{_epsilons_range[i][0]}` must be an interval " + f"within {_epsilons_range[i][2]} of type tuple." + ) + + if (not ( _epsilons_range[i][1][0] <= self.epsilons[i][0] <= self.epsilons[i][1] <= _epsilons_range[i][1][1] ) ): - logger.info("The argument `%s` must be an interval within %s of type tuple.", _epsilons_range[i][0], _epsilons_range[i][2]) - raise ValueError("The argument `{}` must be an interval within {} of type tuple.".format(_epsilons_range[i][0], _epsilons_range[i][2])) + logger.info( + "The argument `%s` must be an interval within %s of type tuple.", + _epsilons_range[i][0], + _epsilons_range[i][2], + ) + raise ValueError( + f"The argument `{_epsilons_range[i][0]}` must be an interval " + f"within {_epsilons_range[i][2]} of type tuple." + ) if not isinstance(self.early_stop, bool): logger.info("The flag `early_stop` has to be of type bool.") - raise ValueError("The flag `early_stop` has to be of type bool.") + raise TypeError("The flag `early_stop` has to be of type bool.") + + if not isinstance(self.max_iter, int): + logger.info("The argument `max_iter` must be positive of type int.") + raise TypeError("The argument `max_iter` must be positive of type int.") - if not isinstance(self.max_iter, int) or self.max_iter <= 0: + if self.max_iter <= 0: logger.info("The argument `max_iter` must be positive of type int.") raise ValueError("The argument `max_iter` must be positive of type int.") @@ -229,6 +254,10 @@ def _check_params(self) -> None: logger.info("The argument `max_inner_iter` must be positive of type int.") raise TypeError("The argument `max_inner_iter` must be positive of type int.") + if self.max_inner_iter <= 0: + logger.info("The argument `max_inner_iter` must be positive of type int.") + raise ValueError("The argument `max_inner_iter` must be positive of type int.") + if self.attack_order not in ("fixed", "random", "scheduled"): logger.info("The argument `attack_order` should be either `fixed`, `random`, or `scheduled`.") raise ValueError("The argument `attack_order` should be either `fixed`, `random`, or `scheduled`.") @@ -239,7 +268,7 @@ def _check_params(self) -> None: if not isinstance(self.verbose, bool): logger.info("The argument `verbose` has to be a Boolean.") - raise ValueError("The argument `verbose` has to be a Boolean.") + raise TypeError("The argument `verbose` has to be a Boolean.") def _setup_attack(self): """ @@ -525,9 +554,7 @@ def caa_linf( return adv_data, eta - def update_attack_order( - self, images: "torch.Tensor", labels: "torch.Tensor", adv_val: List - ) -> None: + def update_attack_order(self, images: "torch.Tensor", labels: "torch.Tensor", adv_val: List) -> None: """ Update the specified attack ordering. :param images: A tensor of a batch of original inputs to be attacked. @@ -600,7 +627,6 @@ def caa_attack(self, images: "torch.Tensor", labels: "torch.Tensor") -> "torch.T """ import torch - attack = self.attack_dict adv_img = images.detach().clone() adv_val_saved = torch.zeros((self.seq_num, self.batch_size), device=self.device) adv_val = [self.adv_val_space[idx] for idx in range(self.seq_num)] @@ -623,7 +649,7 @@ def caa_attack(self, images: "torch.Tensor", labels: "torch.Tensor") -> "torch.T for tdx in range(self.seq_num): idx = self.curr_seq[tdx] - adv_img, adv_val_updated = attack[idx](adv_img, adv_val[idx], labels) + adv_img, adv_val_updated = self.attack_dict[idx](adv_img, adv_val[idx], labels) if idx != self.linf_idx: adv_val[idx] = adv_val_updated diff --git a/tests/attacks/test_composite_adversarial_attack.py b/tests/attacks/test_composite_adversarial_attack.py index 769b195546..7a2b97f607 100644 --- a/tests/attacks/test_composite_adversarial_attack.py +++ b/tests/attacks/test_composite_adversarial_attack.py @@ -50,11 +50,15 @@ def test_generate(art_warning, fix_get_cifar10_subset): classifier = get_cifar10_image_classifier_pt(from_logits=False, load_init=True) attack = CompositeAdversarialAttackPyTorch(classifier) - x_train_adv = attack.generate(x=x_test, y=y_test) + x_train_adv = attack.generate(x=x_train, y=y_train) + x_test_adv = attack.generate(x=x_test, y=y_test) assert x_train.shape == x_train_adv.shape assert np.min(x_train_adv) >= 0.0 assert np.max(x_train_adv) <= 1.0 + assert x_test.shape == x_test_adv.shape + assert np.min(x_test_adv) >= 0.0 + assert np.max(x_test_adv) <= 1.0 except ARTTestException as e: art_warning(e) @@ -67,8 +71,6 @@ def test_check_params(art_warning): try: classifier = get_cifar10_image_classifier_pt(from_logits=False, load_init=True) - with pytest.raises(TypeError): - _ = CompositeAdversarialAttackPyTorch(classifier, enabled_attack=[0, 1, 2, 3, 4]) with pytest.raises(ValueError): _ = CompositeAdversarialAttackPyTorch(classifier, enabled_attack=(0, 1, 2, 3, 4, 5, 6, 7)) @@ -76,97 +78,97 @@ def test_check_params(art_warning): _ = CompositeAdversarialAttackPyTorch(classifier, hue_epsilon=(-10.0, 0.0)) with pytest.raises(ValueError): _ = CompositeAdversarialAttackPyTorch(classifier, hue_epsilon=(0.0, 10.0)) - with pytest.raises(ValueError): + with pytest.raises(TypeError): _ = CompositeAdversarialAttackPyTorch(classifier, hue_epsilon=(-1, 2.0)) - with pytest.raises(ValueError): + with pytest.raises(TypeError): _ = CompositeAdversarialAttackPyTorch(classifier, hue_epsilon=3.14) - with pytest.raises(ValueError): + with pytest.raises(TypeError): _ = CompositeAdversarialAttackPyTorch(classifier, hue_epsilon=(0.0, 10.0, 20.0)) - with pytest.raises(ValueError): + with pytest.raises(TypeError): _ = CompositeAdversarialAttackPyTorch(classifier, hue_epsilon=("1.0", 2.0)) with pytest.raises(ValueError): _ = CompositeAdversarialAttackPyTorch(classifier, sat_epsilon=(-10.0, 0.0)) with pytest.raises(ValueError): _ = CompositeAdversarialAttackPyTorch(classifier, sat_epsilon=(0.0, -10.0)) - with pytest.raises(ValueError): + with pytest.raises(TypeError): _ = CompositeAdversarialAttackPyTorch(classifier, sat_epsilon=(1, 2.0)) - with pytest.raises(ValueError): + with pytest.raises(TypeError): _ = CompositeAdversarialAttackPyTorch(classifier, sat_epsilon=2.0) - with pytest.raises(ValueError): + with pytest.raises(TypeError): _ = CompositeAdversarialAttackPyTorch(classifier, sat_epsilon=(0.0, 10.0, 20.0)) - with pytest.raises(ValueError): + with pytest.raises(TypeError): _ = CompositeAdversarialAttackPyTorch(classifier, sat_epsilon=("1.0", 2.0)) with pytest.raises(ValueError): - _ = CompositeAdversarialAttackPyTorch(classifier, rot_epsilon=(-450.0, 359)) + _ = CompositeAdversarialAttackPyTorch(classifier, rot_epsilon=(-450.0, 359.0)) with pytest.raises(ValueError): _ = CompositeAdversarialAttackPyTorch(classifier, rot_epsilon=(10.0, -10.0)) - with pytest.raises(ValueError): + with pytest.raises(TypeError): _ = CompositeAdversarialAttackPyTorch(classifier, rot_epsilon=(1.0, 2)) - with pytest.raises(ValueError): + with pytest.raises(TypeError): _ = CompositeAdversarialAttackPyTorch(classifier, rot_epsilon=10) - with pytest.raises(ValueError): + with pytest.raises(TypeError): _ = CompositeAdversarialAttackPyTorch(classifier, rot_epsilon=(0.0, 10.0, 20.0)) - with pytest.raises(ValueError): + with pytest.raises(TypeError): _ = CompositeAdversarialAttackPyTorch(classifier, rot_epsilon=("10", 20.0)) with pytest.raises(ValueError): _ = CompositeAdversarialAttackPyTorch(classifier, bri_epsilon=(-10.0, 0.0)) with pytest.raises(ValueError): _ = CompositeAdversarialAttackPyTorch(classifier, bri_epsilon=(0.0, 10.0)) - with pytest.raises(ValueError): + with pytest.raises(TypeError): _ = CompositeAdversarialAttackPyTorch(classifier, bri_epsilon=(-1, 1.0)) - with pytest.raises(ValueError): + with pytest.raises(TypeError): _ = CompositeAdversarialAttackPyTorch(classifier, bri_epsilon=1.0) - with pytest.raises(ValueError): + with pytest.raises(TypeError): _ = CompositeAdversarialAttackPyTorch(classifier, bri_epsilon=(0.0, 10.0, 20.0)) - with pytest.raises(ValueError): + with pytest.raises(TypeError): _ = CompositeAdversarialAttackPyTorch(classifier, bri_epsilon=("1.0", 2.0)) with pytest.raises(ValueError): _ = CompositeAdversarialAttackPyTorch(classifier, con_epsilon=(-10.0, 10.0)) with pytest.raises(ValueError): _ = CompositeAdversarialAttackPyTorch(classifier, con_epsilon=(0.0, -10.0)) - with pytest.raises(ValueError): + with pytest.raises(TypeError): _ = CompositeAdversarialAttackPyTorch(classifier, con_epsilon=(1, 2.0)) - with pytest.raises(ValueError): + with pytest.raises(TypeError): _ = CompositeAdversarialAttackPyTorch(classifier, con_epsilon=2.0) - with pytest.raises(ValueError): + with pytest.raises(TypeError): _ = CompositeAdversarialAttackPyTorch(classifier, con_epsilon=(0.0, 10.0, 20.0)) - with pytest.raises(ValueError): + with pytest.raises(TypeError): _ = CompositeAdversarialAttackPyTorch(classifier, con_epsilon=("1.0", 2.0)) with pytest.raises(ValueError): - _ = CompositeAdversarialAttackPyTorch(classifier, pgd_epsilon=(-0.5, 0)) + _ = CompositeAdversarialAttackPyTorch(classifier, pgd_epsilon=(-0.5, 2.0)) with pytest.raises(ValueError): _ = CompositeAdversarialAttackPyTorch(classifier, pgd_epsilon=(8 / 255, -8 / 255)) - with pytest.raises(ValueError): + with pytest.raises(TypeError): _ = CompositeAdversarialAttackPyTorch(classifier, pgd_epsilon=(-2, 1)) - with pytest.raises(ValueError): + with pytest.raises(TypeError): _ = CompositeAdversarialAttackPyTorch(classifier, pgd_epsilon=8 / 255) - with pytest.raises(ValueError): + with pytest.raises(TypeError): _ = CompositeAdversarialAttackPyTorch(classifier, pgd_epsilon=(0.0, 10.0, 20.0)) - with pytest.raises(ValueError): + with pytest.raises(TypeError): _ = CompositeAdversarialAttackPyTorch(classifier, pgd_epsilon=("2/255", 3 / 255)) - with pytest.raises(ValueError): + with pytest.raises(TypeError): _ = CompositeAdversarialAttackPyTorch(classifier, early_stop="true") - with pytest.raises(ValueError): + with pytest.raises(TypeError): _ = CompositeAdversarialAttackPyTorch(classifier, early_stop=1) - with pytest.raises(ValueError): + with pytest.raises(TypeError): _ = CompositeAdversarialAttackPyTorch(classifier, max_iter="max") with pytest.raises(ValueError): _ = CompositeAdversarialAttackPyTorch(classifier, max_iter=-5) - with pytest.raises(ValueError): + with pytest.raises(TypeError): _ = CompositeAdversarialAttackPyTorch(classifier, max_iter=2.5) - with pytest.raises(ValueError): + with pytest.raises(TypeError): _ = CompositeAdversarialAttackPyTorch(classifier, max_inner_iter="max") with pytest.raises(ValueError): _ = CompositeAdversarialAttackPyTorch(classifier, max_inner_iter=-5) - with pytest.raises(ValueError): + with pytest.raises(TypeError): _ = CompositeAdversarialAttackPyTorch(classifier, max_inner_iter=2.5) with pytest.raises(ValueError): @@ -175,7 +177,7 @@ def test_check_params(art_warning): with pytest.raises(ValueError): _ = CompositeAdversarialAttackPyTorch(classifier, batch_size=-1) - with pytest.raises(ValueError): + with pytest.raises(TypeError): _ = CompositeAdversarialAttackPyTorch(classifier, verbose="true") except ARTTestException as e: From 55f3c72412d5ba331596e5fc1a9dff5eee68dd99 Mon Sep 17 00:00:00 2001 From: Lei Hsiung Date: Sat, 28 Oct 2023 11:29:03 +0800 Subject: [PATCH 11/26] Fix docstring style Signed-off-by: Lei Hsiung --- art/attacks/evasion/composite_adversarial_attack.py | 13 +++++++++++-- .../test_composite_adversarial_attack.py | 2 -- 2 files changed, 11 insertions(+), 4 deletions(-) rename tests/attacks/{ => evasion}/test_composite_adversarial_attack.py (99%) diff --git a/art/attacks/evasion/composite_adversarial_attack.py b/art/attacks/evasion/composite_adversarial_attack.py index b28d94f74b..91c858d885 100644 --- a/art/attacks/evasion/composite_adversarial_attack.py +++ b/art/attacks/evasion/composite_adversarial_attack.py @@ -53,7 +53,7 @@ class CompositeAdversarialAttackPyTorch(EvasionAttack): and uses the iterative gradient sign method to optimize the perturbations in semantic space and Lp-ball (see `FastGradientMethod` and `BasicIterativeMethod`). - Note that this attack is intended for only PyTorch image classifiers with RGB images in the range [0, 1] as inputs. + | Note that this attack is intended for only PyTorch image classifiers with RGB images in the range [0, 1] as inputs. | Paper link: https://arxiv.org/abs/2202.04235 """ @@ -372,6 +372,7 @@ def _comp_pgd( ) -> Tuple["torch.Tensor", "torch.Tensor"]: """ Compute the adversarial examples for each attack component. + :param data: A tensor of a batch of original inputs to be attacked. :param labels: A tensor of a batch of the original labels to be predicted. :param attack_idx: The index of the attack component (one of the enabled attacks) in the attack pool. @@ -416,6 +417,7 @@ def caa_hue( ) -> Tuple["torch.Tensor", "torch.Tensor"]: """ Compute the adversarial examples for hue component. + :param data: A tensor of a batch of original inputs to be attacked. :param hue: Specify the hue shift angle. :param labels: A tensor of a batch of the original labels to be predicted. @@ -435,6 +437,7 @@ def caa_saturation( ) -> Tuple["torch.Tensor", "torch.Tensor"]: """ Compute the adversarial examples for saturation component. + :param data: A tensor of a batch of original inputs to be attacked. :param saturation: Specify the saturation factor. :param labels: A tensor of a batch of the original labels to be predicted. @@ -458,6 +461,7 @@ def caa_rotation( ) -> Tuple["torch.Tensor", "torch.Tensor"]: """ Compute the adversarial examples for rotation component. + :param data: A tensor of a batch of original inputs to be attacked. :param theta: Specify the rotation angle. :param labels: A tensor of a batch of the original labels to be predicted. @@ -477,6 +481,7 @@ def caa_brightness( ) -> Tuple["torch.Tensor", "torch.Tensor"]: """ Compute the adversarial examples for brightness component. + :param data: A tensor of a batch of original inputs to be attacked. :param brightness: Specify the brightness factor. :param labels: A tensor of a batch of the original labels to be predicted. @@ -500,6 +505,7 @@ def caa_contrast( ) -> Tuple["torch.Tensor", "torch.Tensor"]: """ Compute the adversarial examples for contrast component. + :param data: A tensor of a batch of original inputs to be attacked. :param contrast: Specify the contrast factor. :param labels: A tensor of a batch of the original labels to be predicted. @@ -523,9 +529,10 @@ def caa_linf( ) -> Tuple["torch.Tensor", "torch.Tensor"]: """ Compute the adversarial examples for L-infinity (PGD) component. + :param data: A tensor of a batch of original inputs to be attacked. - :param labels: A tensor of a batch of the original labels to be predicted. :param eta: The perturbation in the L-infinity ball. + :param labels: A tensor of a batch of the original labels to be predicted. :return: The perturbed data. """ import torch @@ -557,6 +564,7 @@ def caa_linf( def update_attack_order(self, images: "torch.Tensor", labels: "torch.Tensor", adv_val: List) -> None: """ Update the specified attack ordering. + :param images: A tensor of a batch of original inputs to be attacked. :param labels: A tensor of a batch of the original labels to be predicted. :param adv_val: Optional; A list of a batch of current attack parameters. @@ -621,6 +629,7 @@ def sinkhorn_normalization(ori_dsm, n_iters=20): def caa_attack(self, images: "torch.Tensor", labels: "torch.Tensor") -> "torch.Tensor": """ The main algorithm to generate the adversarial examples for composite adversarial attack. + :param images: A tensor of a batch of original inputs to be attacked. :param labels: A tensor of a batch of the original labels to be predicted. :return: The perturbed data. diff --git a/tests/attacks/test_composite_adversarial_attack.py b/tests/attacks/evasion/test_composite_adversarial_attack.py similarity index 99% rename from tests/attacks/test_composite_adversarial_attack.py rename to tests/attacks/evasion/test_composite_adversarial_attack.py index 7a2b97f607..dc033e6e8c 100644 --- a/tests/attacks/test_composite_adversarial_attack.py +++ b/tests/attacks/evasion/test_composite_adversarial_attack.py @@ -19,7 +19,6 @@ import numpy as np import pytest -import torch from art.attacks.evasion import CompositeAdversarialAttackPyTorch from art.estimators.estimator import BaseEstimator, LossGradientsMixin @@ -43,7 +42,6 @@ def fix_get_cifar10_subset(get_cifar10_dataset): "tensorflow1", "tensorflow2", "tensorflow2v1", "keras", "non_dl_frameworks", "mxnet", "kerastf" ) def test_generate(art_warning, fix_get_cifar10_subset): - print("test_generate") try: (x_train, y_train, x_test, y_test) = fix_get_cifar10_subset From 123af2c9de35832890fdf046dd7c6bacb5aa8d8a Mon Sep 17 00:00:00 2001 From: Farhan Ahmed Date: Tue, 14 Nov 2023 12:04:50 -0800 Subject: [PATCH 12/26] flatten activations for poisoning defenses Signed-off-by: Farhan Ahmed --- art/defences/detector/poison/activation_defence.py | 4 +++- art/defences/detector/poison/spectral_signature_defense.py | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/art/defences/detector/poison/activation_defence.py b/art/defences/detector/poison/activation_defence.py index 9b53235bf4..45b09d0e4d 100644 --- a/art/defences/detector/poison/activation_defence.py +++ b/art/defences/detector/poison/activation_defence.py @@ -695,7 +695,9 @@ def _get_activations(self, x_train: Optional[np.ndarray] = None) -> np.ndarray: # wrong way to get activations activations = self.classifier.predict(self.x_train) if isinstance(activations, np.ndarray): - nodes_last_layer = np.shape(activations)[1] + # flatten activations across batch + activations = np.reshape(activations, (activations.shape[0], -1)) + nodes_last_layer = activations.shape[1] else: raise ValueError("activations is None or tensor.") diff --git a/art/defences/detector/poison/spectral_signature_defense.py b/art/defences/detector/poison/spectral_signature_defense.py index 69109f2d61..8fd44a3200 100644 --- a/art/defences/detector/poison/spectral_signature_defense.py +++ b/art/defences/detector/poison/spectral_signature_defense.py @@ -121,6 +121,8 @@ def detect_poison(self, **kwargs) -> Tuple[dict, List[int]]: raise ValueError("Wrong type detected.") if features_x_poisoned is not None: + # flatten activations across batch + features_x_poisoned = np.reshape(features_x_poisoned, (features_x_poisoned.shape[0], -1)) features_split = segment_by_class(features_x_poisoned, self.y_train, self.classifier.nb_classes) else: raise ValueError("Activation are `None`.") From 4db76267ccac573c81086e8b53accd55379606db Mon Sep 17 00:00:00 2001 From: Farhan Ahmed Date: Tue, 14 Nov 2023 12:05:12 -0800 Subject: [PATCH 13/26] remove huggingface estimator activation hack Signed-off-by: Farhan Ahmed --- art/estimators/classification/hugging_face.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/art/estimators/classification/hugging_face.py b/art/estimators/classification/hugging_face.py index 33a9ce18e0..d029df1b35 100644 --- a/art/estimators/classification/hugging_face.py +++ b/art/estimators/classification/hugging_face.py @@ -318,11 +318,7 @@ def get_activations( # type: ignore def get_feature(name): # the hook signature def hook(model, input, output): # pylint: disable=W0622,W0613 - # TODO: this is using the input, rather than the output, to circumvent the fact - # TODO: that flatten is not a layer in pytorch, and the activation defence expects - # TODO: a flattened input. A better option is to refactor the activation defence - # TODO: to not crash if non 2D inputs are provided. - self._features[name] = input + self._features[name] = output return hook From d345786e297347ecc161ca176bc969aee9a2bc03 Mon Sep 17 00:00:00 2001 From: Farhan Ahmed Date: Thu, 7 Dec 2023 16:21:38 -0800 Subject: [PATCH 14/26] Revert "remove huggingface estimator activation hack" This reverts commit 4db76267ccac573c81086e8b53accd55379606db. Signed-off-by: Farhan Ahmed --- art/estimators/classification/hugging_face.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/art/estimators/classification/hugging_face.py b/art/estimators/classification/hugging_face.py index d029df1b35..33a9ce18e0 100644 --- a/art/estimators/classification/hugging_face.py +++ b/art/estimators/classification/hugging_face.py @@ -318,7 +318,11 @@ def get_activations( # type: ignore def get_feature(name): # the hook signature def hook(model, input, output): # pylint: disable=W0622,W0613 - self._features[name] = output + # TODO: this is using the input, rather than the output, to circumvent the fact + # TODO: that flatten is not a layer in pytorch, and the activation defence expects + # TODO: a flattened input. A better option is to refactor the activation defence + # TODO: to not crash if non 2D inputs are provided. + self._features[name] = input return hook From 191c4d3492d532531d61e80132ce47d70db24de0 Mon Sep 17 00:00:00 2001 From: Beat Buesser Date: Mon, 18 Dec 2023 23:41:24 +0100 Subject: [PATCH 15/26] Update test and format for composite adversarial attack Signed-off-by: Beat Buesser --- art/attacks/evasion/composite_adversarial_attack.py | 9 ++------- .../attacks/evasion/test_composite_adversarial_attack.py | 2 +- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/art/attacks/evasion/composite_adversarial_attack.py b/art/attacks/evasion/composite_adversarial_attack.py index 91c858d885..c22a90294a 100644 --- a/art/attacks/evasion/composite_adversarial_attack.py +++ b/art/attacks/evasion/composite_adversarial_attack.py @@ -210,9 +210,7 @@ def _check_params(self) -> None: if ( not isinstance(self.epsilons[i], tuple) or not len(self.epsilons[i]) == 2 - or not ( - isinstance(self.epsilons[i][0], float) and isinstance(self.epsilons[i][1], float) - ) + or not (isinstance(self.epsilons[i][0], float) and isinstance(self.epsilons[i][1], float)) ): logger.info( "The argument `%s` must be an interval within %s of type tuple.", @@ -224,10 +222,7 @@ def _check_params(self) -> None: f"within {_epsilons_range[i][2]} of type tuple." ) - if (not ( - _epsilons_range[i][1][0] <= self.epsilons[i][0] <= self.epsilons[i][1] <= _epsilons_range[i][1][1] - ) - ): + if not (_epsilons_range[i][1][0] <= self.epsilons[i][0] <= self.epsilons[i][1] <= _epsilons_range[i][1][1]): logger.info( "The argument `%s` must be an interval within %s of type tuple.", _epsilons_range[i][0], diff --git a/tests/attacks/evasion/test_composite_adversarial_attack.py b/tests/attacks/evasion/test_composite_adversarial_attack.py index dc033e6e8c..cd135d01b5 100644 --- a/tests/attacks/evasion/test_composite_adversarial_attack.py +++ b/tests/attacks/evasion/test_composite_adversarial_attack.py @@ -39,7 +39,7 @@ def fix_get_cifar10_subset(get_cifar10_dataset): @pytest.mark.skip_framework( - "tensorflow1", "tensorflow2", "tensorflow2v1", "keras", "non_dl_frameworks", "mxnet", "kerastf" + "tensorflow1", "tensorflow2", "tensorflow2v1", "keras", "non_dl_frameworks", "mxnet", "kerastf", "huggingface" ) def test_generate(art_warning, fix_get_cifar10_subset): try: From 752e4940d5634066a8e9ced22823e2f33ef665f7 Mon Sep 17 00:00:00 2001 From: Beat Buesser Date: Tue, 19 Dec 2023 16:10:02 +0100 Subject: [PATCH 16/26] Fix style checks Signed-off-by: Beat Buesser --- art/attacks/evasion/composite_adversarial_attack.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/art/attacks/evasion/composite_adversarial_attack.py b/art/attacks/evasion/composite_adversarial_attack.py index c22a90294a..0a2dd2fe8b 100644 --- a/art/attacks/evasion/composite_adversarial_attack.py +++ b/art/attacks/evasion/composite_adversarial_attack.py @@ -53,7 +53,7 @@ class CompositeAdversarialAttackPyTorch(EvasionAttack): and uses the iterative gradient sign method to optimize the perturbations in semantic space and Lp-ball (see `FastGradientMethod` and `BasicIterativeMethod`). - | Note that this attack is intended for only PyTorch image classifiers with RGB images in the range [0, 1] as inputs. + | Note that this attack is intended for only PyTorch image classifiers with RGB images in the range [0, 1] as inputs | Paper link: https://arxiv.org/abs/2202.04235 """ @@ -222,7 +222,7 @@ def _check_params(self) -> None: f"within {_epsilons_range[i][2]} of type tuple." ) - if not (_epsilons_range[i][1][0] <= self.epsilons[i][0] <= self.epsilons[i][1] <= _epsilons_range[i][1][1]): + if not _epsilons_range[i][1][0] <= self.epsilons[i][0] <= self.epsilons[i][1] <= _epsilons_range[i][1][1]: logger.info( "The argument `%s` must be an interval within %s of type tuple.", _epsilons_range[i][0], @@ -653,7 +653,7 @@ def caa_attack(self, images: "torch.Tensor", labels: "torch.Tensor") -> "torch.T for tdx in range(self.seq_num): idx = self.curr_seq[tdx] - adv_img, adv_val_updated = self.attack_dict[idx](adv_img, adv_val[idx], labels) + adv_img, adv_val_updated = self.attack_dict[idx](adv_img, adv_val[idx], labels) # type: ignore if idx != self.linf_idx: adv_val[idx] = adv_val_updated From 94cf59f27cfbd0c685c4deff68b3cdd0fa41de1c Mon Sep 17 00:00:00 2001 From: Beat Buesser <49047826+beat-buesser@users.noreply.github.com> Date: Tue, 19 Dec 2023 16:55:54 +0100 Subject: [PATCH 17/26] Update art/estimators/certification/derandomized_smoothing/pytorch.py --- art/estimators/certification/derandomized_smoothing/pytorch.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/art/estimators/certification/derandomized_smoothing/pytorch.py b/art/estimators/certification/derandomized_smoothing/pytorch.py index beb67ed171..52b38d604d 100644 --- a/art/estimators/certification/derandomized_smoothing/pytorch.py +++ b/art/estimators/certification/derandomized_smoothing/pytorch.py @@ -457,7 +457,7 @@ def fit( # pylint: disable=W0221 the batch size. If ``False`` and the size of dataset is not divisible by the batch size, then the last batch will be smaller. (default: ``False``) :param scheduler: Learning rate scheduler to run at the start of every epoch. - :param verbose: if to display training progress bars + :param verbose: Display training progress bar. :param update_batchnorm: ViT specific argument. If to run the training data through the model to update any batch norm statistics prior to training. Useful on small datasets when using pre-trained ViTs. From 1f3026ba3e1889eaaf0ba20891cdc6c871130440 Mon Sep 17 00:00:00 2001 From: Beat Buesser <49047826+beat-buesser@users.noreply.github.com> Date: Tue, 19 Dec 2023 16:59:01 +0100 Subject: [PATCH 18/26] Apply suggestions from code review --- .../derandomized_smoothing/pytorch.py | 8 +- .../derandomized_smoothing/tensorflow.py | 10 +- .../randomized_smoothing/macer/pytorch.py | 9 +- .../randomized_smoothing/macer/tensorflow.py | 9 +- .../randomized_smoothing/pytorch.py | 9 +- .../smooth_adv/pytorch.py | 9 +- .../smooth_adv/tensorflow.py | 9 +- .../smooth_mix/pytorch.py | 9 +- .../randomized_smoothing/tensorflow.py | 9 +- art/estimators/classification/pytorch.py | 52 ++-------- art/estimators/classification/tensorflow.py | 97 +++---------------- .../test_deeplearning_common.py | 18 +--- 12 files changed, 54 insertions(+), 194 deletions(-) diff --git a/art/estimators/certification/derandomized_smoothing/pytorch.py b/art/estimators/certification/derandomized_smoothing/pytorch.py index 52b38d604d..f47a7cd145 100644 --- a/art/estimators/certification/derandomized_smoothing/pytorch.py +++ b/art/estimators/certification/derandomized_smoothing/pytorch.py @@ -438,7 +438,7 @@ def fit( # pylint: disable=W0221 training_mode: bool = True, drop_last: bool = False, scheduler: Optional[Any] = None, - verbose: Optional[Union[bool, int]] = None, + verbose: bool = False, update_batchnorm: bool = True, batchnorm_update_epochs: int = 1, transform: Optional["torchvision.transforms.transforms.Compose"] = None, @@ -469,8 +469,6 @@ def fit( # pylint: disable=W0221 """ import torch - display_pb = self.process_verbose(verbose) - # Set model mode self._model.train(mode=training_mode) @@ -501,7 +499,7 @@ def fit( # pylint: disable=W0221 epoch_loss = [] epoch_batch_sizes = [] - pbar = tqdm(range(num_batch), disable=not display_pb) + pbar = tqdm(range(num_batch), disable=not verbose) # Train for one epoch for m in pbar: @@ -547,7 +545,7 @@ def fit( # pylint: disable=W0221 epoch_loss.append(loss.cpu().detach().numpy()) epoch_batch_sizes.append(len(i_batch)) - if display_pb: + if verbose: pbar.set_description( f"Loss {np.average(epoch_loss, weights=epoch_batch_sizes):.3f} " f"Acc {np.average(epoch_acc, weights=epoch_batch_sizes):.3f} " diff --git a/art/estimators/certification/derandomized_smoothing/tensorflow.py b/art/estimators/certification/derandomized_smoothing/tensorflow.py index 4261443a78..e99154198b 100644 --- a/art/estimators/certification/derandomized_smoothing/tensorflow.py +++ b/art/estimators/certification/derandomized_smoothing/tensorflow.py @@ -160,7 +160,7 @@ def fit( # pylint: disable=W0221 y: np.ndarray, batch_size: int = 128, nb_epochs: int = 10, - verbose: Optional[Union[bool, int]] = None, + verbose: bool = False, **kwargs, ) -> None: """ @@ -171,15 +171,13 @@ def fit( # pylint: disable=W0221 shape (nb_samples,). :param batch_size: Size of batches. :param nb_epochs: Number of epochs to use for training. - :param verbose: If to display training progress bars + :param verbose: Display training progress bar. :param kwargs: Dictionary of framework-specific arguments. This parameter currently only supports "scheduler" which is an optional function that will be called at the end of every epoch to adjust the learning rate. """ import tensorflow as tf - display_pb = self.process_verbose(verbose) - if self._train_step is None: # pragma: no cover if self._loss_object is None: # pragma: no cover raise TypeError( @@ -222,7 +220,7 @@ def train_step(model, images, labels): epoch_loss = [] epoch_batch_sizes = [] - pbar = tqdm(range(num_batch), disable=not display_pb) + pbar = tqdm(range(num_batch), disable=not verbose) ind = np.arange(len(x_preprocessed)) for m in pbar: @@ -239,7 +237,7 @@ def train_step(model, images, labels): else: train_step(self.model, images, labels) - if display_pb: + if verbose: if self._train_step is None: pbar.set_description( f"Loss {np.average(epoch_loss, weights=epoch_batch_sizes):.3f} " diff --git a/art/estimators/certification/randomized_smoothing/macer/pytorch.py b/art/estimators/certification/randomized_smoothing/macer/pytorch.py index cde56c252a..4bc13b1be5 100644 --- a/art/estimators/certification/randomized_smoothing/macer/pytorch.py +++ b/art/estimators/certification/randomized_smoothing/macer/pytorch.py @@ -138,7 +138,7 @@ def fit( # pylint: disable=W0221 training_mode: bool = True, drop_last: bool = False, scheduler: Optional["torch.optim.lr_scheduler._LRScheduler"] = None, - verbose: Optional[Union[bool, int]] = None, + verbose: bool = False, **kwargs, ) -> None: """ @@ -154,8 +154,7 @@ def fit( # pylint: disable=W0221 the batch size. If ``False`` and the size of dataset is not divisible by the batch size, then the last batch will be smaller. (default: ``False``) :param scheduler: Learning rate scheduler to run at the start of every epoch. - :param verbose: (Optional) Display the progress bar, if not supplied will revert to the verbose level when - class was initialised. + :param verbose: Display the training progress bar. :param kwargs: Dictionary of framework-specific arguments. This parameter is not currently supported for PyTorch and providing it takes no effect. """ @@ -163,8 +162,6 @@ class was initialised. import torch.nn.functional as F from torch.utils.data import TensorDataset, DataLoader - display_pb = self.process_verbose(verbose) - # Set model mode self._model.train(mode=training_mode) @@ -190,7 +187,7 @@ class was initialised. ) # Start training - for _ in trange(nb_epochs, disable=not display_pb): + for _ in trange(nb_epochs, disable=not verbose): for x_batch, y_batch in dataloader: # Move inputs to GPU x_batch = x_batch.to(self.device) diff --git a/art/estimators/certification/randomized_smoothing/macer/tensorflow.py b/art/estimators/certification/randomized_smoothing/macer/tensorflow.py index 5c88011f8d..860921507c 100644 --- a/art/estimators/certification/randomized_smoothing/macer/tensorflow.py +++ b/art/estimators/certification/randomized_smoothing/macer/tensorflow.py @@ -138,7 +138,7 @@ def fit( y: np.ndarray, batch_size: int = 128, nb_epochs: int = 10, - verbose: Optional[Union[bool, int]] = None, + verbose: bool = False, **kwargs ) -> None: """ @@ -149,16 +149,13 @@ def fit( shape (nb_samples,). :param batch_size: Size of batches. :param nb_epochs: Number of epochs to use for training. - :param verbose: (Optional) Display the progress bar, if not supplied will revert to the verbose level when - class was initialised. + :param verbose: Display the training progress bar. :param kwargs: Dictionary of framework-specific arguments. This parameter currently only supports "scheduler" which is an optional function that will be called at the end of every epoch to adjust the learning rate. """ import tensorflow as tf - display_pb = self.process_verbose(verbose) - if self._train_step is None: # pragma: no cover if self._optimizer is None: # pragma: no cover raise ValueError( @@ -225,7 +222,7 @@ def train_step(model, images, labels): train_ds = tf.data.Dataset.from_tensor_slices((x_preprocessed, y_preprocessed)).shuffle(10000).batch(batch_size) - for epoch in trange(nb_epochs, disable=not display_pb): + for epoch in trange(nb_epochs, disable=not verbose): for images, labels in train_ds: # Tile samples for Gaussian augmentation input_size = len(images) diff --git a/art/estimators/certification/randomized_smoothing/pytorch.py b/art/estimators/certification/randomized_smoothing/pytorch.py index eff16f7c90..fddc7d0938 100644 --- a/art/estimators/certification/randomized_smoothing/pytorch.py +++ b/art/estimators/certification/randomized_smoothing/pytorch.py @@ -140,7 +140,7 @@ def fit( # pylint: disable=W0221 training_mode: bool = True, drop_last: bool = False, scheduler: Optional["torch.optim.lr_scheduler._LRScheduler"] = None, - verbose: Optional[Union[bool, int]] = None, + verbose: bool = False, **kwargs, ) -> None: """ @@ -156,16 +156,13 @@ def fit( # pylint: disable=W0221 the batch size. If ``False`` and the size of dataset is not divisible by the batch size, then the last batch will be smaller. (default: ``False``) :param scheduler: Learning rate scheduler to run at the start of every epoch. - :param verbose: (Optional) Display the progress bar, if not supplied will revert to the verbose level when - class was initialised. + :param verbose: Display the training progress bar. :param kwargs: Dictionary of framework-specific arguments. This parameter is not currently supported for PyTorch and providing it takes no effect. """ import torch from torch.utils.data import TensorDataset, DataLoader - display_pb = self.process_verbose(verbose) - # Set model mode self._model.train(mode=training_mode) @@ -187,7 +184,7 @@ class was initialised. dataloader = DataLoader(dataset=dataset, batch_size=batch_size, shuffle=True, drop_last=drop_last) # Start training - for _ in trange(nb_epochs, disable=not display_pb): + for _ in trange(nb_epochs, disable=not verbose): for x_batch, y_batch in dataloader: # Move inputs to device x_batch = x_batch.to(self._device) diff --git a/art/estimators/certification/randomized_smoothing/smooth_adv/pytorch.py b/art/estimators/certification/randomized_smoothing/smooth_adv/pytorch.py index b80d5888b2..a0ac0a1742 100644 --- a/art/estimators/certification/randomized_smoothing/smooth_adv/pytorch.py +++ b/art/estimators/certification/randomized_smoothing/smooth_adv/pytorch.py @@ -155,7 +155,7 @@ def fit( # pylint: disable=W0221 training_mode: bool = True, drop_last: bool = False, scheduler: Optional["torch.optim.lr_scheduler._LRScheduler"] = None, - verbose: Optional[Union[bool, int]] = None, + verbose: bool = False, **kwargs, ) -> None: """ @@ -171,16 +171,13 @@ def fit( # pylint: disable=W0221 the batch size. If ``False`` and the size of dataset is not divisible by the batch size, then the last batch will be smaller. (default: ``False``) :param scheduler: Learning rate scheduler to run at the start of every epoch. - :param verbose: (Optional) Display the progress bar, if not supplied will revert to the verbose level when - class was initialised. + :param verbose: Display the training progress bar. :param kwargs: Dictionary of framework-specific arguments. This parameter is not currently supported for PyTorch and providing it takes no effect. """ import torch from torch.utils.data import TensorDataset, DataLoader - display_pb = self.process_verbose(verbose) - # Set model mode self._model.train(mode=training_mode) @@ -202,7 +199,7 @@ class was initialised. dataloader = DataLoader(dataset=dataset, batch_size=batch_size, shuffle=True, drop_last=drop_last) # Start training - for epoch in trange(nb_epochs, disable=not display_pb): + for epoch in trange(nb_epochs, disable=not verbose): self.attack.norm = min(self.epsilon, (epoch + 1) * self.epsilon / self.warmup) for x_batch, y_batch in dataloader: diff --git a/art/estimators/certification/randomized_smoothing/smooth_adv/tensorflow.py b/art/estimators/certification/randomized_smoothing/smooth_adv/tensorflow.py index 938db2a5c3..0d8b960de0 100644 --- a/art/estimators/certification/randomized_smoothing/smooth_adv/tensorflow.py +++ b/art/estimators/certification/randomized_smoothing/smooth_adv/tensorflow.py @@ -155,7 +155,7 @@ def fit( y: np.ndarray, batch_size: int = 128, nb_epochs: int = 10, - verbose: Optional[Union[bool, int]] = None, + verbose: bool = False, **kwargs ) -> None: """ @@ -166,16 +166,13 @@ def fit( shape (nb_samples,). :param batch_size: Size of batches. :param nb_epochs: Number of epochs to use for training. - :param verbose: (Optional) Display the progress bar, if not supplied will revert to the verbose level when - class was initialised. + :param verbose: Display the training progress bar. :param kwargs: Dictionary of framework-specific arguments. This parameter currently only supports "scheduler" which is an optional function that will be called at the end of every epoch to adjust the learning rate. """ import tensorflow as tf - display_pb = self.process_verbose(verbose) - if self._train_step is None: # pragma: no cover if self._loss_object is None: # pragma: no cover raise TypeError( @@ -212,7 +209,7 @@ def train_step(model, images, labels): train_ds = tf.data.Dataset.from_tensor_slices((x_preprocessed, y_preprocessed)).shuffle(10000).batch(batch_size) - for epoch in trange(nb_epochs, disable=not display_pb): + for epoch in trange(nb_epochs, disable=not verbose): self.attack.norm = min(self.epsilon, (epoch + 1) * self.epsilon / self.warmup) for x_batch, y_batch in train_ds: diff --git a/art/estimators/certification/randomized_smoothing/smooth_mix/pytorch.py b/art/estimators/certification/randomized_smoothing/smooth_mix/pytorch.py index 9bf3b848e4..9a84470edc 100644 --- a/art/estimators/certification/randomized_smoothing/smooth_mix/pytorch.py +++ b/art/estimators/certification/randomized_smoothing/smooth_mix/pytorch.py @@ -172,7 +172,7 @@ def fit( # pylint: disable=W0221 training_mode: bool = True, drop_last: bool = False, scheduler: Optional["torch.optim.lr_scheduler._LRScheduler"] = None, - verbose: Optional[Union[bool, int]] = None, + verbose: bool = False, **kwargs, ) -> None: """ @@ -188,8 +188,7 @@ def fit( # pylint: disable=W0221 the batch size. If ``False`` and the size of dataset is not divisible by the batch size, then the last batch will be smaller. (default: ``False``) :param scheduler: Learning rate scheduler to run at the start of every epoch. - :param verbose: (Optional) Display the progress bar, if not supplied will revert to the verbose level when - class was initialised. + :param verbose: Display the training progress bar. :param kwargs: Dictionary of framework-specific arguments. This parameter is not currently supported for PyTorch and providing it takes no effect. """ @@ -197,8 +196,6 @@ class was initialised. import torch.nn.functional as F from torch.utils.data import TensorDataset, DataLoader - display_pb = self.process_verbose(verbose) - # Set model mode self._model.train(mode=training_mode) @@ -220,7 +217,7 @@ class was initialised. dataloader = DataLoader(dataset=dataset, batch_size=batch_size, shuffle=True, drop_last=drop_last) # Start training - for epoch in trange(nb_epochs, disable=not display_pb): + for epoch in trange(nb_epochs, disable=not verbose): warmup_v = min(1.0, (epoch + 1) / self.warmup) for x_batch, y_batch in dataloader: diff --git a/art/estimators/certification/randomized_smoothing/tensorflow.py b/art/estimators/certification/randomized_smoothing/tensorflow.py index 74c1c875da..6c6949a770 100644 --- a/art/estimators/certification/randomized_smoothing/tensorflow.py +++ b/art/estimators/certification/randomized_smoothing/tensorflow.py @@ -137,7 +137,7 @@ def fit( # pylint: disable=W0221 y: np.ndarray, batch_size: int = 128, nb_epochs: int = 10, - verbose: Optional[Union[bool, int]] = None, + verbose: bool = False, **kwargs ) -> None: """ @@ -148,16 +148,13 @@ def fit( # pylint: disable=W0221 shape (nb_samples,). :param batch_size: Size of batches. :param nb_epochs: Number of epochs to use for training. - :param verbose: (Optional) Display the progress bar, if not supplied will revert to the verbose level when - class was initialised. + :param verbose: Display the training progress bar. :param kwargs: Dictionary of framework-specific arguments. This parameter currently only supports "scheduler" which is an optional function that will be called at the end of every epoch to adjust the learning rate. """ import tensorflow as tf - display_pb = self.process_verbose(verbose) - if self._train_step is None: # pragma: no cover if self._loss_object is None: # pragma: no cover raise TypeError( @@ -194,7 +191,7 @@ def train_step(model, images, labels): train_ds = tf.data.Dataset.from_tensor_slices((x_preprocessed, y_preprocessed)).shuffle(10000).batch(batch_size) - for epoch in trange(nb_epochs, disable=not display_pb): + for epoch in trange(nb_epochs, disable=not verbose): for images, labels in train_ds: # Add random noise for randomized smoothing images += tf.random.normal(shape=images.shape, mean=0.0, stddev=self.scale) diff --git a/art/estimators/classification/pytorch.py b/art/estimators/classification/pytorch.py index 41a3408eb6..a9fe17ab89 100644 --- a/art/estimators/classification/pytorch.py +++ b/art/estimators/classification/pytorch.py @@ -366,35 +366,6 @@ def _predict_framework( return output, y_preprocessed - def process_verbose(self, verbose: Optional[Union[bool, int]] = None) -> bool: - """ - Function to unify the various ways implemented in ART of displaying progress bars - into a single True/False output. - - :param verbose: If to display the progress bar information in one of a few possible formats. - :return: True/False if to display the progress bars. - """ - - if verbose is not None: - if isinstance(verbose, int): - if verbose <= 0: - display_pb = False - else: - display_pb = True - elif isinstance(verbose, bool): - display_pb = verbose - else: - raise ValueError("Verbose should be True/False or an int") - else: - # Check if the verbose attribute is present in the current classifier - if hasattr(self, "verbose"): - display_pb = self.verbose # type: ignore - # else default to False - else: - display_pb = False - - return display_pb - def fit( # pylint: disable=W0221 self, x: np.ndarray, @@ -404,7 +375,7 @@ def fit( # pylint: disable=W0221 training_mode: bool = True, drop_last: bool = False, scheduler: Optional["torch.optim.lr_scheduler._LRScheduler"] = None, - verbose: Optional[Union[bool, int]] = None, + verbose: bool = False, **kwargs, ) -> None: """ @@ -427,8 +398,6 @@ def fit( # pylint: disable=W0221 import torch from torch.utils.data import TensorDataset, DataLoader - display_pb = self.process_verbose(verbose) - # Set model mode self._model.train(mode=training_mode) @@ -450,8 +419,8 @@ def fit( # pylint: disable=W0221 dataloader = DataLoader(dataset=dataset, batch_size=batch_size, shuffle=True, drop_last=drop_last) # Start training - for _ in tqdm(range(nb_epochs), disable=not display_pb, desc="Epochs"): - for x_batch, y_batch in tqdm(dataloader, disable=not display_pb, desc="Batches"): + for _ in tqdm(range(nb_epochs), disable=not verbose, desc="Epochs"): + for x_batch, y_batch in dataloader: # Move inputs to device x_batch = x_batch.to(self._device) y_batch = y_batch.to(self._device) @@ -488,22 +457,20 @@ def fit( # pylint: disable=W0221 scheduler.step() def fit_generator( # pylint: disable=W0221 - self, generator: "DataGenerator", nb_epochs: int = 20, verbose: Optional[Union[bool, int]] = None, **kwargs + self, generator: "DataGenerator", nb_epochs: int = 20, verbose: bool = False, **kwargs ) -> None: """ Fit the classifier using the generator that yields batches as specified. :param generator: Batch generator providing `(x, y)` for each epoch. :param nb_epochs: Number of epochs to use for training. - :param verbose: If to display the progress bar information. + :param verbose: Display the training progress bar. :param kwargs: Dictionary of framework-specific arguments. This parameter is not currently supported for PyTorch and providing it takes no effect. """ import torch from art.data_generators import PyTorchDataGenerator - display_pb = self.process_verbose(verbose) - # Put the model in the training mode self._model.train() @@ -524,8 +491,8 @@ def fit_generator( # pylint: disable=W0221 == (0, 1) ) ): - for _ in tqdm(range(nb_epochs), disable=not display_pb, desc="Epochs"): - for i_batch, o_batch in tqdm(generator.iterator, disable=not display_pb, desc="Batches"): + for _ in tqdm(range(nb_epochs), disable=not verbose, desc="Epochs"): + for i_batch, o_batch in generator.iterator: if isinstance(i_batch, np.ndarray): i_batch = torch.from_numpy(i_batch).to(self._device) else: @@ -534,10 +501,7 @@ def fit_generator( # pylint: disable=W0221 if isinstance(o_batch, np.ndarray): o_batch = torch.argmax(torch.from_numpy(o_batch).to(self._device), dim=1) else: - if o_batch.dim() > 1: - o_batch = torch.argmax(o_batch.to(self._device), dim=1) - else: - o_batch = o_batch.to(self._device) + o_batch = torch.argmax(o_batch.to(self._device), dim=1) # Zero the parameter gradients self._optimizer.zero_grad() diff --git a/art/estimators/classification/tensorflow.py b/art/estimators/classification/tensorflow.py index 963f64697c..6ead0ec234 100644 --- a/art/estimators/classification/tensorflow.py +++ b/art/estimators/classification/tensorflow.py @@ -266,41 +266,13 @@ def predict( # pylint: disable=W0221 return predictions - def process_verbose(self, verbose: Optional[Union[bool, int]] = None) -> bool: - """ - Function to unify the various ways implemented in ART of displaying progress bars - into a single True/False output. - :param verbose: If to display the progress bar information in one of a few possible formats. - :return: True/False if to display the progress bars. - """ - - if verbose is not None: - if isinstance(verbose, int): - if verbose == 0: - display_pb = False - else: - display_pb = True - elif isinstance(verbose, bool): - display_pb = verbose - else: - raise ValueError("Verbose should be True/False or a 0/1 int") - else: - # Check if the verbose attribute is present in the current classifier - if hasattr(self, "verbose"): - display_pb = self.verbose # type: ignore - # else default to False - else: - display_pb = False - - return display_pb - def fit( # pylint: disable=W0221 self, x: np.ndarray, y: np.ndarray, batch_size: int = 128, nb_epochs: int = 10, - verbose: Optional[Union[bool, int]] = None, + verbose: bool = False, **kwargs, ) -> None: """ @@ -311,15 +283,13 @@ def fit( # pylint: disable=W0221 shape (nb_samples,). :param batch_size: Size of batches. :param nb_epochs: Number of epochs to use for training. - :param verbose: If to display the progress bar information. + :param verbose: Display the training progress bar. :param kwargs: Dictionary of framework-specific arguments. This parameter is not currently supported for TensorFlow and providing it takes no effect. """ if self.learning is not None: self.feed_dict[self.learning] = True - display_pb = self.process_verbose(verbose) - # Check if train and output_ph available if self.train is None or self.labels_ph is None: # pragma: no cover raise ValueError("Need the training objective and the output placeholder to train the model.") @@ -337,12 +307,12 @@ def fit( # pylint: disable=W0221 ind = np.arange(len(x_preprocessed)).tolist() # Start training - for _ in tqdm(range(nb_epochs), disable=not display_pb, desc="Epochs"): + for _ in tqdm(range(nb_epochs), disable=not verbose, desc="Epochs"): # Shuffle the examples random.shuffle(ind) # Train for one epoch - for m in tqdm(range(num_batch), disable=not display_pb, desc="Batches"): + for m in range(num_batch): i_batch = x_preprocessed[ind[m * batch_size : (m + 1) * batch_size]] o_batch = y_preprocessed[ind[m * batch_size : (m + 1) * batch_size]] @@ -354,7 +324,7 @@ def fit( # pylint: disable=W0221 self._sess.run(self.train, feed_dict=feed_dict) def fit_generator( # pylint: disable=W0221 - self, generator: "DataGenerator", nb_epochs: int = 20, verbose: Optional[Union[bool, int]] = None, **kwargs + self, generator: "DataGenerator", nb_epochs: int = 20, verbose: bool = False, **kwargs ) -> None: """ Fit the classifier using the generator that yields batches as specified. @@ -362,14 +332,12 @@ def fit_generator( # pylint: disable=W0221 :param generator: Batch generator providing `(x, y)` for each epoch. If the generator can be used for native training in TensorFlow, it will. :param nb_epochs: Number of epochs to use for training. - :param verbose: If to display the progress bar information. + :param verbose: Display the training progress bar. :param kwargs: Dictionary of framework-specific arguments. This parameter is not currently supported for TensorFlow and providing it takes no effect. """ from art.data_generators import TensorFlowDataGenerator - display_pb = self.process_verbose(verbose) - if self.learning is not None: self.feed_dict[self.learning] = True @@ -387,14 +355,14 @@ def fit_generator( # pylint: disable=W0221 == (0, 1) ) ): - for _ in tqdm(range(nb_epochs), disable=not display_pb, desc="Epochs"): + for _ in tqdm(range(nb_epochs), disable=not verbose, desc="Epochs"): gen_size = generator.size if isinstance(gen_size, int): num_batchcs = int(gen_size / generator.batch_size) else: raise ValueError("Number of batches could not be determined from the generator") - for _ in tqdm(range(num_batchcs), disable=not display_pb, desc="Batches"): + for _ in range(num_batches): i_batch, o_batch = generator.get_batch() if self._reduce_labels: @@ -1003,42 +971,13 @@ def _predict_framework(self, x: "tf.Tensor", training_mode: bool = False) -> "tf return self._model(x_preprocessed, training=training_mode) - def process_verbose(self, verbose: Optional[Union[bool, int]] = None) -> bool: - """ - Function to unify the various ways implemented in ART of displaying progress bars - into a single True/False output. - - :param verbose: If to display the progress bar information in one of a few possible formats. - :return: True/False if to display the progress bars. - """ - - if verbose is not None: - if isinstance(verbose, int): - if verbose <= 0: - display_pb = False - else: - display_pb = True - elif isinstance(verbose, bool): - display_pb = verbose - else: - raise ValueError("Verbose should be True/False or a 0/1 int") - else: - # Check if the verbose attribute is present in the current classifier - if hasattr(self, "verbose"): - display_pb = self.verbose # type: ignore - # else default to False - else: - display_pb = False - - return display_pb - def fit( # pylint: disable=W0221 self, x: np.ndarray, y: np.ndarray, batch_size: int = 128, nb_epochs: int = 10, - verbose: Optional[Union[bool, int]] = None, + verbose: bool = False, **kwargs, ) -> None: """ @@ -1049,15 +988,13 @@ def fit( # pylint: disable=W0221 shape (nb_samples,). :param batch_size: Size of batches. :param nb_epochs: Number of epochs to use for training. - :param verbose: If to display progress bar information. + :param verbose: Display training progress bar. :param kwargs: Dictionary of framework-specific arguments. This parameter currently supports "scheduler" which is an optional function that will be called at the end of every epoch to adjust the learning rate. """ import tensorflow as tf - display_pb = self.process_verbose(verbose) - if self._train_step is None: # pragma: no cover if self._loss_object is None: # pragma: no cover raise TypeError( @@ -1094,15 +1031,15 @@ def train_step(model, images, labels): train_ds = tf.data.Dataset.from_tensor_slices((x_preprocessed, y_preprocessed)).shuffle(10000).batch(batch_size) - for epoch in tqdm(range(nb_epochs), disable=not display_pb, desc="Epochs"): - for images, labels in tqdm(train_ds, disable=not display_pb, desc="Batches"): + for epoch in tqdm(range(nb_epochs), disable=not verbose, desc="Epochs"): + for images, labels in train_ds: train_step(self.model, images, labels) if scheduler is not None: scheduler(epoch) def fit_generator( # pylint: disable=W0221 - self, generator: "DataGenerator", nb_epochs: int = 20, verbose: Optional[Union[bool, int]] = None, **kwargs + self, generator: "DataGenerator", nb_epochs: int = 20, verbose: bool = False, **kwargs ) -> None: """ Fit the classifier using the generator that yields batches as specified. @@ -1110,7 +1047,7 @@ def fit_generator( # pylint: disable=W0221 :param generator: Batch generator providing `(x, y)` for each epoch. If the generator can be used for native training in TensorFlow, it will. :param nb_epochs: Number of epochs to use for training. - :param verbose: If to display progress bar information + :param verbose: Display training progress bar. :param kwargs: Dictionary of framework-specific arguments. This parameter currently supports "scheduler" which is an optional function that will be called at the end of every epoch to adjust the learning rate. @@ -1118,8 +1055,6 @@ def fit_generator( # pylint: disable=W0221 import tensorflow as tf from art.data_generators import TensorFlowV2DataGenerator - display_pb = self.process_verbose(verbose) - if self._train_step is None: # pragma: no cover if self._loss_object is None: # pragma: no cover raise TypeError( @@ -1159,8 +1094,8 @@ def train_step(model, images, labels): == (0, 1) ) ): - for epoch in tqdm(range(nb_epochs), disable=not display_pb, desc="Epochs"): - for i_batch, o_batch in tqdm(generator.iterator, disable=not display_pb, desc="Batches"): + for epoch in tqdm(range(nb_epochs), disable=not verbose, desc="Epochs"): + for i_batch, o_batch in generator.iterator: if self._reduce_labels: o_batch = tf.math.argmax(o_batch, axis=1) train_step(self._model, i_batch, o_batch) diff --git a/tests/estimators/classification/test_deeplearning_common.py b/tests/estimators/classification/test_deeplearning_common.py index de2d9e3cdb..b7dbf8323a 100644 --- a/tests/estimators/classification/test_deeplearning_common.py +++ b/tests/estimators/classification/test_deeplearning_common.py @@ -204,27 +204,13 @@ def get_lr(_): # Test a valid callback classifier, sess = image_dl_estimator(from_logits=True) - kwargs = {"callbacks": [LearningRateScheduler(get_lr)], "verbose": True} - classifier.fit(x_train_mnist, y_train_mnist, batch_size=default_batch_size, nb_epochs=1, **kwargs) + kwargs = {"callbacks": [LearningRateScheduler(get_lr)]} + classifier.fit(x_train_mnist, y_train_mnist, batch_size=default_batch_size, nb_epochs=1, verbose=True, **kwargs) # Check for fit_generator kwargs as well data_gen = image_data_generator(sess=sess) classifier.fit_generator(generator=data_gen, nb_epochs=1, **kwargs) - # Test failure for invalid parameters: does not apply to many frameworks which allow arbitrary kwargs - if framework not in [ - "tensorflow1", - "tensorflow2", - "tensorflow2v1", - "huggingface", - "pytorch", - ]: - kwargs = {"epochs": 1} - with pytest.raises(TypeError) as exception: - classifier.fit(x_train_mnist, y_train_mnist, batch_size=default_batch_size, nb_epochs=1, **kwargs) - - assert "multiple values for keyword argument" in str(exception) - except ARTTestException as e: art_warning(e) From aa6a0ee0dcc6309c5f80e1222c6ca79f94c900a9 Mon Sep 17 00:00:00 2001 From: Beat Buesser <49047826+beat-buesser@users.noreply.github.com> Date: Wed, 20 Dec 2023 10:45:12 +0100 Subject: [PATCH 19/26] Apply suggestions from code review --- art/estimators/classification/tensorflow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/art/estimators/classification/tensorflow.py b/art/estimators/classification/tensorflow.py index 6ead0ec234..33cc515ae1 100644 --- a/art/estimators/classification/tensorflow.py +++ b/art/estimators/classification/tensorflow.py @@ -358,7 +358,7 @@ def fit_generator( # pylint: disable=W0221 for _ in tqdm(range(nb_epochs), disable=not verbose, desc="Epochs"): gen_size = generator.size if isinstance(gen_size, int): - num_batchcs = int(gen_size / generator.batch_size) + num_batches = int(gen_size / generator.batch_size) else: raise ValueError("Number of batches could not be determined from the generator") From 56f7f4abe99413d27e0ab3fecb6788d54cf622a8 Mon Sep 17 00:00:00 2001 From: GiulioZizzo Date: Wed, 20 Dec 2023 11:54:38 +0000 Subject: [PATCH 20/26] unifying art tools in verbose interface Signed-off-by: GiulioZizzo --- art/attacks/extraction/knockoff_nets.py | 4 ++-- art/attacks/poisoning/sleeper_agent_attack.py | 4 ++-- art/defences/trainer/adversarial_trainer.py | 8 ++++++-- art/defences/trainer/dp_instahide_trainer.py | 4 ++-- .../randomized_smoothing/macer/pytorch.py | 3 --- .../randomized_smoothing/macer/tensorflow.py | 11 +---------- .../certification/randomized_smoothing/pytorch.py | 3 --- .../randomized_smoothing/randomized_smoothing.py | 8 +++----- .../randomized_smoothing/smooth_adv/pytorch.py | 3 --- .../randomized_smoothing/smooth_adv/tensorflow.py | 10 +--------- .../randomized_smoothing/smooth_mix/pytorch.py | 3 --- .../certification/randomized_smoothing/tensorflow.py | 10 +--------- art/estimators/classification/keras.py | 10 ++++++---- art/estimators/keras.py | 4 ++++ 14 files changed, 28 insertions(+), 57 deletions(-) diff --git a/art/attacks/extraction/knockoff_nets.py b/art/attacks/extraction/knockoff_nets.py index 50bcd44751..c630777b7f 100644 --- a/art/attacks/extraction/knockoff_nets.py +++ b/art/attacks/extraction/knockoff_nets.py @@ -155,7 +155,7 @@ def _random_extraction(self, x: np.ndarray, thieved_classifier: "CLASSIFIER_TYPE y=fake_labels, batch_size=self.batch_size_fit, nb_epochs=self.nb_epochs, - verbose=0, + verbose=False, ) return thieved_classifier @@ -243,7 +243,7 @@ def _adaptive_extraction( y=fake_label, batch_size=self.batch_size_fit, nb_epochs=1, - verbose=0, + verbose=False, ) # Test new labels diff --git a/art/attacks/poisoning/sleeper_agent_attack.py b/art/attacks/poisoning/sleeper_agent_attack.py index 505dff1554..ce140cc691 100644 --- a/art/attacks/poisoning/sleeper_agent_attack.py +++ b/art/attacks/poisoning/sleeper_agent_attack.py @@ -360,7 +360,7 @@ def _create_model( for layer in model_pt.model.children(): if hasattr(layer, "reset_parameters"): layer.reset_parameters() # type: ignore - model_pt.fit(x_train, y_train, batch_size=batch_size, nb_epochs=epochs, verbose=1) + model_pt.fit(x_train, y_train, batch_size=batch_size, nb_epochs=epochs, verbose=True) predictions = model_pt.predict(x_test) accuracy = np.sum(np.argmax(predictions, axis=1) == np.argmax(y_test, axis=1)) / len(y_test) logger.info("Accuracy of retrained model : %s", accuracy * 100.0) @@ -370,7 +370,7 @@ def _create_model( self.substitute_classifier.model.trainable = True model_tf = self.substitute_classifier.clone_for_refitting() - model_tf.fit(x_train, y_train, batch_size=batch_size, nb_epochs=epochs, verbose=0) + model_tf.fit(x_train, y_train, batch_size=batch_size, nb_epochs=epochs, verbose=False) predictions = model_tf.predict(x_test) accuracy = np.sum(np.argmax(predictions, axis=1) == np.argmax(y_test, axis=1)) / len(y_test) logger.info("Accuracy of retrained model : %s", accuracy * 100.0) diff --git a/art/defences/trainer/adversarial_trainer.py b/art/defences/trainer/adversarial_trainer.py index 69aaae252d..b33a34aa4f 100644 --- a/art/defences/trainer/adversarial_trainer.py +++ b/art/defences/trainer/adversarial_trainer.py @@ -188,7 +188,9 @@ def fit_generator(self, generator: "DataGenerator", nb_epochs: int = 20, **kwarg x_batch[adv_ids] = x_adv # Fit batch - self._classifier.fit(x_batch, y_batch, nb_epochs=1, batch_size=x_batch.shape[0], verbose=0, **kwargs) + self._classifier.fit( + x_batch, y_batch, nb_epochs=1, batch_size=x_batch.shape[0], verbose=False, **kwargs + ) attack_id = (attack_id + 1) % len(self.attacks) def fit( # pylint: disable=W0221 @@ -260,7 +262,9 @@ def fit( # pylint: disable=W0221 x_batch[adv_ids] = x_adv # Fit batch - self._classifier.fit(x_batch, y_batch, nb_epochs=1, batch_size=x_batch.shape[0], verbose=0, **kwargs) + self._classifier.fit( + x_batch, y_batch, nb_epochs=1, batch_size=x_batch.shape[0], verbose=False, **kwargs + ) attack_id = (attack_id + 1) % len(self.attacks) def predict(self, x: np.ndarray, **kwargs) -> np.ndarray: diff --git a/art/defences/trainer/dp_instahide_trainer.py b/art/defences/trainer/dp_instahide_trainer.py index 73f1277f8a..bc843a339d 100644 --- a/art/defences/trainer/dp_instahide_trainer.py +++ b/art/defences/trainer/dp_instahide_trainer.py @@ -155,7 +155,7 @@ def fit( # pylint: disable=W0221 x_aug = self._generate_noise(x_aug) # fit batch - self._classifier.fit(x_aug, y_aug, nb_epochs=1, batch_size=x_aug.shape[0], verbose=0, **kwargs) + self._classifier.fit(x_aug, y_aug, nb_epochs=1, batch_size=x_aug.shape[0], verbose=False, **kwargs) # get metrics loss = self._classifier.compute_loss(x_aug, y_aug, reduction="mean") @@ -234,7 +234,7 @@ def fit_generator(self, generator: "DataGenerator", nb_epochs: int = 20, **kwarg x_aug = self._generate_noise(x_aug) # fit batch - self._classifier.fit(x_aug, y_aug, nb_epochs=1, batch_size=x_aug.shape[0], verbose=0, **kwargs) + self._classifier.fit(x_aug, y_aug, nb_epochs=1, batch_size=x_aug.shape[0], verbose=False, **kwargs) # get metrics loss = self._classifier.compute_loss(x_aug, y_aug, reduction="mean") diff --git a/art/estimators/certification/randomized_smoothing/macer/pytorch.py b/art/estimators/certification/randomized_smoothing/macer/pytorch.py index 4bc13b1be5..ac3d1f3dfa 100644 --- a/art/estimators/certification/randomized_smoothing/macer/pytorch.py +++ b/art/estimators/certification/randomized_smoothing/macer/pytorch.py @@ -75,7 +75,6 @@ def __init__( gamma: float = 8.0, lmbda: float = 12.0, gaussian_samples: int = 16, - verbose: bool = False, ) -> None: """ Create a MACER classifier. @@ -105,7 +104,6 @@ def __init__( :param gamma: The hinge factor. :param lmbda: The trade-off factor. :param gaussian_samples: The number of gaussian samples per input. - :param verbose: Show progress bars. """ super().__init__( model=model, @@ -122,7 +120,6 @@ def __init__( sample_size=sample_size, scale=scale, alpha=alpha, - verbose=verbose, ) self.beta = beta self.gamma = gamma diff --git a/art/estimators/certification/randomized_smoothing/macer/tensorflow.py b/art/estimators/certification/randomized_smoothing/macer/tensorflow.py index 860921507c..cf0c921a7b 100644 --- a/art/estimators/certification/randomized_smoothing/macer/tensorflow.py +++ b/art/estimators/certification/randomized_smoothing/macer/tensorflow.py @@ -75,7 +75,6 @@ def __init__( gamma: float = 8.0, lmbda: float = 12.0, gaussian_samples: int = 16, - verbose: bool = False, ) -> None: """ Create a MACER classifier. @@ -108,7 +107,6 @@ def __init__( :param gamma: The hinge factor. :param lmbda: The trade-off factor. :param gaussian_samples: The number of gaussian samples per input. - :param verbose: Show progress bars. """ super().__init__( model=model, @@ -125,7 +123,6 @@ def __init__( sample_size=sample_size, scale=scale, alpha=alpha, - verbose=verbose, ) self.beta = beta self.gamma = gamma @@ -133,13 +130,7 @@ def __init__( self.gaussian_samples = gaussian_samples def fit( - self, - x: np.ndarray, - y: np.ndarray, - batch_size: int = 128, - nb_epochs: int = 10, - verbose: bool = False, - **kwargs + self, x: np.ndarray, y: np.ndarray, batch_size: int = 128, nb_epochs: int = 10, verbose: bool = False, **kwargs ) -> None: """ Fit the classifier on the training set `(x, y)`. diff --git a/art/estimators/certification/randomized_smoothing/pytorch.py b/art/estimators/certification/randomized_smoothing/pytorch.py index fddc7d0938..1006764080 100644 --- a/art/estimators/certification/randomized_smoothing/pytorch.py +++ b/art/estimators/certification/randomized_smoothing/pytorch.py @@ -71,7 +71,6 @@ def __init__( sample_size: int = 32, scale: float = 0.1, alpha: float = 0.001, - verbose: bool = False, ): """ Create a randomized smoothing classifier. @@ -97,7 +96,6 @@ def __init__( :param sample_size: Number of samples for smoothing. :param scale: Standard deviation of Gaussian noise added. :param alpha: The failure probability of smoothing. - :param verbose: Show progress bars. """ if preprocessing_defences is not None: warnings.warn( @@ -120,7 +118,6 @@ def __init__( sample_size=sample_size, scale=scale, alpha=alpha, - verbose=verbose, ) def _predict_classifier(self, x: np.ndarray, batch_size: int, training_mode: bool, **kwargs) -> np.ndarray: diff --git a/art/estimators/certification/randomized_smoothing/randomized_smoothing.py b/art/estimators/certification/randomized_smoothing/randomized_smoothing.py index e9b188c494..6027bd4d5e 100644 --- a/art/estimators/certification/randomized_smoothing/randomized_smoothing.py +++ b/art/estimators/certification/randomized_smoothing/randomized_smoothing.py @@ -49,7 +49,6 @@ def __init__( *args, scale: float = 0.1, alpha: float = 0.001, - verbose: bool = False, **kwargs, ) -> None: """ @@ -58,13 +57,11 @@ def __init__( :param sample_size: Number of samples for smoothing. :param scale: Standard deviation of Gaussian noise added. :param alpha: The failure probability of smoothing. - :param verbose: Show progress bars. """ super().__init__(*args, **kwargs) # type: ignore self.sample_size = sample_size self.scale = scale self.alpha = alpha - self.verbose = verbose def _predict_classifier(self, x: np.ndarray, batch_size: int, training_mode: bool, **kwargs) -> np.ndarray: """ @@ -77,12 +74,13 @@ def _predict_classifier(self, x: np.ndarray, batch_size: int, training_mode: boo """ raise NotImplementedError - def predict(self, x: np.ndarray, batch_size: int = 128, **kwargs) -> np.ndarray: + def predict(self, x: np.ndarray, batch_size: int = 128, verbose: bool = False, **kwargs) -> np.ndarray: """ Perform prediction of the given classifier for a batch of inputs, taking an expectation over transformations. :param x: Input samples. :param batch_size: Batch size. + :param verbose: Display training progress bar. :param is_abstain: True if function will abstain from prediction and return 0s. Default: True :type is_abstain: `boolean` :return: Array of predictions of shape `(nb_inputs, nb_classes)`. @@ -98,7 +96,7 @@ def predict(self, x: np.ndarray, batch_size: int = 128, **kwargs) -> np.ndarray: logger.info("Applying randomized smoothing.") n_abstained = 0 prediction = [] - for x_i in tqdm(x, desc="Randomized smoothing", disable=not self.verbose): + for x_i in tqdm(x, desc="Randomized smoothing", disable=not verbose): # get class counts counts_pred = self._prediction_counts(x_i, batch_size=batch_size) top = counts_pred.argsort()[::-1] diff --git a/art/estimators/certification/randomized_smoothing/smooth_adv/pytorch.py b/art/estimators/certification/randomized_smoothing/smooth_adv/pytorch.py index a0ac0a1742..e57f4c7c88 100644 --- a/art/estimators/certification/randomized_smoothing/smooth_adv/pytorch.py +++ b/art/estimators/certification/randomized_smoothing/smooth_adv/pytorch.py @@ -77,7 +77,6 @@ def __init__( num_noise_vec: int = 1, num_steps: int = 10, warmup: int = 1, - verbose: bool = False, ) -> None: """ Create a SmoothAdv classifier. @@ -107,7 +106,6 @@ def __init__( :param num_noise_vec: The number of noise vectors. :param num_steps: The number of attack updates. :param warmup: The warm-up strategy that is gradually increased up to the original value. - :param verbose: Show progress bars. """ super().__init__( model=model, @@ -124,7 +122,6 @@ def __init__( sample_size=sample_size, scale=scale, alpha=alpha, - verbose=verbose, ) self.epsilon = epsilon self.num_noise_vec = num_noise_vec diff --git a/art/estimators/certification/randomized_smoothing/smooth_adv/tensorflow.py b/art/estimators/certification/randomized_smoothing/smooth_adv/tensorflow.py index 0d8b960de0..f83341ab6f 100644 --- a/art/estimators/certification/randomized_smoothing/smooth_adv/tensorflow.py +++ b/art/estimators/certification/randomized_smoothing/smooth_adv/tensorflow.py @@ -77,7 +77,6 @@ def __init__( num_noise_vec: int = 1, num_steps: int = 10, warmup: int = 1, - verbose: bool = False, ) -> None: """ Create a MACER classifier. @@ -110,7 +109,6 @@ def __init__( :param num_noise_vec: The number of noise vectors. :param num_steps: The number of attack updates. :param warmup: The warm-up strategy that is gradually increased up to the original value. - :param verbose: Show progress bars. """ super().__init__( model=model, @@ -150,13 +148,7 @@ def __init__( self.attack = ProjectedGradientDescent(classifier, eps=self.epsilon, max_iter=1, verbose=False) def fit( - self, - x: np.ndarray, - y: np.ndarray, - batch_size: int = 128, - nb_epochs: int = 10, - verbose: bool = False, - **kwargs + self, x: np.ndarray, y: np.ndarray, batch_size: int = 128, nb_epochs: int = 10, verbose: bool = False, **kwargs ) -> None: """ Fit the classifier on the training set `(x, y)`. diff --git a/art/estimators/certification/randomized_smoothing/smooth_mix/pytorch.py b/art/estimators/certification/randomized_smoothing/smooth_mix/pytorch.py index 9a84470edc..a23fba769e 100644 --- a/art/estimators/certification/randomized_smoothing/smooth_mix/pytorch.py +++ b/art/estimators/certification/randomized_smoothing/smooth_mix/pytorch.py @@ -103,7 +103,6 @@ def __init__( mix_step: int = 0, maxnorm_s: Optional[float] = None, maxnorm: Optional[float] = None, - verbose: bool = False, ) -> None: """ Create a SmoothMix classifier. @@ -136,7 +135,6 @@ def __init__( :param mix_step: Determines which sample to use for the clean side. :param maxnorm_s: The initial value of `alpha * mix_step`. :param maxnorm: The initial value of `alpha * mix_step` for adversarial examples. - :param verbose: Show progress bars. """ super().__init__( model=model, @@ -153,7 +151,6 @@ def __init__( sample_size=sample_size, scale=scale, alpha=alpha, - verbose=verbose, ) self.eta = eta self.num_noise_vec = num_noise_vec diff --git a/art/estimators/certification/randomized_smoothing/tensorflow.py b/art/estimators/certification/randomized_smoothing/tensorflow.py index 6c6949a770..db148b389f 100644 --- a/art/estimators/certification/randomized_smoothing/tensorflow.py +++ b/art/estimators/certification/randomized_smoothing/tensorflow.py @@ -99,7 +99,6 @@ def __init__( :param sample_size: Number of samples for smoothing. :param scale: Standard deviation of Gaussian noise added. :param alpha: The failure probability of smoothing. - :param verbose: Show progress bars. """ if preprocessing_defences is not None: warnings.warn( @@ -122,7 +121,6 @@ def __init__( sample_size=sample_size, scale=scale, alpha=alpha, - verbose=verbose, ) def _predict_classifier(self, x: np.ndarray, batch_size: int, training_mode: bool, **kwargs) -> np.ndarray: @@ -132,13 +130,7 @@ def _fit_classifier(self, x: np.ndarray, y: np.ndarray, batch_size: int, nb_epoc return TensorFlowV2Classifier.fit(self, x, y, batch_size=batch_size, nb_epochs=nb_epochs, **kwargs) def fit( # pylint: disable=W0221 - self, - x: np.ndarray, - y: np.ndarray, - batch_size: int = 128, - nb_epochs: int = 10, - verbose: bool = False, - **kwargs + self, x: np.ndarray, y: np.ndarray, batch_size: int = 128, nb_epochs: int = 10, verbose: bool = False, **kwargs ) -> None: """ Fit the classifier on the training set `(x, y)`. diff --git a/art/estimators/classification/keras.py b/art/estimators/classification/keras.py index 21bb9afcee..b7404f713e 100644 --- a/art/estimators/classification/keras.py +++ b/art/estimators/classification/keras.py @@ -582,6 +582,9 @@ def fit(self, x: np.ndarray, y: np.ndarray, batch_size: int = 128, nb_epochs: in if self._reduce_labels or y_ndim == 1: y_preprocessed = np.argmax(y_preprocessed, axis=1) + if "verbose" in kwargs: + kwargs["verbose"] = int(kwargs["verbose"]) + self._model.fit(x=x_preprocessed, y=y_preprocessed, batch_size=batch_size, epochs=nb_epochs, **kwargs) def fit_generator(self, generator: "DataGenerator", nb_epochs: int = 20, **kwargs) -> None: @@ -600,6 +603,9 @@ def fit_generator(self, generator: "DataGenerator", nb_epochs: int = 20, **kwarg # Try to use the generator as a Keras native generator, otherwise use it through the `DataGenerator` interface from art.preprocessing.standardisation_mean_std.numpy import StandardisationMeanStd + if "verbose" in kwargs: + kwargs["verbose"] = int(kwargs["verbose"]) + if isinstance(generator, KerasDataGenerator) and ( self.preprocessing is None or ( @@ -615,12 +621,8 @@ def fit_generator(self, generator: "DataGenerator", nb_epochs: int = 20, **kwarg self._model.fit_generator(generator.iterator, epochs=nb_epochs, **kwargs) except ValueError: # pragma: no cover logger.info("Unable to use data generator as Keras generator. Now treating as framework-independent.") - if "verbose" not in kwargs: - kwargs["verbose"] = 0 super().fit_generator(generator, nb_epochs=nb_epochs, **kwargs) else: # pragma: no cover - if "verbose" not in kwargs: - kwargs["verbose"] = 0 super().fit_generator(generator, nb_epochs=nb_epochs, **kwargs) def get_activations( diff --git a/art/estimators/keras.py b/art/estimators/keras.py index c6e1e943e9..5ef58bd5df 100644 --- a/art/estimators/keras.py +++ b/art/estimators/keras.py @@ -61,6 +61,8 @@ def predict(self, x: np.ndarray, batch_size: int = 128, **kwargs): :return: Predictions. :rtype: Format as expected by the `model` """ + if "verbose" in kwargs: + kwargs["verbose"] = int(kwargs["verbose"]) return NeuralNetworkMixin.predict(self, x, batch_size=batch_size, **kwargs) def fit(self, x: np.ndarray, y, batch_size: int = 128, nb_epochs: int = 20, **kwargs) -> None: @@ -74,6 +76,8 @@ def fit(self, x: np.ndarray, y, batch_size: int = 128, nb_epochs: int = 20, **kw :param batch_size: Batch size. :param nb_epochs: Number of training epochs. """ + if "verbose" in kwargs: + kwargs["verbose"] = int(kwargs["verbose"]) NeuralNetworkMixin.fit(self, x, y, batch_size=batch_size, nb_epochs=nb_epochs, **kwargs) def compute_loss(self, x: np.ndarray, y: np.ndarray, **kwargs) -> np.ndarray: From 63916b202c5c717fe738cbf489cdc1533297df46 Mon Sep 17 00:00:00 2001 From: GiulioZizzo Date: Wed, 20 Dec 2023 15:23:11 +0000 Subject: [PATCH 21/26] mypy fixes Signed-off-by: GiulioZizzo --- .../certification/randomized_smoothing/pytorch.py | 7 +++++-- .../randomized_smoothing/smooth_adv/tensorflow.py | 1 - .../certification/randomized_smoothing/tensorflow.py | 8 +++++--- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/art/estimators/certification/randomized_smoothing/pytorch.py b/art/estimators/certification/randomized_smoothing/pytorch.py index 1006764080..e00f66692e 100644 --- a/art/estimators/certification/randomized_smoothing/pytorch.py +++ b/art/estimators/certification/randomized_smoothing/pytorch.py @@ -222,17 +222,20 @@ def fit( # pylint: disable=W0221 if scheduler is not None: scheduler.step() - def predict(self, x: np.ndarray, batch_size: int = 128, **kwargs) -> np.ndarray: # type: ignore + def predict(self, x: np.ndarray, batch_size: int = 128, verbose: bool = False, **kwargs) -> np.ndarray: # type: ignore """ Perform prediction of the given classifier for a batch of inputs, taking an expectation over transformations. :param x: Input samples. :param batch_size: Batch size. + :param verbose: Display training progress bar. :param is_abstain: True if function will abstain from prediction and return 0s. Default: True :type is_abstain: `boolean` :return: Array of predictions of shape `(nb_inputs, nb_classes)`. """ - return RandomizedSmoothingMixin.predict(self, x, batch_size=batch_size, training_mode=False, **kwargs) + return RandomizedSmoothingMixin.predict( + self, x, batch_size=batch_size, verbose=verbose, training_mode=False, **kwargs + ) def loss_gradient( # type: ignore self, x: np.ndarray, y: np.ndarray, training_mode: bool = False, **kwargs diff --git a/art/estimators/certification/randomized_smoothing/smooth_adv/tensorflow.py b/art/estimators/certification/randomized_smoothing/smooth_adv/tensorflow.py index f83341ab6f..0887e7ce6c 100644 --- a/art/estimators/certification/randomized_smoothing/smooth_adv/tensorflow.py +++ b/art/estimators/certification/randomized_smoothing/smooth_adv/tensorflow.py @@ -125,7 +125,6 @@ def __init__( sample_size=sample_size, scale=scale, alpha=alpha, - verbose=verbose, ) self.epsilon = epsilon self.num_noise_vec = num_noise_vec diff --git a/art/estimators/certification/randomized_smoothing/tensorflow.py b/art/estimators/certification/randomized_smoothing/tensorflow.py index db148b389f..908feb381d 100644 --- a/art/estimators/certification/randomized_smoothing/tensorflow.py +++ b/art/estimators/certification/randomized_smoothing/tensorflow.py @@ -70,7 +70,6 @@ def __init__( sample_size: int = 32, scale: float = 0.1, alpha: float = 0.001, - verbose: bool = False, ): """ Create a randomized smoothing classifier. @@ -192,17 +191,20 @@ def train_step(model, images, labels): if scheduler is not None: scheduler(epoch) - def predict(self, x: np.ndarray, batch_size: int = 128, **kwargs) -> np.ndarray: # type: ignore + def predict(self, x: np.ndarray, batch_size: int = 128, verbose: bool = False, **kwargs) -> np.ndarray: # type: ignore """ Perform prediction of the given classifier for a batch of inputs, taking an expectation over transformations. :param x: Input samples. :param batch_size: Batch size. + :param verbose: Display training progress bar. :param is_abstain: True if function will abstain from prediction and return 0s. Default: True :type is_abstain: `boolean` :return: Array of predictions of shape `(nb_inputs, nb_classes)`. """ - return RandomizedSmoothingMixin.predict(self, x, batch_size=batch_size, training_mode=False, **kwargs) + return RandomizedSmoothingMixin.predict( + self, x, batch_size=batch_size, verbose=verbose, training_mode=False, **kwargs + ) def loss_gradient(self, x: np.ndarray, y: np.ndarray, training_mode: bool = False, **kwargs) -> np.ndarray: """ From b817b9ca9070a866b57758a01270898b6746219d Mon Sep 17 00:00:00 2001 From: GiulioZizzo Date: Wed, 20 Dec 2023 17:47:20 +0000 Subject: [PATCH 22/26] mypy fixes Signed-off-by: GiulioZizzo --- art/estimators/certification/randomized_smoothing/pytorch.py | 4 +++- .../certification/randomized_smoothing/tensorflow.py | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/art/estimators/certification/randomized_smoothing/pytorch.py b/art/estimators/certification/randomized_smoothing/pytorch.py index e00f66692e..57ec55a3ee 100644 --- a/art/estimators/certification/randomized_smoothing/pytorch.py +++ b/art/estimators/certification/randomized_smoothing/pytorch.py @@ -222,7 +222,9 @@ def fit( # pylint: disable=W0221 if scheduler is not None: scheduler.step() - def predict(self, x: np.ndarray, batch_size: int = 128, verbose: bool = False, **kwargs) -> np.ndarray: # type: ignore + def predict( # type: ignore + self, x: np.ndarray, batch_size: int = 128, verbose: bool = False, **kwargs + ) -> np.ndarray: """ Perform prediction of the given classifier for a batch of inputs, taking an expectation over transformations. diff --git a/art/estimators/certification/randomized_smoothing/tensorflow.py b/art/estimators/certification/randomized_smoothing/tensorflow.py index 908feb381d..636b62f547 100644 --- a/art/estimators/certification/randomized_smoothing/tensorflow.py +++ b/art/estimators/certification/randomized_smoothing/tensorflow.py @@ -191,7 +191,9 @@ def train_step(model, images, labels): if scheduler is not None: scheduler(epoch) - def predict(self, x: np.ndarray, batch_size: int = 128, verbose: bool = False, **kwargs) -> np.ndarray: # type: ignore + def predict( # type: ignore + self, x: np.ndarray, batch_size: int = 128, verbose: bool = False, **kwargs + ) -> np.ndarray: """ Perform prediction of the given classifier for a batch of inputs, taking an expectation over transformations. From 4111de68df706a2858ebf4fe89bda91e14213c79 Mon Sep 17 00:00:00 2001 From: Farhan Ahmed Date: Tue, 14 Nov 2023 12:04:50 -0800 Subject: [PATCH 23/26] flatten activations for poisoning defenses Signed-off-by: Farhan Ahmed --- art/defences/detector/poison/activation_defence.py | 4 +++- art/defences/detector/poison/spectral_signature_defense.py | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/art/defences/detector/poison/activation_defence.py b/art/defences/detector/poison/activation_defence.py index 9b53235bf4..45b09d0e4d 100644 --- a/art/defences/detector/poison/activation_defence.py +++ b/art/defences/detector/poison/activation_defence.py @@ -695,7 +695,9 @@ def _get_activations(self, x_train: Optional[np.ndarray] = None) -> np.ndarray: # wrong way to get activations activations = self.classifier.predict(self.x_train) if isinstance(activations, np.ndarray): - nodes_last_layer = np.shape(activations)[1] + # flatten activations across batch + activations = np.reshape(activations, (activations.shape[0], -1)) + nodes_last_layer = activations.shape[1] else: raise ValueError("activations is None or tensor.") diff --git a/art/defences/detector/poison/spectral_signature_defense.py b/art/defences/detector/poison/spectral_signature_defense.py index 69109f2d61..8fd44a3200 100644 --- a/art/defences/detector/poison/spectral_signature_defense.py +++ b/art/defences/detector/poison/spectral_signature_defense.py @@ -121,6 +121,8 @@ def detect_poison(self, **kwargs) -> Tuple[dict, List[int]]: raise ValueError("Wrong type detected.") if features_x_poisoned is not None: + # flatten activations across batch + features_x_poisoned = np.reshape(features_x_poisoned, (features_x_poisoned.shape[0], -1)) features_split = segment_by_class(features_x_poisoned, self.y_train, self.classifier.nb_classes) else: raise ValueError("Activation are `None`.") From 47801a779606285bd067b7fa35e9434431c437c3 Mon Sep 17 00:00:00 2001 From: Farhan Ahmed Date: Tue, 14 Nov 2023 12:05:12 -0800 Subject: [PATCH 24/26] remove huggingface estimator activation hack Signed-off-by: Farhan Ahmed --- art/estimators/classification/hugging_face.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/art/estimators/classification/hugging_face.py b/art/estimators/classification/hugging_face.py index 3bf8099e1b..33e512f45d 100644 --- a/art/estimators/classification/hugging_face.py +++ b/art/estimators/classification/hugging_face.py @@ -324,11 +324,7 @@ def get_activations( # type: ignore def get_feature(name): # the hook signature def hook(model, input, output): # pylint: disable=W0622,W0613 - # TODO: this is using the input, rather than the output, to circumvent the fact - # TODO: that flatten is not a layer in pytorch, and the activation defence expects - # TODO: a flattened input. A better option is to refactor the activation defence - # TODO: to not crash if non 2D inputs are provided. - self._features[name] = input + self._features[name] = output return hook From b8607cf89eec524d3cc1de6cd2a5c489565d7141 Mon Sep 17 00:00:00 2001 From: Farhan Ahmed Date: Thu, 7 Dec 2023 16:21:38 -0800 Subject: [PATCH 25/26] Revert "remove huggingface estimator activation hack" This reverts commit 4db76267ccac573c81086e8b53accd55379606db. Signed-off-by: Farhan Ahmed --- art/estimators/classification/hugging_face.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/art/estimators/classification/hugging_face.py b/art/estimators/classification/hugging_face.py index 33e512f45d..3bf8099e1b 100644 --- a/art/estimators/classification/hugging_face.py +++ b/art/estimators/classification/hugging_face.py @@ -324,7 +324,11 @@ def get_activations( # type: ignore def get_feature(name): # the hook signature def hook(model, input, output): # pylint: disable=W0622,W0613 - self._features[name] = output + # TODO: this is using the input, rather than the output, to circumvent the fact + # TODO: that flatten is not a layer in pytorch, and the activation defence expects + # TODO: a flattened input. A better option is to refactor the activation defence + # TODO: to not crash if non 2D inputs are provided. + self._features[name] = input return hook From b62f8665dc4334dd90a11dfef4dfb923201353c5 Mon Sep 17 00:00:00 2001 From: Beat Buesser Date: Fri, 22 Dec 2023 23:15:37 +0100 Subject: [PATCH 26/26] Update KerasClassifier for verbose argument Signed-off-by: Beat Buesser --- art/estimators/classification/keras.py | 24 ++++++++++++------------ art/estimators/classification/pytorch.py | 2 +- art/estimators/keras.py | 4 ---- 3 files changed, 13 insertions(+), 17 deletions(-) diff --git a/art/estimators/classification/keras.py b/art/estimators/classification/keras.py index b7404f713e..728068d313 100644 --- a/art/estimators/classification/keras.py +++ b/art/estimators/classification/keras.py @@ -559,7 +559,9 @@ def predict( # pylint: disable=W0221 return predictions - def fit(self, x: np.ndarray, y: np.ndarray, batch_size: int = 128, nb_epochs: int = 20, **kwargs) -> None: + def fit( + self, x: np.ndarray, y: np.ndarray, batch_size: int = 128, nb_epochs: int = 20, verbose: bool = False, **kwargs + ) -> None: """ Fit the classifier on the training set `(x, y)`. @@ -568,6 +570,7 @@ def fit(self, x: np.ndarray, y: np.ndarray, batch_size: int = 128, nb_epochs: in shape (nb_samples,). :param batch_size: Size of batches. :param nb_epochs: Number of epochs to use for training. + :param verbose: Display training progress bar. :param kwargs: Dictionary of framework-specific arguments. These should be parameters supported by the `fit_generator` function in Keras and will be passed to this function as such. Including the number of epochs or the number of steps per epoch as part of this argument will result in as error. @@ -582,18 +585,18 @@ def fit(self, x: np.ndarray, y: np.ndarray, batch_size: int = 128, nb_epochs: in if self._reduce_labels or y_ndim == 1: y_preprocessed = np.argmax(y_preprocessed, axis=1) - if "verbose" in kwargs: - kwargs["verbose"] = int(kwargs["verbose"]) - - self._model.fit(x=x_preprocessed, y=y_preprocessed, batch_size=batch_size, epochs=nb_epochs, **kwargs) + self._model.fit( + x=x_preprocessed, y=y_preprocessed, batch_size=batch_size, epochs=nb_epochs, verbose=int(verbose), **kwargs + ) - def fit_generator(self, generator: "DataGenerator", nb_epochs: int = 20, **kwargs) -> None: + def fit_generator(self, generator: "DataGenerator", nb_epochs: int = 20, verbose: bool = False, **kwargs) -> None: """ Fit the classifier using the generator that yields batches as specified. :param generator: Batch generator providing `(x, y)` for each epoch. If the generator can be used for native training in Keras, it will. :param nb_epochs: Number of epochs to use for training. + :param verbose: Display training progress bar. :param kwargs: Dictionary of framework-specific arguments. These should be parameters supported by the `fit_generator` function in Keras and will be passed to this function as such. Including the number of epochs as part of this argument will result in as error. @@ -603,9 +606,6 @@ def fit_generator(self, generator: "DataGenerator", nb_epochs: int = 20, **kwarg # Try to use the generator as a Keras native generator, otherwise use it through the `DataGenerator` interface from art.preprocessing.standardisation_mean_std.numpy import StandardisationMeanStd - if "verbose" in kwargs: - kwargs["verbose"] = int(kwargs["verbose"]) - if isinstance(generator, KerasDataGenerator) and ( self.preprocessing is None or ( @@ -618,12 +618,12 @@ def fit_generator(self, generator: "DataGenerator", nb_epochs: int = 20, **kwarg ) ): try: - self._model.fit_generator(generator.iterator, epochs=nb_epochs, **kwargs) + self._model.fit_generator(generator.iterator, epochs=nb_epochs, verbose=int(verbose), **kwargs) except ValueError: # pragma: no cover logger.info("Unable to use data generator as Keras generator. Now treating as framework-independent.") - super().fit_generator(generator, nb_epochs=nb_epochs, **kwargs) + super().fit_generator(generator, nb_epochs=nb_epochs, verbose=verbose, **kwargs) else: # pragma: no cover - super().fit_generator(generator, nb_epochs=nb_epochs, **kwargs) + super().fit_generator(generator, nb_epochs=nb_epochs, verbose=verbose, **kwargs) def get_activations( self, x: np.ndarray, layer: Union[int, str], batch_size: int = 128, framework: bool = False diff --git a/art/estimators/classification/pytorch.py b/art/estimators/classification/pytorch.py index a9fe17ab89..5216c02c21 100644 --- a/art/estimators/classification/pytorch.py +++ b/art/estimators/classification/pytorch.py @@ -391,7 +391,7 @@ def fit( # pylint: disable=W0221 the batch size. If ``False`` and the size of dataset is not divisible by the batch size, then the last batch will be smaller. (default: ``False``) :param scheduler: Learning rate scheduler to run at the start of every epoch. - :param verbose: If to display the progress bar information. + :param verbose: Display training progress bar. :param kwargs: Dictionary of framework-specific arguments. This parameter is not currently supported for PyTorch and providing it takes no effect. """ diff --git a/art/estimators/keras.py b/art/estimators/keras.py index 5ef58bd5df..c6e1e943e9 100644 --- a/art/estimators/keras.py +++ b/art/estimators/keras.py @@ -61,8 +61,6 @@ def predict(self, x: np.ndarray, batch_size: int = 128, **kwargs): :return: Predictions. :rtype: Format as expected by the `model` """ - if "verbose" in kwargs: - kwargs["verbose"] = int(kwargs["verbose"]) return NeuralNetworkMixin.predict(self, x, batch_size=batch_size, **kwargs) def fit(self, x: np.ndarray, y, batch_size: int = 128, nb_epochs: int = 20, **kwargs) -> None: @@ -76,8 +74,6 @@ def fit(self, x: np.ndarray, y, batch_size: int = 128, nb_epochs: int = 20, **kw :param batch_size: Batch size. :param nb_epochs: Number of training epochs. """ - if "verbose" in kwargs: - kwargs["verbose"] = int(kwargs["verbose"]) NeuralNetworkMixin.fit(self, x, y, batch_size=batch_size, nb_epochs=nb_epochs, **kwargs) def compute_loss(self, x: np.ndarray, y: np.ndarray, **kwargs) -> np.ndarray: