From 6fec117a9f0291b468dc155633ce01a1f105b62f Mon Sep 17 00:00:00 2001 From: Harry Kim <24K.Harry@gmail.com> Date: Thu, 23 Dec 2021 12:38:14 +0900 Subject: [PATCH] v3.2.4 --- UPDATE_HISTORY.md | 177 +++++++++++++++------------- torchattacks/__init__.py | 2 +- torchattacks/attack.py | 10 +- torchattacks/attacks/multiattack.py | 13 +- 4 files changed, 109 insertions(+), 93 deletions(-) diff --git a/UPDATE_HISTORY.md b/UPDATE_HISTORY.md index eaeb06a8..2b8aae93 100644 --- a/UPDATE_HISTORY.md +++ b/UPDATE_HISTORY.md @@ -1,58 +1,67 @@ - ### ~~v0.3~~ + * ~~**New Attacks** : FGSM, IFGSM, IterLL, RFGSM, CW(L2), PGD are added.~~ * ~~**Demos** are uploaded.~~ ### ~~v0.4~~ + * ~~**DO NOT USE** : 'init.py' is omitted.~~ ### ~~v0.5~~ + * ~~**Package name changed** : 'attacks' is changed to 'torchattacks'.~~ * ~~**New Attack** : APGD is added.~~ * ~~**attack.py** : 'update_model' method is added.~~ ### ~~v0.6~~ + * ~~**Error Solved** :~~ - * ~~Before this version, even after getting an adversarial image, the model remains evaluation mode.~~ - * ~~To solve this, below methods are modified.~~ - * ~~'_switch_model' method is added into **attack.py**. It will automatically change model mode to the previous mode after getting adversarial images. When getting adversarial images, model is switched to evaluation mode.~~ - * ~~'__call__' methods in all attack changed to forward. Instead of this, '__call__' method is added into 'attack.py'~~ + * ~~Before this version, even after getting an adversarial image, the model remains evaluation mode.~~ + * ~~To solve this, below methods are modified.~~ + * ~~'_switch_model' method is added into **attack.py**. It will automatically change model mode to the previous mode after getting adversarial images. When getting adversarial images, model is switched to evaluation mode.~~ + * ~~'__call__' methods in all attack changed to forward. Instead of this, '__call__' method is added into 'attack.py'~~ * ~~**attack.py** : To provide ease of changing images to uint8 from float, 'set_mode' and '_to_uint' is added.~~ - * ~~'set_mode' determines returning all outputs as 'int' OR 'flaot' through '_to_uint'.~~ - * ~~'_to_uint' changes all outputs into uint8.~~ + * ~~'set_mode' determines returning all outputs as 'int' OR 'flaot' through '_to_uint'.~~ + * ~~'_to_uint' changes all outputs into uint8.~~ ### ~~v0.7~~ + * ~~**All attacks are modified**~~ - * ~~clone().detach() is used instead of .data~~ - * ~~torch.autograd.grad is used instead of .backward() and .grad :~~ - * ~~It showed 2% reduction of computation time.~~ - + * ~~clone().detach() is used instead of .data~~ + * ~~torch.autograd.grad is used instead of .backward() and .grad :~~ + * ~~It showed 2% reduction of computation time.~~ + ### ~~v0.8~~ + * ~~**New Attack** : RPGD is added.~~ * ~~**attack.py** : 'update_model' method is depreciated. Because torch models are passed by call-by-reference, we don't need to update models.~~ - * ~~**cw.py** : In the process of cw attack, now masked_select uses a mask with dtype torch.bool instead of a mask with dtype torch.uint8.~~ + * ~~**cw.py** : In the process of cw attack, now masked_select uses a mask with dtype torch.bool instead of a mask with dtype torch.uint8.~~ ### ~~v0.9~~ + * ~~**New Attack** : DeepFool is added.~~ * ~~**Some attacks are renamed** :~~ - * ~~I-FGSM -> BIM~~ - * ~~IterLL -> StepLL~~ + * ~~I-FGSM -> BIM~~ + * ~~IterLL -> StepLL~~ ### ~~v1.0~~ + * ~~**attack.py** :~~ - * ~~**load** : Load is depreciated. Instead, use TensorDataset and DataLoader.~~ - * ~~**save** : The problem of calculating invalid accuracy when the mode of the attack set to 'int' is solved.~~ + * ~~**load** : Load is depreciated. Instead, use TensorDataset and DataLoader.~~ + * ~~**save** : The problem of calculating invalid accuracy when the mode of the attack set to 'int' is solved.~~ ### ~~v1.1~~ + * ~~**DeepFool** :~~ - * ~~[**Error solved**](https://github.com/Harry24k/adversairal-attacks-pytorch/issues/2).~~ - + * ~~[**Error solved**](https://github.com/Harry24k/adversairal-attacks-pytorch/issues/2).~~ + ### ~~v1.2~~ + * ~~**Description has been added for each module.**~~ * ~~**Sphinx Document uploaded**~~ * ~~**attack.py** : 'device' will be decided by [next(model.parameters()).device](https://github.com/Harry24k/adversarial-attacks-pytorch/issues/3#issue-602571865).~~ * ~~**Two attacks are merged** :~~ - * ~~RPGD, PGD -> PGD~~ + * ~~RPGD, PGD -> PGD~~ @@ -144,93 +153,94 @@ ### v2.11.0 * ``CW`` - * Now it outputs the best L2 adversarial images. - * Faster computation. + * Now it outputs the best L2 adversarial images. + * Faster computation. * `DeepFool` - * Make the codes cleaner. + * Make the codes cleaner. * `BIM` - * Bug fixed: Wrong cliping. + * Bug fixed: Wrong cliping. * `MIFGSM` - * Bug fixed: Wrong cliping. - * Bug fixed: [Gradient Norm](https://github.com/Harry24k/adversarial-attacks-pytorch/issues/12). + * Bug fixed: Wrong cliping. + * Bug fixed: [Gradient Norm](https://github.com/Harry24k/adversarial-attacks-pytorch/issues/12). * Demo Added - * Performance Comparison (CIFAR10) + * Performance Comparison (CIFAR10) ### v2.12.1 * `DeepFool` - * Deprecated. + * Deprecated. * `Attack._targeted` - * ._targeted is set to 1 when targeted mode is activated. [Issue](https://github.com/Harry24k/adversarial-attacks-pytorch/issues/14). - * All attacks supporting targeted mode is change. + * ._targeted is set to 1 when targeted mode is activated. [Issue](https://github.com/Harry24k/adversarial-attacks-pytorch/issues/14). + * All attacks supporting targeted mode is change. * `Attack.set_attack_mode` - * To provide various attack mode, it uses following methods. - * `set_default_mode`: default mode. - * `set_targeted_mode`: targeted mode. Now supporting `target_map_function=None` for pre-generated targeted labels. - * `set_least_likely_mode`: least likely targeted mode. Now supporting k-th smallest probability targeted mode by `kth_min`. + * To provide various attack mode, it uses following methods. + * `set_default_mode`: default mode. + * `set_targeted_mode`: targeted mode. Now supporting `target_map_function=None` for pre-generated targeted labels. + * `set_least_likely_mode`: least likely targeted mode. Now supporting k-th smallest probability targeted mode by `kth_min`. * `Attack.save` - * Bug fixed: When `verbose=True`, it now use model.eval() and torch.no_grad(). + * Bug fixed: When `verbose=True`, it now use model.eval() and torch.no_grad(). ### v2.12.1 * `DeepFool` - * Deprecated. + * Deprecated. * `Attack._targeted` - * ._targeted is set to 1 when targeted mode is activated. [Issue](https://github.com/Harry24k/adversarial-attacks-pytorch/issues/14). - * All attacks supporting targeted mode is change. + * ._targeted is set to 1 when targeted mode is activated. [Issue](https://github.com/Harry24k/adversarial-attacks-pytorch/issues/14). + * All attacks supporting targeted mode is change. * `Attack.set_attack_mode` - * To provide various attack mode, it uses following methods. - * `set_default_mode`: default mode. - * `set_targeted_mode`: targeted mode. Now supporting `target_map_function=None` for pre-generated targeted labels. - * `set_least_likely_mode`: least likely targeted mode. Now supporting k-th smallest probability targeted mode by `kth_min`. + * To provide various attack mode, it uses following methods. + * `set_default_mode`: default mode. + * `set_targeted_mode`: targeted mode. Now supporting `target_map_function=None` for pre-generated targeted labels. + * `set_least_likely_mode`: least likely targeted mode. Now supporting k-th smallest probability targeted mode by `kth_min`. * `Attack.save` - * Bug fixed: When `verbose=True`, it now use model.eval() and torch.no_grad(). + * Bug fixed: When `verbose=True`, it now use model.eval() and torch.no_grad(). ### v2.12.2 * `PGDL2` - * PGD with L2 distance measure. + * PGD with L2 distance measure. * `Attack.save` - * Print L2 distance between adversarial examples and the original examples. + * Print L2 distance between adversarial examples and the original examples. ### v2.12.3 * `PGDL2` + * Initialization perturbation is changed. + - - + ### v2.13.1 * `Attack.set_attack_mode` - * Deprecated. Use following built-in functions. - * `set_mode_default`: default mode. - * `set_mode_targeted`: targeted mode. Now supporting `target_map_function=None` for pre-generated targeted labels. - * `set_mode_least_likely`: least likely targeted mode. Now supporting k-th smallest probability targeted mode by `kth_min`. + * Deprecated. Use following built-in functions. + * `set_mode_default`: default mode. + * `set_mode_targeted`: targeted mode. Now supporting `target_map_function=None` for pre-generated targeted labels. + * `set_mode_least_likely`: least likely targeted mode. Now supporting k-th smallest probability targeted mode by `kth_min`. * `APGD` is changed to `EOTPGD`. * `PGDDLR` is added. * `APGD`, `APGDT`, `Square`, `FAB` - * Modified from https://github.com/fra31/auto-attack. - * `n_iters` is changed to `steps`. - * `n_target_classes` is calculated based on `n_claases`. - * `reduce=False` is erased because it is enough with `reduction='none'`. + * Modified from https://github.com/fra31/auto-attack. + * `n_iters` is changed to `steps`. + * `n_target_classes` is calculated based on `n_claases`. + * `reduce=False` is erased because it is enough with `reduction='none'`. * `AutoAttack` - * Created based on `APGD`, `APGDT`, `Square`, `FAB`. + * Created based on `APGD`, `APGDT`, `Square`, `FAB`. ### v2.13.2 * `Attack.save` - * Don't use an additional memory if `save_path=None` + * Don't use an additional memory if `save_path=None` @@ -245,8 +255,8 @@ ### v2.14.1 * `Attack.set_training_mode` - * The method to support changing the model to training mode. - * Note that RNN requires model.training=True to calculate gradient. + * The method to support changing the model to training mode. + * Note that RNN requires model.training=True to calculate gradient. @@ -272,7 +282,7 @@ ### v2.14.4 * `Square` is fixed. - * If idx_to_fool is empty, then terminate an iteration. + * If idx_to_fool is empty, then terminate an iteration. @@ -281,9 +291,9 @@ ### v2.14.5 * `MIFGSM` is fixed. - * https://github.com/Harry24k/adversarial-attacks-pytorch/issues/33 + * https://github.com/Harry24k/adversarial-attacks-pytorch/issues/33 * `CW` is fixed. - * https://github.com/Harry24k/adversarial-attacks-pytorch/issues/32 + * https://github.com/Harry24k/adversarial-attacks-pytorch/issues/32 @@ -297,18 +307,18 @@ * Targeted mode is officially supported. - * `Attack` & `Attacks.*` + * `Attack` & `Attacks.*` - * `set_mode_default` - * `set_mode_targeted_by_function` - * `set_mode_targeted_least_likely` - * `set_mode_targeted_random` - * `_get_target_label` - * `_get_least_likely_label` - * `_get_random_target_label` + * `set_mode_default` + * `set_mode_targeted_by_function` + * `set_mode_targeted_least_likely` + * `set_mode_targeted_random` + * `_get_target_label` + * `_get_least_likely_label` + * `_get_random_target_label` - * `self._supported_mode` - * `self._targeted` + * `self._supported_mode` + * `self._targeted` * `UPGD` created. @@ -331,7 +341,7 @@ ### v3.1.0 * `TIFGSM` is added. - * https://github.com/Harry24k/adversarial-attacks-pytorch/pull/29/commits + * https://github.com/Harry24k/adversarial-attacks-pytorch/pull/29/commits @@ -341,18 +351,20 @@ ### v3.2.0 * `Jitter` is added. + * `Attack.*` + * `set_training_mode`: Now supports changing training mode of `Batchnorm` and `Dropout`. * `save`: Now supports return values of the last verbose information. * `MultiAttack` - * Fixed the verbose function. - * Now supports return values of the last verbose information + * Fixed the verbose function. + * Now supports return values of the last verbose information - + - + ### v3.2.1 @@ -367,15 +379,16 @@ ### v3.2.2 * `SparseFool`: [bug fixed](https://github.com/Harry24k/adversarial-attacks-pytorch/pull/43). + * `MultiAttack`: [bug fixed](https://github.com/Harry24k/adversarial-attacks-pytorch/issues/44). - +​ - +​ ### v3.2.3 @@ -384,7 +397,11 @@ +​ - +​ - + +### v3.2.4 + + * `save`, `MultiAttack`: `return_verbose` can be `True `even if `verbose=False`. \ No newline at end of file diff --git a/torchattacks/__init__.py b/torchattacks/__init__.py index f322641d..196648b2 100644 --- a/torchattacks/__init__.py +++ b/torchattacks/__init__.py @@ -24,4 +24,4 @@ from .attacks.tifgsm import TIFGSM from .attacks.jitter import Jitter -__version__ = '3.2.3' \ No newline at end of file +__version__ = '3.2.4' \ No newline at end of file diff --git a/torchattacks/attack.py b/torchattacks/attack.py index 922241e0..da824eee 100644 --- a/torchattacks/attack.py +++ b/torchattacks/attack.py @@ -157,10 +157,7 @@ def save(self, data_loader, save_path=None, verbose=True, return_verbose=False, return_verbose (bool): True for returning detailed information. (Default: False) save_pred (bool): True for saving predicted labels (Default: False) - """ - if (verbose==False) and (return_verbose==True): - raise ValueError("Verobse should be True if return_verbose==True.") - + """ if save_path is not None: image_list = [] label_list = [] @@ -183,7 +180,7 @@ def save(self, data_loader, save_path=None, verbose=True, return_verbose=False, batch_size = len(images) - if verbose: + if verbose or return_verbose: with torch.no_grad(): if given_training: self.model.eval() @@ -200,7 +197,8 @@ def save(self, data_loader, save_path=None, verbose=True, return_verbose=False, l2 = torch.cat(l2_distance).mean().item() progress = (step+1)/total_batch*100 elapsed_time = end-start - self._save_print(progress, rob_acc, l2, elapsed_time, end='\r') + if verbose: + self._save_print(progress, rob_acc, l2, elapsed_time, end='\r') if save_path is not None: if given_return_type == 'int': diff --git a/torchattacks/attacks/multiattack.py b/torchattacks/attacks/multiattack.py index ca775201..02b312b7 100644 --- a/torchattacks/attacks/multiattack.py +++ b/torchattacks/attacks/multiattack.py @@ -93,10 +93,7 @@ def _update_multi_atk_records(self, multi_atk_records): def save(self, data_loader, save_path=None, verbose=True, return_verbose=False, save_pred=False): r""" Overridden. - """ - if (verbose==False) and (return_verbose==True): - raise ValueError("Verobse should be True if return_verbose==True.") - + """ self._clear_multi_atk_records() prev_verbose = self.verbose self.verbose = False @@ -105,11 +102,15 @@ def save(self, data_loader, save_path=None, verbose=True, return_verbose=False, for i, attack in enumerate(self.attacks): self._multi_atk_records.append(0.0) - if verbose: + if return_verbose: rob_acc, l2, elapsed_time = super().save(data_loader, save_path, - verbose=True, return_verbose=True, + verbose, return_verbose, save_pred=save_pred) sr = self._covert_to_success_rates(self._multi_atk_records) + elif verbose: + super().save(data_loader, save_path, verbose, + return_verbose, save_pred=save_pred) + sr = self._covert_to_success_rates(self._multi_atk_records) else: super().save(data_loader, save_path, verbose=False, return_verbose=False, save_pred=save_pred)