adv-lib 0.2.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. adv_lib-0.2.2/LICENSE +29 -0
  2. adv_lib-0.2.2/PKG-INFO +170 -0
  3. adv_lib-0.2.2/README.md +118 -0
  4. adv_lib-0.2.2/adv_lib/__init__.py +1 -0
  5. adv_lib-0.2.2/adv_lib/attacks/__init__.py +13 -0
  6. adv_lib-0.2.2/adv_lib/attacks/augmented_lagrangian.py +243 -0
  7. adv_lib-0.2.2/adv_lib/attacks/auto_pgd.py +523 -0
  8. adv_lib-0.2.2/adv_lib/attacks/boundary_projection_tf.py +170 -0
  9. adv_lib-0.2.2/adv_lib/attacks/carlini_wagner/__init__.py +2 -0
  10. adv_lib-0.2.2/adv_lib/attacks/carlini_wagner/l2.py +151 -0
  11. adv_lib-0.2.2/adv_lib/attacks/carlini_wagner/linf.py +158 -0
  12. adv_lib-0.2.2/adv_lib/attacks/decoupled_direction_norm.py +113 -0
  13. adv_lib-0.2.2/adv_lib/attacks/fast_adaptive_boundary/__init__.py +1 -0
  14. adv_lib-0.2.2/adv_lib/attacks/fast_adaptive_boundary/fast_adaptive_boundary.py +215 -0
  15. adv_lib-0.2.2/adv_lib/attacks/fast_adaptive_boundary/projections.py +164 -0
  16. adv_lib-0.2.2/adv_lib/attacks/fast_minimum_norm.py +218 -0
  17. adv_lib-0.2.2/adv_lib/attacks/perceptual_color_attacks/__init__.py +1 -0
  18. adv_lib-0.2.2/adv_lib/attacks/perceptual_color_attacks/differential_color_functions.py +181 -0
  19. adv_lib-0.2.2/adv_lib/attacks/perceptual_color_attacks/perceptual_color_distance_al.py +128 -0
  20. adv_lib-0.2.2/adv_lib/attacks/primal_dual_gradient_descent.py +379 -0
  21. adv_lib-0.2.2/adv_lib/attacks/projected_gradient_descent.py +109 -0
  22. adv_lib-0.2.2/adv_lib/attacks/segmentation/__init__.py +4 -0
  23. adv_lib-0.2.2/adv_lib/attacks/segmentation/alma_prox.py +283 -0
  24. adv_lib-0.2.2/adv_lib/attacks/segmentation/asma.py +92 -0
  25. adv_lib-0.2.2/adv_lib/attacks/segmentation/dense_adversary.py +83 -0
  26. adv_lib-0.2.2/adv_lib/attacks/segmentation/primal_dual_gradient_descent.py +349 -0
  27. adv_lib-0.2.2/adv_lib/attacks/self_adaptive_norm_update.py +127 -0
  28. adv_lib-0.2.2/adv_lib/attacks/sigma_zero.py +119 -0
  29. adv_lib-0.2.2/adv_lib/attacks/stochastic_sparse_attacks.py +237 -0
  30. adv_lib-0.2.2/adv_lib/attacks/structured_adversarial_attack.py +289 -0
  31. adv_lib-0.2.2/adv_lib/attacks/trust_region.py +153 -0
  32. adv_lib-0.2.2/adv_lib/distances/__init__.py +0 -0
  33. adv_lib-0.2.2/adv_lib/distances/color_difference.py +212 -0
  34. adv_lib-0.2.2/adv_lib/distances/lp_norms.py +18 -0
  35. adv_lib-0.2.2/adv_lib/distances/lpips.py +99 -0
  36. adv_lib-0.2.2/adv_lib/distances/structural_similarity.py +147 -0
  37. adv_lib-0.2.2/adv_lib/utils/__init__.py +1 -0
  38. adv_lib-0.2.2/adv_lib/utils/attack_utils.py +226 -0
  39. adv_lib-0.2.2/adv_lib/utils/color_conversions.py +71 -0
  40. adv_lib-0.2.2/adv_lib/utils/image_selection.py +27 -0
  41. adv_lib-0.2.2/adv_lib/utils/lagrangian_penalties/__init__.py +1 -0
  42. adv_lib-0.2.2/adv_lib/utils/lagrangian_penalties/all_penalties.py +67 -0
  43. adv_lib-0.2.2/adv_lib/utils/lagrangian_penalties/penalty_functions.py +79 -0
  44. adv_lib-0.2.2/adv_lib/utils/lagrangian_penalties/scripts/plot_penalties.py +42 -0
  45. adv_lib-0.2.2/adv_lib/utils/lagrangian_penalties/scripts/plot_univariates.py +32 -0
  46. adv_lib-0.2.2/adv_lib/utils/lagrangian_penalties/univariate_functions.py +299 -0
  47. adv_lib-0.2.2/adv_lib/utils/losses.py +29 -0
  48. adv_lib-0.2.2/adv_lib/utils/projections.py +100 -0
  49. adv_lib-0.2.2/adv_lib/utils/utils.py +58 -0
  50. adv_lib-0.2.2/adv_lib/utils/visdom_logger.py +109 -0
  51. adv_lib-0.2.2/adv_lib.egg-info/PKG-INFO +170 -0
  52. adv_lib-0.2.2/adv_lib.egg-info/SOURCES.txt +55 -0
  53. adv_lib-0.2.2/adv_lib.egg-info/dependency_links.txt +1 -0
  54. adv_lib-0.2.2/adv_lib.egg-info/requires.txt +8 -0
  55. adv_lib-0.2.2/adv_lib.egg-info/top_level.txt +1 -0
  56. adv_lib-0.2.2/pyproject.toml +39 -0
  57. adv_lib-0.2.2/setup.cfg +4 -0
