Skip to content

Commit 7c26580

Browse files
authored
Merge pull request #772 from Trusted-AI/development_maintenance_150
General maintenance updates
2 parents 1792db8 + 2600481 commit 7c26580

File tree

114 files changed

+871
-556
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

114 files changed

+871
-556
lines changed

.github/workflows/ci.yml

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,10 @@ jobs:
4949
tensorflow: 2.3.1
5050
tf_version: v2
5151
keras: 2.4.3
52-
- name: TensorFlow 2.4.0rc2 (Keras 2.4.3 Python 3.8)
52+
- name: TensorFlow 2.4.0rc3 (Keras 2.4.3 Python 3.8)
5353
framework: tensorflow
5454
python: 3.8
55-
tensorflow: 2.4.0rc1
55+
tensorflow: 2.4.0rc3
5656
tf_version: v2
5757
keras: 2.4.3
5858
- name: Keras 2.3.1 (TensorFlow 2.2.1 Python 3.7)
@@ -100,27 +100,30 @@ jobs:
100100
uses: actions/setup-python@v2
101101
with:
102102
python-version: ${{ matrix.python }}
103+
- name: Install Dependencies
104+
run: |
105+
sudo apt-get update
106+
sudo apt-get -y -q install ffmpeg libavcodec-extra
107+
python -m pip install --upgrade pip setuptools wheel
108+
pip3 install -q -r requirements.txt
109+
pip list
103110
- name: Pre-install legacy
104111
if: ${{ matrix.framework == 'legacy' }}
105112
run: |
106113
pip install tensorflow==${{ matrix.tensorflow }}
107114
pip install keras==${{ matrix.keras }}
108115
pip install scikit-learn==${{ matrix.scikit-learn }}
116+
pip list
109117
- name: Pre-install tensorflow
110118
if: ${{ matrix.framework == 'tensorflow' || matrix.framework == 'keras' || matrix.framework == 'kerastf' }}
111119
run: |
112120
pip install tensorflow==${{ matrix.tensorflow }}
113121
pip install keras==${{ matrix.keras }}
122+
pip list
114123
- name: Pre-install scikit-learn
115124
if: ${{ matrix.framework == 'scikitlearn' }}
116125
run: |
117126
pip install scikit-learn==${{ matrix.scikit-learn }}
118-
- name: Install Dependencies
119-
run: |
120-
sudo apt-get update
121-
sudo apt-get -y -q install ffmpeg libavcodec-extra
122-
python -m pip install --upgrade pip setuptools wheel
123-
pip3 install -q -r requirements.txt
124127
pip list
125128
- name: Run ${{ matrix.name }} Tests
126129
run: ./run_tests.sh ${{ matrix.framework }}

CODE_OF_CONDUCT.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
The Adversarial Robustness Toolbox is dedicated to providing a harassment-free experience for everyone, regardless of gender, gender identity and expression, sexual orientation, disability, physical appearance, body size, age, race, or religion. We do not tolerate harassment of participants in any form.
1+
The Adversarial Robustness Toolbox (ART) is dedicated to providing a harassment-free experience for everyone, regardless of gender, gender identity and expression, sexual orientation, disability, physical appearance, body size, age, race, or religion. We do not tolerate harassment of participants in any form.
22

3-
This code of conduct applies to all Adversarial Robustness Toolbox spaces, both online and off. Anyone who violates this code of conduct may be sanctioned or expelled from these spaces at the discretion of the IBM Research AI team.
3+
This code of conduct applies to all Adversarial Robustness Toolbox spaces, both online and off. Anyone who violates this code of conduct may be sanctioned or expelled from these spaces at the discretion of the Trusted-AI team.
44

55
We may add additional rules over time, which will be made clearly available to participants. Participants are responsible for knowing and abiding by these rules.

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
PROJECT_HOME_DIR := ${CURDIR}
22

33
build:
4-
# Builds a Tensorflow 2 ART docker container
4+
# Builds a TensorFlow 2 ART docker container
55
# IMPORTANT ! If you have an existing python env folder make sure to first add it to the `.dockerIgnore` \
66
to reduce the size of your the art docker image
77
docker build -t project-art-tf2 .
88

99
build1:
10-
# Builds a Tensorflow 1 ART docker container
10+
# Builds a TensorFlow 1 ART docker container
1111
# IMPORTANT ! If you have an existing python env folder make sure to first add it to the `.dockerIgnore` \
1212
to reduce the size of your the art docker image
1313
docker build -t project-art-tf1 .

