Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement estimator for Hugging Face models #2245

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
b0b5be0
adding core hf estimator
GiulioZizzo Jul 3, 2023
2e32345
initial image processing
GiulioZizzo Jul 3, 2023
7a33398
adding huggingface to trainer tests
GiulioZizzo Jul 7, 2023
8faa487
updates to huggingface estimator
GiulioZizzo Jul 7, 2023
b7ed033
initial test_adversarial_trainer from unittest to pytest conversion
GiulioZizzo Jul 14, 2023
7728cb2
update test_deeplearning_common.py for huggingface
GiulioZizzo Jul 19, 2023
9e0246f
updating test for test_clean_label_backdoor_attack
GiulioZizzo Jul 21, 2023
101a309
update to test_adversarial_trainer_madry_pgd
GiulioZizzo Jul 24, 2023
c314c11
add huggingface workflow
GiulioZizzo Jul 24, 2023
b6d3fb0
Create ci-huggingface-2.yml
GiulioZizzo Jul 24, 2023
5005e08
checking workflow
GiulioZizzo Jul 24, 2023
f42e115
updating failing tests
GiulioZizzo Jul 24, 2023
1f3bfcc
updates to test_adversarial_trainer for huggingface
GiulioZizzo Jul 24, 2023
11c8d91
adding initial functionality for getting activations
GiulioZizzo Jul 24, 2023
8d96eea
updating huggignface get activations
GiulioZizzo Jul 25, 2023
df40e1c
updates to test_adversarial_trainer_FBF for huggingface
GiulioZizzo Jul 25, 2023
9399ccd
initial refactor for getting activations with pytorch. Potentially mo…
GiulioZizzo Jul 25, 2023
551da0b
using logits in pytorch estimator to follow the default loss function
GiulioZizzo Jul 26, 2023
c3d52ef
updating keyword args
GiulioZizzo Jul 26, 2023
4249610
initial activation defence test refactor
GiulioZizzo Jul 27, 2023
17f4f46
refactor test_activation_defence_pytest for pytest
GiulioZizzo Jul 28, 2023
f49978c
check for HF output type. Development to HF tests for TRADES
GiulioZizzo Jul 31, 2023
ef805e8
adding option for small classifier to run on CI actions
GiulioZizzo Jul 31, 2023
d209c0f
refactor for hidden trigger backdoor. Added tiebreak check for hidden…
GiulioZizzo Jul 31, 2023
ae3b343
update get_activations for huggingface with correct return if using f…
GiulioZizzo Jul 31, 2023
6498386
initial addition of test_projected_gradient_descent in pytorch format
GiulioZizzo Jul 31, 2023
126460a
addinf framework check to some tests in test_adversarial_trainer
GiulioZizzo Aug 1, 2023
d9326ff
adding tests for pgd checks
GiulioZizzo Aug 1, 2023
c1c5b94
adding hf tabular classifier
GiulioZizzo Aug 1, 2023
2bab5d6
correctly checking framework in test
GiulioZizzo Aug 2, 2023
de1d477
remove unneeded files. CI fixes.
GiulioZizzo Aug 16, 2023
86645ec
CI updates and style edits
GiulioZizzo Aug 17, 2023
fffed5a
re adding old test_adversarial_trainer_madry_pgd.py due to legacy tes…
GiulioZizzo Aug 17, 2023
e2f2ab7
adjusting pre-processors for HF. Adding progress bar to pgd trainer t…
GiulioZizzo Aug 21, 2023
88a2791
updates to progress bar display
GiulioZizzo Aug 21, 2023
ed65928
updates to progress bar display
GiulioZizzo Aug 21, 2023
ad3d581
adding initial notebook
GiulioZizzo Aug 21, 2023
d178ab6
Updating displayed progress bar info. Updated notebook. Type hinting …
GiulioZizzo Aug 23, 2023
5d7b08d
Black formatting. Executed notebook
GiulioZizzo Aug 24, 2023
daa7c62
Merge branch 'dev_1.16.0' into huggingface_integration
GiulioZizzo Aug 24, 2023
9208af9
Switch to small HF model for FBF test. Formatting edits
GiulioZizzo Aug 24, 2023
124f6c8
update allowed values for HF FBF. Formatting edits
GiulioZizzo Aug 24, 2023
2e7a29a
Initial review edits
GiulioZizzo Aug 25, 2023
e67388f
initial round of review edits
GiulioZizzo Aug 25, 2023
e520782
CI cleanup
GiulioZizzo Aug 26, 2023
41ac37d
removing option for large model
GiulioZizzo Aug 26, 2023
5cccfba
moving location of hf classifier. updating clean label attack to work…
GiulioZizzo Aug 26, 2023
f9fcc3f
moving progress bars to different PR. Re-running notebook
GiulioZizzo Aug 26, 2023
0178cbe
Simplifying poison changes. Removing missed progress bar edits
GiulioZizzo Aug 26, 2023
0914f99
Using clip values in notebook. CI error fixes
GiulioZizzo Aug 27, 2023
9ed5e32
remove unneeded components
GiulioZizzo Aug 31, 2023
d0f3fa1
remove unneeded change
GiulioZizzo Sep 1, 2023
b3cbf95
Merge branch 'dev_1.16.0' into huggingface_integration
beat-buesser Sep 8, 2023
5d6f11a
Update tests/attacks/poison/test_hidden_trigger_backdoor.py
GiulioZizzo Sep 13, 2023
89bd452
review cleanup
GiulioZizzo Sep 13, 2023
44bdefe
adding additional options for arguments to hf to match pytorch classi…
GiulioZizzo Sep 13, 2023
6f37944
mypy error fix
GiulioZizzo Sep 13, 2023
25d357a
clean up of dp instahide test
GiulioZizzo Sep 14, 2023
fe91036
clean up of dp instahide test
GiulioZizzo Sep 14, 2023
3d4fe0d
Merge branch 'dev_1.16.0' into huggingface_integration
beat-buesser Sep 18, 2023
6a6f094
Merge branch 'dev_1.16.0' into huggingface_integration
beat-buesser Sep 18, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions .github/workflows/ci-huggingface.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
name: CI Huggingface
on:
# Run on manual trigger
workflow_dispatch:

# Run on pull requests
pull_request:
paths-ignore:
- '*.md'

# Run on merge queue
merge_group:

# Run when pushing to main or dev branches
push:
branches:
- main
- dev*

# Run scheduled CI flow daily
schedule:
- cron: '0 8 * * 0'

jobs:
test:
runs-on: ubuntu-20.04
strategy:
fail-fast: false
matrix:
include:
- name: Huggingface 4.30
framework: huggingface
python: 3.9
torch: 1.13.1+cpu
torchvision: 0.14.1+cpu
torchaudio: 0.13.1
transformers: 4.30.2

name: ${{ matrix.name }}
steps:
- name: Checkout Repo
uses: actions/checkout@v3
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python }}
- name: Install Dependencies
run: |
sudo apt-get update
sudo apt-get -y -q install ffmpeg libavcodec-extra
python -m pip install --upgrade pip setuptools wheel
pip3 install -r requirements_test.txt
pip install tensorflow==2.10.1
pip install keras==2.10.0
pip install torch==${{ matrix.torch }} -f https://download.pytorch.org/whl/cpu/torch_stable.html
pip install torchvision==${{ matrix.torchvision }} -f https://download.pytorch.org/whl/cpu/torch_stable.html
pip install torchaudio==${{ matrix.torchaudio }} -f https://download.pytorch.org/whl/cpu/torch_stable.html
pip install transformers==${{ matrix.transformers }}
pip list
- name: Run Tests
run: ./run_tests.sh ${{ matrix.framework }}
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
with:
fail_ci_if_error: true
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,8 @@ def poison( # pylint: disable=W0221

for _ in range(feat2.size(0)):
dist_min_index = (dist == torch.min(dist)).nonzero().squeeze()
if dist_min_index.dim() > 1: # If multiple values in dist equal torch.min(dist), return the first.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this change required?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There could be several items in dist with the same minimum value. Hence, dist_min_index, rather than being an expected index, is a tensor with several values. To avoid this crashing the attack, we pick the first returned index. This bug was discovered when adapting the attacks to run with HF.

dist_min_index = dist_min_index[0]
feat1[dist_min_index[1]] = feat11[dist_min_index[0]]
dist[dist_min_index[0], dist_min_index[1]] = 1e5

Expand Down
23 changes: 21 additions & 2 deletions art/attacks/poisoning/perturbations/image_perturbations.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,18 +49,29 @@ def add_single_bd(x: np.ndarray, distance: int = 2, pixel_value: int = 1) -> np.
return x


def add_pattern_bd(x: np.ndarray, distance: int = 2, pixel_value: int = 1) -> np.ndarray:
def add_pattern_bd(x: np.ndarray, distance: int = 2, pixel_value: int = 1, channels_first: bool = False) -> np.ndarray:
GiulioZizzo marked this conversation as resolved.
Show resolved Hide resolved
"""
Augments a matrix by setting a checkerboard-like pattern of values some `distance` away from the bottom-right
edge to 1. Works for single images or a batch of images.

:param x: A single image or batch of images of shape NWHC, NHW, or HC. Pixels will be added to all channels.
:param distance: Distance from bottom-right walls.
:param pixel_value: Value used to replace the entries of the image matrix.
:param channels_first: If the data is provided in channels first format we transpose to NWHC or HC depending on
input shape
:return: Backdoored image.
"""
x = np.copy(x)
original_dtype = x.dtype
shape = x.shape
if channels_first:
if len(shape) == 4:
# Transpose the image putting channels last
x = np.transpose(x, (0, 2, 3, 1))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the transpose with 4 indices work if len(shape)==3?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point: that should only apply to 4D inputs and an additional one is needed for 2D to go from HC to CH.

if len(shape) == 2:
# HC to CH
x = np.transpose(x)

if len(shape) == 4:
height, width = x.shape[1:3]
x[:, height - distance, width - distance, :] = pixel_value
Expand All @@ -81,7 +92,15 @@ def add_pattern_bd(x: np.ndarray, distance: int = 2, pixel_value: int = 1) -> np
x[height - distance - 2, width - distance] = pixel_value
else:
raise ValueError(f"Invalid array shape: {shape}")
return x

if channels_first:
if len(shape) == 4:
# Putting channels first again
x = np.transpose(x, (0, 3, 1, 2))
if len(shape) == 2:
x = np.transpose(x)

return x.astype(original_dtype)


def insert_image(
Expand Down
1 change: 1 addition & 0 deletions art/estimators/classification/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from art.estimators.classification.lightgbm import LightGBMClassifier
from art.estimators.classification.mxnet import MXClassifier
from art.estimators.classification.pytorch import PyTorchClassifier
from art.estimators.classification.hugging_face import HuggingFaceClassifierPyTorch
from art.estimators.classification.query_efficient_bb import QueryEfficientGradientEstimationClassifier
from art.estimators.classification.scikitlearn import SklearnClassifier
from art.estimators.classification.tensorflow import (
Expand Down
Loading
Loading