adv_lib-0.2.2/LICENSE ADDED
@@ -0,0 +1,29 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2020, Jérôme Rony
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions are met:
8
+
9
+ 1. Redistributions of source code must retain the above copyright notice, this
10
+ list of conditions and the following disclaimer.
11
+
12
+ 2. Redistributions in binary form must reproduce the above copyright notice,
13
+ this list of conditions and the following disclaimer in the documentation
14
+ and/or other materials provided with the distribution.
15
+
16
+ 3. Neither the name of the copyright holder nor the names of its
17
+ contributors may be used to endorse or promote products derived from
18
+ this software without specific prior written permission.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
adv_lib-0.2.2/PKG-INFO ADDED
@@ -0,0 +1,170 @@
1
+ Metadata-Version: 2.1
2
+ Name: adv-lib
3
+ Version: 0.2.2
4
+ Summary: Library of various adversarial attacks resources in PyTorch
5
+ Author-email: Jerome Rony <jerome.rony@gmail.com>
6
+ License: BSD 3-Clause License
7
+
8
+ Copyright (c) 2020, Jérôme Rony
9
+ All rights reserved.
10
+
11
+ Redistribution and use in source and binary forms, with or without
12
+ modification, are permitted provided that the following conditions are met:
13
+
14
+ 1. Redistributions of source code must retain the above copyright notice, this
15
+ list of conditions and the following disclaimer.
16
+
17
+ 2. Redistributions in binary form must reproduce the above copyright notice,
18
+ this list of conditions and the following disclaimer in the documentation
19
+ and/or other materials provided with the distribution.
20
+
21
+ 3. Neither the name of the copyright holder nor the names of its
22
+ contributors may be used to endorse or promote products derived from
23
+ this software without specific prior written permission.
24
+
25
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
28
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
29
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
31
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
33
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35
+
36
+ Project-URL: Repository, https://github.com/jeromerony/adversarial-library.git
37
+ Classifier: Programming Language :: Python :: 3
38
+ Classifier: Development Status :: 3 - Alpha
39
+ Classifier: Intended Audience :: Developers
40
+ Classifier: Intended Audience :: Science/Research
41
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
42
+ Requires-Python: >=3.8
43
+ Description-Content-Type: text/markdown
44
+ License-File: LICENSE
45
+ Requires-Dist: torch>=1.8.0
46
+ Requires-Dist: torchvision>=0.9.0
47
+ Requires-Dist: tqdm>=4.48.0
48
+ Requires-Dist: visdom>=0.1.8
49
+ Provides-Extra: test
50
+ Requires-Dist: scikit-image; extra == "test"
51
+ Requires-Dist: pytest; extra == "test"
52
+
53
+
54
+ [![DOI](https://zenodo.org/badge/315504148.svg)](https://zenodo.org/badge/latestdoi/315504148)
55
+
56
+ # Adversarial Library
57
+
58
+ This library contains various resources related to adversarial attacks implemented in PyTorch. It is aimed towards researchers looking for implementations of state-of-the-art attacks.
59
+
60
+ The code was written to maximize efficiency (_e.g._ by preferring low level functions from PyTorch) while retaining simplicity (_e.g._ by avoiding abstractions). As a consequence, most of the library, and especially the attacks, is implemented using **pure functions** (whenever possible).
61
+
62
+ While focused on attacks, this library also provides several utilities related to adversarial attacks: distances (SSIM, CIEDE2000, LPIPS), visdom callback, projections, losses and helper functions. Most notably the function `run_attack` from `utils/attack_utils.py` performs an attack on a model given the inputs and labels, with fixed batch size, and reports complexity related metrics (run-time and forward/backward propagations).
63
+
64
+ ### Dependencies
65
+
66
+ The goal of this library is to be up-to-date with newer versions of PyTorch so the dependencies are expected to be updated regularly (possibly resulting in breaking changes).
67
+
68
+ - pytorch>=1.8.0
69
+ - torchvision>=0.9.0
70
+ - tqdm>=4.48.0
71
+ - visdom>=0.1.8
72
+
73
+ ### Installation
74
+
75
+ You can either install using:
76
+
77
+ ```pip install git+https://github.com/jeromerony/adversarial-library```
78
+
79
+ Or you can clone the repo and run:
80
+
81
+ ```python setup.py install```
82
+
83
+ Alternatively, you can install (after cloning) the library in editable mode:
84
+
85
+ ```pip install -e .```
86
+
87
+ ### Usage
88
+ Attacks are implemented as functions, so they can be called directly by providing the model, samples and labels (possibly with optional arguments):
89
+ ```python
90
+ from adv_lib.attacks import ddn
91
+ adv_samples = ddn(model=model, inputs=inputs, labels=labels, steps=300)
92
+ ```
93
+
94
+ Classification attacks all expect the following arguments:
95
+ - `model`: the model that produces logits (pre-softmax activations) with inputs in $[0, 1]$
96
+ - `inputs`: the samples to attack in $[0, 1]$
97
+ - `labels`: either the ground-truth labels for the samples or the targets
98
+ - `targeted`: flag indicated if the attack should be targeted or not -- defaults to `False`
99
+
100
+ Additionally, many attacks have an optional `callback` argument which accepts an `adv_lib.utils.visdom_logger.VisdomLogger` to plot data to a visdom server for monitoring purposes.
101
+
102
+ For a more detailed example on how to use this library, you can look at this repo: https://github.com/jeromerony/augmented_lagrangian_adversarial_attacks
103
+
104
+ ## Contents
105
+
106
+ ### Attacks
107
+
108
+ #### Classification
109
+
110
+ Currently the following classification attacks are implemented in the `adv_lib.attacks` module:
111
+
112
+ | Name | Knowledge | Type | Distance(s) | ArXiv Link |
113
+ |-----------------------------------------------------------------------------------------|-----------|---------|-----------------------------------------------------------|------------------------------------------------------------------------------------------------------|
114
+ | Carlini and Wagner (C&W) | White-box | Minimal | $\ell_2$, $\ell_\infty$ | [1608.04644](https://arxiv.org/abs/1608.04644) |
115
+ | Projected Gradient Descent (PGD) | White-box | Budget | $\ell_\infty$ | [1706.06083](https://arxiv.org/abs/1706.06083) |
116
+ | Structured Adversarial Attack (StrAttack) | White-box | Minimal | $\ell_2$ + group-sparsity | [1808.01664](https://arxiv.org/abs/1808.01664) |
117
+ | **Decoupled Direction and Norm (DDN)** | White-box | Minimal | $\ell_2$ | [1811.09600](https://arxiv.org/abs/1811.09600) |
118
+ | Trust Region (TR) | White-box | Minimal | $\ell_2$, $\ell_\infty$ | [1812.06371](https://arxiv.org/abs/1812.06371) |
119
+ | Fast Adaptive Boundary (FAB) | White-box | Minimal | $\ell_1$, $\ell_2$, $\ell_\infty$ | [1907.02044](https://arxiv.org/abs/1907.02044) |
120
+ | Perceptual Color distance Alternating Loss (PerC-AL) | White-box | Minimal | CIEDE2000 | [1911.02466](https://arxiv.org/abs/1911.02466) |
121
+ | Auto-PGD (APGD) | White-box | Budget | $\ell_1$, $\ell_2$, $\ell_\infty$ | [2003.01690](https://arxiv.org/abs/2003.01690) <br /> [2103.01208](https://arxiv.org/abs/2103.01208) |
122
+ | **Augmented Lagrangian Method for Adversarial (ALMA)** | White-box | Minimal | $\ell_1$, $\ell_2$, SSIM, CIEDE2000, LPIPS, ... | [2011.11857](https://arxiv.org/abs/2011.11857) |
123
+ | Folded Gaussian Attack (FGA)<br /> Voting Folded Gaussian Attack (VFGA) | White-box | Minimal | $\ell_0$ | [2011.12423](https://arxiv.org/abs/2011.12423) |
124
+ | Fast Minimum-Norm (FMN) | White-box | Minimal | $\ell_0$, $\ell_1$, $\ell_2$, $\ell_\infty$ | [2102.12827](https://arxiv.org/abs/2102.12827) |
125
+ | Primal-Dual Gradient Descent (PDGD)<br /> Primal-Dual Proximal Gradient Descent (PDPGD) | White-box | Minimal | $\ell_2$<br />$\ell_0$, $\ell_1$, $\ell_2$, $\ell_\infty$ | [2106.01538](https://arxiv.org/abs/2106.01538) |
126
+ | σ-zero | White-box | Minimal | $\ell_0$ | [2402.01879](https://arxiv.org/abs/2402.01879) |
127
+
128
+ **Bold** means that this repository contains the official implementation.
129
+
130
+ _Type_ refers to the goal of the attack:
131
+ - _Minimal_ attacks aim to find the smallest adversarial perturbation w.r.t. a given distance;
132
+ - _Budget_ attacks aim to find an adversarial perturbation within a distance budget (and often to maximize a loss as well).
133
+
134
+ #### Segmentation
135
+
136
+ The library now includes segmentation attacks in the `adv_lib.attacks.segmentation` module. These require the following arguments:
137
+ - `model`: the model that produces logits (pre-softmax activations) with inputs in $[0, 1]$
138
+ - `inputs`: the images to attack in $[0, 1]$. Shape: $b\times c\times h\times w$ with $b$ the batch size, $c$ the number of color channels and $h$ and $w$ the height and width of the images.
139
+ - `labels`: either the ground-truth labels for the samples or the targets. Shape: $b\times h\times w$.
140
+ - `masks`: binary mask indicating which pixels to attack, to account for unlabeled pixels (e.g. void in Pascal VOC). Shape: $b\times h\times w$
141
+ - `targeted`: flag indicated if the attack should be targeted or not -- defaults to `False`
142
+ - `adv_threshold`: fraction of the pixels to consider an attack successful -- defaults to `0.99`
143
+
144
+ The following segmentation attacks are implemented:
145
+
146
+ | Name | Knowledge | Type | Distance(s) | ArXiv Link |
147
+ |-------------------------------------------------------------------------------------------|-----------|---------|-----------------------------------------------------------|------------------------------------------------|
148
+ | Dense Adversary Generation (DAG) | White-box | Minimal | $\ell_2$, $\ell_\infty$ | [1703.08603](https://arxiv.org/abs/1703.08603) |
149
+ | Adaptive Segmentation Mask Attack (ASMA) | White-box | Minimal | $\ell_2$ | [1907.13124](https://arxiv.org/abs/1907.13124) |
150
+ | _Primal-Dual Gradient Descent (PDGD)<br /> Primal-Dual Proximal Gradient Descent (PDPGD)_ | White-box | Minimal | $\ell_2$<br />$\ell_0$, $\ell_1$, $\ell_2$, $\ell_\infty$ | [2106.01538](https://arxiv.org/abs/2106.01538) |
151
+ | **ALMA prox** | White-box | Minimal | $\ell_\infty$ | [2206.07179](https://arxiv.org/abs/2206.07179) |
152
+
153
+ _Italic_ indicates that the attack is unofficially adapted from the classification variant.
154
+
155
+ ### Distances
156
+
157
+ The following distances are available in the utils `adv_lib.distances` module:
158
+ - Lp-norms
159
+ - SSIM https://ece.uwaterloo.ca/~z70wang/research/ssim/
160
+ - MS-SSIM https://ece.uwaterloo.ca/~z70wang/publications/msssim.html
161
+ - CIEDE2000 color difference http://www2.ece.rochester.edu/~gsharma/ciede2000/ciede2000noteCRNA.pdf
162
+ - LPIPS https://arxiv.org/abs/1801.03924
163
+
164
+ ## Contributions
165
+
166
+ Suggestions and contributions are welcome :)
167
+
168
+ ## Citation
169
+
170
+ If this library has been useful for your research, you can cite it using the "Cite this repository" button in the "About" section.
@@ -0,0 +1,118 @@
1
+
2
+ [![DOI](https://zenodo.org/badge/315504148.svg)](https://zenodo.org/badge/latestdoi/315504148)
3
+
4
+ # Adversarial Library
5
+
6
+ This library contains various resources related to adversarial attacks implemented in PyTorch. It is aimed towards researchers looking for implementations of state-of-the-art attacks.
7
+
8
+ The code was written to maximize efficiency (_e.g._ by preferring low level functions from PyTorch) while retaining simplicity (_e.g._ by avoiding abstractions). As a consequence, most of the library, and especially the attacks, is implemented using **pure functions** (whenever possible).
9
+
10
+ While focused on attacks, this library also provides several utilities related to adversarial attacks: distances (SSIM, CIEDE2000, LPIPS), visdom callback, projections, losses and helper functions. Most notably the function `run_attack` from `utils/attack_utils.py` performs an attack on a model given the inputs and labels, with fixed batch size, and reports complexity related metrics (run-time and forward/backward propagations).
11
+
12
+ ### Dependencies
13
+
14
+ The goal of this library is to be up-to-date with newer versions of PyTorch so the dependencies are expected to be updated regularly (possibly resulting in breaking changes).
15
+
16
+ - pytorch>=1.8.0
17
+ - torchvision>=0.9.0
18
+ - tqdm>=4.48.0
19
+ - visdom>=0.1.8
20
+
21
+ ### Installation
22
+
23
+ You can either install using:
24
+
25
+ ```pip install git+https://github.com/jeromerony/adversarial-library```
26
+
27
+ Or you can clone the repo and run:
28
+
29
+ ```python setup.py install```
30
+
31
+ Alternatively, you can install (after cloning) the library in editable mode:
32
+
33
+ ```pip install -e .```
34
+
35
+ ### Usage
36
+ Attacks are implemented as functions, so they can be called directly by providing the model, samples and labels (possibly with optional arguments):
37
+ ```python
38
+ from adv_lib.attacks import ddn
39
+ adv_samples = ddn(model=model, inputs=inputs, labels=labels, steps=300)
40
+ ```
41
+
42
+ Classification attacks all expect the following arguments:
43
+ - `model`: the model that produces logits (pre-softmax activations) with inputs in $[0, 1]$
44
+ - `inputs`: the samples to attack in $[0, 1]$
45
+ - `labels`: either the ground-truth labels for the samples or the targets
46
+ - `targeted`: flag indicated if the attack should be targeted or not -- defaults to `False`
47
+
48
+ Additionally, many attacks have an optional `callback` argument which accepts an `adv_lib.utils.visdom_logger.VisdomLogger` to plot data to a visdom server for monitoring purposes.
49
+
50
+ For a more detailed example on how to use this library, you can look at this repo: https://github.com/jeromerony/augmented_lagrangian_adversarial_attacks
51
+
52
+ ## Contents
53
+
54
+ ### Attacks
55
+
56
+ #### Classification
57
+
58
+ Currently the following classification attacks are implemented in the `adv_lib.attacks` module:
59
+
60
+ | Name | Knowledge | Type | Distance(s) | ArXiv Link |
61
+ |-----------------------------------------------------------------------------------------|-----------|---------|-----------------------------------------------------------|------------------------------------------------------------------------------------------------------|
62
+ | Carlini and Wagner (C&W) | White-box | Minimal | $\ell_2$, $\ell_\infty$ | [1608.04644](https://arxiv.org/abs/1608.04644) |
63
+ | Projected Gradient Descent (PGD) | White-box | Budget | $\ell_\infty$ | [1706.06083](https://arxiv.org/abs/1706.06083) |
64
+ | Structured Adversarial Attack (StrAttack) | White-box | Minimal | $\ell_2$ + group-sparsity | [1808.01664](https://arxiv.org/abs/1808.01664) |
65
+ | **Decoupled Direction and Norm (DDN)** | White-box | Minimal | $\ell_2$ | [1811.09600](https://arxiv.org/abs/1811.09600) |
66
+ | Trust Region (TR) | White-box | Minimal | $\ell_2$, $\ell_\infty$ | [1812.06371](https://arxiv.org/abs/1812.06371) |
67
+ | Fast Adaptive Boundary (FAB) | White-box | Minimal | $\ell_1$, $\ell_2$, $\ell_\infty$ | [1907.02044](https://arxiv.org/abs/1907.02044) |
68
+ | Perceptual Color distance Alternating Loss (PerC-AL) | White-box | Minimal | CIEDE2000 | [1911.02466](https://arxiv.org/abs/1911.02466) |
69
+ | Auto-PGD (APGD) | White-box | Budget | $\ell_1$, $\ell_2$, $\ell_\infty$ | [2003.01690](https://arxiv.org/abs/2003.01690) <br /> [2103.01208](https://arxiv.org/abs/2103.01208) |
70
+ | **Augmented Lagrangian Method for Adversarial (ALMA)** | White-box | Minimal | $\ell_1$, $\ell_2$, SSIM, CIEDE2000, LPIPS, ... | [2011.11857](https://arxiv.org/abs/2011.11857) |
71
+ | Folded Gaussian Attack (FGA)<br /> Voting Folded Gaussian Attack (VFGA) | White-box | Minimal | $\ell_0$ | [2011.12423](https://arxiv.org/abs/2011.12423) |
72
+ | Fast Minimum-Norm (FMN) | White-box | Minimal | $\ell_0$, $\ell_1$, $\ell_2$, $\ell_\infty$ | [2102.12827](https://arxiv.org/abs/2102.12827) |
73
+ | Primal-Dual Gradient Descent (PDGD)<br /> Primal-Dual Proximal Gradient Descent (PDPGD) | White-box | Minimal | $\ell_2$<br />$\ell_0$, $\ell_1$, $\ell_2$, $\ell_\infty$ | [2106.01538](https://arxiv.org/abs/2106.01538) |
74
+ | σ-zero | White-box | Minimal | $\ell_0$ | [2402.01879](https://arxiv.org/abs/2402.01879) |
75
+
76
+ **Bold** means that this repository contains the official implementation.
77
+
78
+ _Type_ refers to the goal of the attack:
79
+ - _Minimal_ attacks aim to find the smallest adversarial perturbation w.r.t. a given distance;
80
+ - _Budget_ attacks aim to find an adversarial perturbation within a distance budget (and often to maximize a loss as well).
81
+
82
+ #### Segmentation
83
+
84
+ The library now includes segmentation attacks in the `adv_lib.attacks.segmentation` module. These require the following arguments:
85
+ - `model`: the model that produces logits (pre-softmax activations) with inputs in $[0, 1]$
86
+ - `inputs`: the images to attack in $[0, 1]$. Shape: $b\times c\times h\times w$ with $b$ the batch size, $c$ the number of color channels and $h$ and $w$ the height and width of the images.
87
+ - `labels`: either the ground-truth labels for the samples or the targets. Shape: $b\times h\times w$.
88
+ - `masks`: binary mask indicating which pixels to attack, to account for unlabeled pixels (e.g. void in Pascal VOC). Shape: $b\times h\times w$
89
+ - `targeted`: flag indicated if the attack should be targeted or not -- defaults to `False`
90
+ - `adv_threshold`: fraction of the pixels to consider an attack successful -- defaults to `0.99`
91
+
92
+ The following segmentation attacks are implemented:
93
+
94
+ | Name | Knowledge | Type | Distance(s) | ArXiv Link |
95
+ |-------------------------------------------------------------------------------------------|-----------|---------|-----------------------------------------------------------|------------------------------------------------|
96
+ | Dense Adversary Generation (DAG) | White-box | Minimal | $\ell_2$, $\ell_\infty$ | [1703.08603](https://arxiv.org/abs/1703.08603) |
97
+ | Adaptive Segmentation Mask Attack (ASMA) | White-box | Minimal | $\ell_2$ | [1907.13124](https://arxiv.org/abs/1907.13124) |
98
+ | _Primal-Dual Gradient Descent (PDGD)<br /> Primal-Dual Proximal Gradient Descent (PDPGD)_ | White-box | Minimal | $\ell_2$<br />$\ell_0$, $\ell_1$, $\ell_2$, $\ell_\infty$ | [2106.01538](https://arxiv.org/abs/2106.01538) |
99
+ | **ALMA prox** | White-box | Minimal | $\ell_\infty$ | [2206.07179](https://arxiv.org/abs/2206.07179) |
100
+
101
+ _Italic_ indicates that the attack is unofficially adapted from the classification variant.
102
+
103
+ ### Distances
104
+
105
+ The following distances are available in the utils `adv_lib.distances` module:
106
+ - Lp-norms
107
+ - SSIM https://ece.uwaterloo.ca/~z70wang/research/ssim/
108
+ - MS-SSIM https://ece.uwaterloo.ca/~z70wang/publications/msssim.html
109
+ - CIEDE2000 color difference http://www2.ece.rochester.edu/~gsharma/ciede2000/ciede2000noteCRNA.pdf
110
+ - LPIPS https://arxiv.org/abs/1801.03924
111
+
112
+ ## Contributions
113
+
114
+ Suggestions and contributions are welcome :)
115
+
116
+ ## Citation
117
+
118
+ If this library has been useful for your research, you can cite it using the "Cite this repository" button in the "About" section.
@@ -0,0 +1 @@
1
+ __version__ = "0.2.2"
@@ -0,0 +1,13 @@
1
+ from .augmented_lagrangian import alma
2
+ from .auto_pgd import apgd, apgd_targeted
3
+ from .carlini_wagner import carlini_wagner_l2, carlini_wagner_linf
4
+ from .decoupled_direction_norm import ddn
5
+ from .fast_adaptive_boundary import fab
6
+ from .fast_minimum_norm import fmn
7
+ from .perceptual_color_attacks import perc_al
8
+ from .primal_dual_gradient_descent import pdgd, pdpgd
9
+ from .projected_gradient_descent import pgd_linf
10
+ from .sigma_zero import sigma_zero
11
+ from .stochastic_sparse_attacks import fga, vfga
12
+ from .structured_adversarial_attack import str_attack
13
+ from .trust_region import tr
@@ -0,0 +1,243 @@
1
+ from functools import partial
2
+ from typing import Callable, Optional
3
+
4
+ import torch
5
+ from torch import Tensor, nn
6
+ from torch.autograd import grad
7
+
8
+ from adv_lib.distances.color_difference import ciede2000_loss
9
+ from adv_lib.distances.lp_norms import l1_distances, l2_distances
10
+ from adv_lib.distances.lpips import LPIPS
11
+ from adv_lib.distances.structural_similarity import ms_ssim_loss, ssim_loss
12
+ from adv_lib.utils.lagrangian_penalties import all_penalties
13
+ from adv_lib.utils.losses import difference_of_logits_ratio
14
+ from adv_lib.utils.visdom_logger import VisdomLogger
15
+
16
+
17
+ def init_lr_finder(inputs: Tensor, grad: Tensor, distance_function: Callable, target_distance: float) -> Tensor:
18
+ """
19
+ Performs a line search and a binary search to find the learning rate η for each sample such that:
20
+ distance_function(inputs - η * grad) = target_distance.
21
+
22
+ Parameters
23
+ ----------
24
+ inputs : Tensor
25
+ Reference to compute the distance from.
26
+ grad : Tensor
27
+ Direction to step in.
28
+ distance_function : Callable
29
+ target_distance : float
30
+ Target distance that inputs - η * grad should reach.
31
+
32
+ Returns
33
+ -------
34
+ η : Tensor
35
+ Learning rate for each sample.
36
+
37
+ """
38
+ batch_size = len(inputs)
39
+ batch_view = lambda tensor: tensor.view(batch_size, *[1] * (inputs.ndim - 1))
40
+ lr = torch.ones(batch_size, device=inputs.device)
41
+ lower = torch.zeros_like(lr)
42
+
43
+ found_upper = distance_function((inputs - grad).clamp_(min=0, max=1)) > target_distance
44
+ while (~found_upper).any():
45
+ lower = torch.where(found_upper, lower, lr)
46
+ lr = torch.where(found_upper, lr, lr * 2)
47
+ found_upper = distance_function((inputs - batch_view(lr) * grad).clamp_(min=0, max=1)) > target_distance
48
+
49
+ for i in range(20):
50
+ new_lr = (lower + lr) / 2
51
+ larger = distance_function((inputs - batch_view(new_lr) * grad).clamp_(min=0, max=1)) > target_distance
52
+ lower, lr = torch.where(larger, lower, new_lr), torch.where(larger, new_lr, lr)
53
+
54
+ return (lr + lower) / 2
55
+
56
+
57
+ _distances = {
58
+ 'ssim': ssim_loss,
59
+ 'msssim': ms_ssim_loss,
60
+ 'ciede2000': partial(ciede2000_loss, ε=1e-12),
61
+ 'lpips': LPIPS,
62
+ 'l2': l2_distances,
63
+ 'l1': l1_distances,
64
+ }
65
+
66
+
67
+ def alma(model: nn.Module,
68
+ inputs: Tensor,
69
+ labels: Tensor,
70
+ penalty: Callable = all_penalties['P2'],
71
+ targeted: bool = False,
72
+ num_steps: int = 1000,
73
+ lr_init: float = 0.1,
74
+ lr_reduction: float = 0.01,
75
+ distance: str = 'l2',
76
+ init_lr_distance: Optional[float] = None,
77
+ μ_init: float = 1,
78
+ ρ_init: float = 1,
79
+ check_steps: int = 10,
80
+ τ: float = 0.95,
81
+ γ: float = 1.2,
82
+ α: float = 0.9,
83
+ α_rms: Optional[float] = None,
84
+ momentum: Optional[float] = None,
85
+ logit_tolerance: float = 1e-4,
86
+ levels: Optional[int] = None,
87
+ callback: Optional[VisdomLogger] = None) -> Tensor:
88
+ """
89
+ Augmented Lagrangian Method for Adversarial (ALMA) attack from https://arxiv.org/abs/2011.11857.
90
+
91
+ Parameters
92
+ ----------
93
+ model : nn.Module
94
+ Model to attack.
95
+ inputs : Tensor
96
+ Inputs to attack. Should be in [0, 1].
97
+ labels : Tensor
98
+ Labels corresponding to the inputs if untargeted, else target labels.
99
+ penalty : Callable
100
+ Penalty-Lagrangian function to use. A good default choice is P2 (see the original article).
101
+ targeted : bool
102
+ Whether to perform a targeted attack or not.
103
+ num_steps : int
104
+ Number of optimization steps. Corresponds to the number of forward and backward propagations.
105
+ lr_init : float
106
+ Initial learning rate.
107
+ lr_reduction : float
108
+ Reduction factor for the learning rate. The final learning rate is lr_init * lr_reduction
109
+ distance : str
110
+ Distance to use.
111
+ init_lr_distance : float
112
+ If a float is given, the initial learning rate will be calculated such that the first step results in an
113
+ increase of init_lr_distance of the distance to minimize. This corresponds to ε in the original article.
114
+ μ_init : float
115
+ Initial value of the penalty multiplier.
116
+ ρ_init : float
117
+ Initial value of the penalty parameter.
118
+ check_steps : int
119
+ Number of steps between checks for the improvement of the constraint. This corresponds to M in the original
120
+ article.
121
+ τ : float
122
+ Constraint improvement rate.
123
+ γ : float
124
+ Penalty parameter increase rate.
125
+ α : float
126
+ Weight for the exponential moving average.
127
+ α_rms : float
128
+ Smoothing constant for RMSProp. If none is provided, defaults to α.
129
+ momentum : float
130
+ Momentum for the RMSProp. If none is provided, defaults to α.
131
+ logit_tolerance : float
132
+ Small quantity added to the difference of logits to avoid solutions where the difference of logits is 0, which
133
+ can results in inconsistent class prediction (using argmax) on GPU. This can also be used as a confidence
134
+ parameter κ as in https://arxiv.org/abs/1608.04644, however, a confidence parameter on logits is not robust to
135
+ scaling of the logits.
136
+ levels : int
137
+ Number of levels for quantization. The attack will perform quantization only if the number of levels is
138
+ provided.
139
+ callback : VisdomLogger
140
+ Callback to visualize the progress of the algorithm.
141
+
142
+ Returns
143
+ -------
144
+ best_adv : Tensor
145
+ Perturbed inputs (inputs + perturbation) that are adversarial and have smallest distance with the original
146
+ inputs.
147
+
148
+ """
149
+ device = inputs.device
150
+ batch_size = len(inputs)
151
+ batch_view = lambda tensor: tensor.view(batch_size, *[1] * (inputs.ndim - 1))
152
+ multiplier = -1 if targeted else 1
153
+
154
+ # Setup variables
155
+ δ = torch.zeros_like(inputs, requires_grad=True)
156
+ square_avg = torch.ones_like(inputs)
157
+ momentum_buffer = torch.zeros_like(inputs)
158
+ lr = torch.full((batch_size,), lr_init, device=device, dtype=torch.float)
159
+ α_rms, momentum = α if α_rms is None else α_rms, α if momentum is None else momentum
160
+
161
+ # Init rho and mu
162
+ μ = torch.full((batch_size,), μ_init, device=device, dtype=torch.float)
163
+ ρ = torch.full((batch_size,), ρ_init, device=device, dtype=torch.float)
164
+
165
+ # Init similarity metric
166
+ if distance in ['lpips']:
167
+ dist_func = _distances[distance](target=inputs)
168
+ else:
169
+ dist_func = partial(_distances[distance], inputs)
170
+
171
+ # Init trackers
172
+ best_dist = torch.full((batch_size,), float('inf'), device=device)
173
+ best_adv = inputs.clone()
174
+ adv_found = torch.zeros_like(best_dist, dtype=torch.bool)
175
+ step_found = torch.full_like(best_dist, num_steps + 1)
176
+
177
+ for i in range(num_steps):
178
+
179
+ adv_inputs = inputs + δ
180
+ logits = model(adv_inputs)
181
+ dist = dist_func(adv_inputs)
182
+
183
+ if i == 0:
184
+ labels_infhot = torch.zeros_like(logits).scatter_(1, labels.unsqueeze(1), float('inf'))
185
+ dlr_func = partial(difference_of_logits_ratio, labels=labels, labels_infhot=labels_infhot,
186
+ targeted=targeted, ε=logit_tolerance)
187
+
188
+ dlr = multiplier * dlr_func(logits)
189
+
190
+ if i == 0:
191
+ prev_dlr = dlr.detach()
192
+ elif (i + 1) % check_steps == 0:
193
+ improved_dlr = (dlr.detach() < τ * prev_dlr)
194
+ ρ = torch.where(~(adv_found | improved_dlr), γ * ρ, ρ)
195
+ prev_dlr = dlr.detach()
196
+
197
+ if i:
198
+ new_μ = grad(penalty(dlr, ρ, μ).sum(), dlr, only_inputs=True)[0]
199
+ μ.lerp_(new_μ, weight=1 - α).clamp_(min=1e-6, max=1e12)
200
+
201
+ is_adv = dlr < 0
202
+ is_smaller = dist < best_dist
203
+ is_both = is_adv & is_smaller
204
+ step_found.masked_fill_((~adv_found) & is_adv, i)
205
+ adv_found.logical_or_(is_adv)
206
+ best_dist = torch.where(is_both, dist.detach(), best_dist)
207
+ best_adv = torch.where(batch_view(is_both), adv_inputs.detach(), best_adv)
208
+
209
+ if i == 0:
210
+ loss = penalty(dlr, ρ, μ)
211
+ else:
212
+ loss = dist + penalty(dlr, ρ, μ)
213
+ δ_grad = grad(loss.sum(), δ, only_inputs=True)[0]
214
+
215
+ grad_norm = δ_grad.flatten(1).norm(p=2, dim=1)
216
+ if init_lr_distance is not None and i == 0:
217
+ randn_grad = torch.randn_like(δ_grad).renorm(dim=0, p=2, maxnorm=1)
218
+ δ_grad = torch.where(batch_view(grad_norm <= 1e-6), randn_grad, δ_grad)
219
+ lr = init_lr_finder(inputs, δ_grad, dist_func, target_distance=init_lr_distance)
220
+
221
+ exp_decay = lr_reduction ** ((i - step_found).clamp_(min=0) / (num_steps - step_found))
222
+ step_lr = lr * exp_decay
223
+ square_avg.mul_(α_rms).addcmul_(δ_grad, δ_grad, value=1 - α_rms)
224
+ momentum_buffer.mul_(momentum).addcdiv_(δ_grad, square_avg.sqrt().add_(1e-8))
225
+ δ.data.addcmul_(momentum_buffer, batch_view(step_lr), value=-1)
226
+
227
+ δ.data.add_(inputs).clamp_(min=0, max=1)
228
+ if levels is not None:
229
+ δ.data.mul_(levels - 1).round_().div_(levels - 1)
230
+ δ.data.sub_(inputs)
231
+
232
+ if callback:
233
+ cb_best_dist = best_dist.masked_select(adv_found).mean()
234
+ callback.accumulate_line([distance, 'dlr'], i, [dist.mean(), dlr.mean()])
235
+ callback.accumulate_line(['μ_c', 'ρ_c'], i, [μ.mean(), ρ.mean()])
236
+ callback.accumulate_line('grad_norm', i, grad_norm.mean())
237
+ callback.accumulate_line(['best_{}'.format(distance), 'success', 'lr'], i,
238
+ [cb_best_dist, adv_found.float().mean(), step_lr.mean()])
239
+
240
+ if (i + 1) % (num_steps // 20) == 0 or (i + 1) == num_steps:
241
+ callback.update_lines()
242
+
243
+ return best_adv