art/attacks/evasion/__init__.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,26 @@
44
from art.attacks.evasion.adversarial_patch.adversarial_patch import AdversarialPatch
55
from art.attacks.evasion.adversarial_patch.adversarial_patch_numpy import AdversarialPatchNumpy
66
from art.attacks.evasion.adversarial_patch.adversarial_patch_tensorflow import AdversarialPatchTensorFlowV2
7+
from art.attacks.evasion.auto_attack import AutoAttack
8+
from art.attacks.evasion.auto_projected_gradient_descent import AutoProjectedGradientDescent
9+
from art.attacks.evasion.brendel_bethge import BrendelBethgeAttack
710
from art.attacks.evasion.boundary import BoundaryAttack
811
from art.attacks.evasion.carlini import CarliniL2Method, CarliniLInfMethod
912
from art.attacks.evasion.decision_tree_attack import DecisionTreeAttack
1013
from art.attacks.evasion.deepfool import DeepFool
14+
from art.attacks.evasion.dpatch import DPatch
15+
from art.attacks.evasion.dpatch_robust import RobustDPatch
1116
from art.attacks.evasion.elastic_net import ElasticNet
1217
from art.attacks.evasion.fast_gradient import FastGradientMethod
18+
from art.attacks.evasion.frame_saliency import FrameSaliencyAttack
19+
from art.attacks.evasion.feature_adversaries import FeatureAdversaries
1320
from art.attacks.evasion.hclu import HighConfidenceLowUncertainty
1421
from art.attacks.evasion.hop_skip_jump import HopSkipJump
1522
from art.attacks.evasion.imperceptible_asr.imperceptible_asr import ImperceptibleASR
23+
from art.attacks.evasion.imperceptible_asr.imperceptible_asr_pytorch import ImperceptibleASRPyTorch
1624
from art.attacks.evasion.iterative_method import BasicIterativeMethod
1725
from art.attacks.evasion.newtonfool import NewtonFool
26+
from art.attacks.evasion.pixel_threshold import PixelAttack
1827
from art.attacks.evasion.projected_gradient_descent.projected_gradient_descent import ProjectedGradientDescent
1928
from art.attacks.evasion.projected_gradient_descent.projected_gradient_descent_numpy import (
2029
ProjectedGradientDescentNumpy,
@@ -26,23 +35,14 @@
2635
ProjectedGradientDescentTensorFlowV2,
2736
)
2837
from art.attacks.evasion.saliency_map import SaliencyMapMethod
38+
from art.attacks.evasion.shadow_attack import ShadowAttack
39+
from art.attacks.evasion.shapeshifter import ShapeShifter
40+
from art.attacks.evasion.simba import SimBA
2941
from art.attacks.evasion.spatial_transformation import SpatialTransformation
42+
from art.attacks.evasion.square_attack import SquareAttack
43+
from art.attacks.evasion.pixel_threshold import ThresholdAttack
3044
from art.attacks.evasion.universal_perturbation import UniversalPerturbation
3145
from art.attacks.evasion.targeted_universal_perturbation import TargetedUniversalPerturbation
3246
from art.attacks.evasion.virtual_adversarial import VirtualAdversarialMethod
3347
from art.attacks.evasion.wasserstein import Wasserstein
3448
from art.attacks.evasion.zoo import ZooAttack
35-
from art.attacks.evasion.pixel_threshold import PixelAttack
36-
from art.attacks.evasion.pixel_threshold import ThresholdAttack
37-
from art.attacks.evasion.frame_saliency import FrameSaliencyAttack
38-
from art.attacks.evasion.feature_adversaries import FeatureAdversaries
39-
from art.attacks.evasion.dpatch import DPatch
40-
from art.attacks.evasion.shadow_attack import ShadowAttack
41-
from art.attacks.evasion.auto_attack import AutoAttack
42-
from art.attacks.evasion.auto_projected_gradient_descent import AutoProjectedGradientDescent
43-
from art.attacks.evasion.square_attack import SquareAttack
44-
from art.attacks.evasion.simba import SimBA
45-
from art.attacks.evasion.shapeshifter import ShapeShifter
46-
from art.attacks.evasion.imperceptible_asr.imperceptible_asr_pytorch import ImperceptibleASRPytorch
47-
from art.attacks.evasion.brendel_bethge import BrendelBethgeAttack
48-
from art.attacks.evasion.dpatch_robust import RobustDPatch

art/attacks/evasion/brendel_bethge.py

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2104,17 +2104,10 @@ def generate(
21042104
"""
21052105
Applies the Brendel & Bethge attack.
21062106
2107-
Parameters
2108-
----------
2109-
inputs : Tensor that matches model type
2110-
The original clean inputs.
2111-
criterion : Callable
2112-
A callable that returns true if the given logits of perturbed
2113-
inputs should be considered adversarial w.r.t. to the given labels
2114-
and unperturbed inputs.
2115-
starting_point : Tensor of same type and shape as inputs
2116-
Adversarial inputs to use as a starting points, in particular
2117-
for targeted attacks.
2107+
:param x: The original clean inputs.
2108+
:param y: The labels for inputs `x`.
2109+
:param starting_points: Adversarial inputs to use as a starting points, in particular for targeted attacks.
2110+
:param early_stop: Early-stopping criteria.
21182111
"""
21192112
originals = x.copy()
21202113

art/attacks/evasion/dpatch.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ def generate(
225225
return self._patch
226226

227227
@staticmethod
228-
@deprecated_keyword_arg("channel_index", end_version="1.5.0", replaced_by="channels_first")
228+
@deprecated_keyword_arg("channel_index", end_version="1.6.0", replaced_by="channels_first")
229229
def _augment_images_with_patch(
230230
x: np.ndarray,
231231
patch: np.ndarray,
@@ -249,7 +249,7 @@ def _augment_images_with_patch(
249249
center location of the patch during sampling.
250250
:type mask: `np.ndarray`
251251
"""
252-
# Remove in 1.5.0
252+
# Remove in 1.6.0
253253
if channel_index == 3:
254254
channels_first = False
255255
elif channel_index == 1:

art/attacks/evasion/dpatch_robust.py

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -170,10 +170,7 @@ def generate(self, x: np.ndarray, y: Optional[np.ndarray] = None, **kwargs) -> n
170170
x[i_batch_start:i_batch_end], self._patch, channels_first=self.estimator.channels_first
171171
)
172172

173-
gradients = self.estimator.loss_gradient(
174-
x=patched_images,
175-
y=patch_target,
176-
)
173+
gradients = self.estimator.loss_gradient(x=patched_images, y=patch_target,)
177174

178175
gradients = self._untransform_gradients(
179176
gradients, transforms, channels_first=self.estimator.channels_first
@@ -191,9 +188,7 @@ def generate(self, x: np.ndarray, y: Optional[np.ndarray] = None, **kwargs) -> n
191188

192189
if self.estimator.clip_values is not None:
193190
self._patch = np.clip(
194-
self._patch,
195-
a_min=self.estimator.clip_values[0],
196-
a_max=self.estimator.clip_values[1],
191+
self._patch, a_min=self.estimator.clip_values[0], a_max=self.estimator.clip_values[1],
197192
)
198193

199194
return self._patch
@@ -209,7 +204,7 @@ def _augment_images_with_patch(
209204
:param channels_first: Set channels first or last.
210205
"""
211206

212-
transformations = dict()
207+
transformations: Dict[str, Union[float, int]] = dict()
213208
x_copy = x.copy()
214209
patch_copy = patch.copy()
215210
x_patch = x.copy()
@@ -267,10 +262,7 @@ def _augment_images_with_patch(
267262
return x_patch, patch_target, transformations
268263

269264
def _untransform_gradients(
270-
self,
271-
gradients: np.ndarray,
272-
transforms: Dict[str, Union[int, float]],
273-
channels_first: bool,
265+
self, gradients: np.ndarray, transforms: Dict[str, Union[int, float]], channels_first: bool,
274266
) -> np.ndarray:
275267
"""
276268
Revert transformation on gradients.
@@ -291,8 +283,8 @@ def _untransform_gradients(
291283
gradients = np.rot90(gradients, rot90, (1, 2))
292284

293285
# Account for cropping when considering the upper left point of the patch:
294-
x_1 = self.patch_location[0] - transforms["crop_x"]
295-
y_1 = self.patch_location[1] - transforms["crop_y"]
286+
x_1 = self.patch_location[0] - int(transforms["crop_x"])
287+
y_1 = self.patch_location[1] - int(transforms["crop_y"])
296288
x_2 = x_1 + self.patch_shape[0]
297289
y_2 = y_1 + self.patch_shape[1]
298290
gradients = gradients[:, x_1:x_2, y_1:y_2, :]

art/attacks/evasion/feature_adversaries.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,6 @@ def generate(self, x: np.ndarray, y: Optional[np.ndarray] = None, **kwargs) -> n
8383
`scipy.optimize.show_options(solver='minimize', method='L-BFGS-B')`:
8484
Minimize a scalar function of one or more variables using the L-BFGS-B algorithm.
8585
86-
Options
87-
-------
8886
disp : None or int
8987
If `disp is None` (the default), then the supplied version of `iprint`
9088
is used. If `disp is not None`, then it overrides the supplied version
@@ -120,8 +118,6 @@ def generate(self, x: np.ndarray, y: Optional[np.ndarray] = None, **kwargs) -> n
120118
maxls : int, optional
121119
Maximum number of line search steps (per iteration). Default is 20.
122120
123-
Notes
124-
-----
125121
The option `ftol` is exposed via the `scipy.optimize.minimize` interface,
126122
but calling `scipy.optimize.fmin_l_bfgs_b` directly exposes `factr`. The
127123
relationship between the two is ``ftol = factr * numpy.finfo(float).eps``.

art/attacks/evasion/imperceptible_asr/imperceptible_asr.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,7 @@ def _loss_gradient_masking_threshold_torch(
388388
389389
See also `ImperceptibleASR._loss_gradient_masking_threshold_tf`.
390390
"""
391-
import torch
391+
import torch # lgtm [py/import-and-import-from]
392392

393393
# define tensors
394394
perturbation_torch = torch.from_numpy(perturbation).to(self.estimator._device)
@@ -453,7 +453,7 @@ def _approximate_power_spectral_density_torch(
453453
454454
See also `ImperceptibleASR._approximate_power_spectral_density_tf`.
455455
"""
456-
import torch
456+
import torch # lgtm [py/import-and-import-from]
457457

458458
# compute short-time Fourier transform (STFT)
459459
stft_matrix = torch.stft(
@@ -540,10 +540,10 @@ def __init__(self, window_size: int = 2048, hop_size: int = 512, sample_rate: in
540540

541541
def calculate_threshold_and_psd_maximum(self, audio: np.ndarray) -> Tuple[np.ndarray, np.ndarray]:
542542
"""
543-
Compute the global masking threshold for an audio input and also return its maxium power spectral density.
543+
Compute the global masking threshold for an audio input and also return its maximum power spectral density.
544544
545545
This method is the main method to call in order to obtain global masking thresholds for an audio input. It also
546-
returns the maxium power spectral density (PSD) for each frame. Given an audio input, the following steps are
546+
returns the maximum power spectral density (PSD) for each frame. Given an audio input, the following steps are
547547
performed:
548548
549549
1. STFT analysis and sound pressure level normalization
@@ -630,7 +630,8 @@ def power_spectral_density(self, audio: np.ndarray) -> Tuple[np.ndarray, np.ndar
630630
Compute the power spectral density matrix for an audio input.
631631
632632
:param audio: Audio sample of shape `(length,)`.
633-
:return: PSD matrix of shape `(window_size // 2 + 1, frame_length)` and maxium vector of shape `(frame_length)`.
633+
:return: PSD matrix of shape `(window_size // 2 + 1, frame_length)` and maximum vector of shape
634+
`(frame_length)`.
634635
"""
635636
# compute short-time Fourier transform (STFT)
636637
stft_params = {

art/attacks/evasion/imperceptible_asr/imperceptible_asr_pytorch.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"""
1919
This module implements the imperceptible, robust, and targeted attack to generate adversarial examples for automatic
2020
speech recognition models. This attack will be implemented specifically for DeepSpeech model and is framework dependent,
21-
specifically for Pytorch.
21+
specifically for PyTorch.
2222
2323
| Paper link: https://arxiv.org/abs/1903.10346
2424
"""
@@ -44,11 +44,11 @@
4444
logger = logging.getLogger(__name__)
4545

4646

47-
class ImperceptibleASRPytorch(EvasionAttack):
47+
class ImperceptibleASRPyTorch(EvasionAttack):
4848
"""
4949
This class implements the imperceptible, robust, and targeted attack to generate adversarial examples for automatic
5050
speech recognition models. This attack will be implemented specifically for DeepSpeech model and is framework
51-
dependent, specifically for Pytorch.
51+
dependent, specifically for PyTorch.
5252
5353
| Paper link: https://arxiv.org/abs/1903.10346
5454
"""
@@ -108,7 +108,7 @@ def __init__(
108108
opt_level: str = "O1",
109109
):
110110
"""
111-
Create a :class:`.ImperceptibleASRPytorch` instance.
111+
Create a :class:`.ImperceptibleASRPyTorch` instance.
112112
113113
:param estimator: A trained estimator.
114114
:param initial_eps: Initial maximum perturbation that the attacker can introduce.
@@ -236,7 +236,7 @@ class only supports targeted attack.
236236

237237
if y is None:
238238
raise ValueError(
239-
"`ImperceptibleASRPytorch` is a targeted attack and requires the definition of target"
239+
"`ImperceptibleASRPyTorch` is a targeted attack and requires the definition of target"
240240
"labels `y`. Currently `y` is set to `None`."
241241
)
242242

0 commit comments

Comments
 (0)