Kieran Fraser commited on
Commit
f5ee954
1 Parent(s): 6b3cf2c

Initial commit.

Browse files

Signed-off-by: Kieran Fraser <Kieran.Fraser@ibm.com>

This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitignore +259 -0
  2. README.md +5 -4
  3. app.py +333 -0
  4. art_lfai.png +0 -0
  5. baby-on-board.png +0 -0
  6. carbon_colors.py +173 -0
  7. carbon_theme.py +102 -0
  8. data/imagenette2-320/noisy_imagenette.csv +0 -0
  9. data/imagenette2-320/train/n01440764/ILSVRC2012_val_00000293.JPEG +0 -0
  10. data/imagenette2-320/train/n01440764/ILSVRC2012_val_00002138.JPEG +0 -0
  11. data/imagenette2-320/train/n01440764/ILSVRC2012_val_00003014.JPEG +0 -0
  12. data/imagenette2-320/train/n01440764/ILSVRC2012_val_00006697.JPEG +0 -0
  13. data/imagenette2-320/train/n01440764/ILSVRC2012_val_00007197.JPEG +0 -0
  14. data/imagenette2-320/train/n01440764/ILSVRC2012_val_00009346.JPEG +0 -0
  15. data/imagenette2-320/train/n01440764/ILSVRC2012_val_00009379.JPEG +0 -0
  16. data/imagenette2-320/train/n01440764/ILSVRC2012_val_00009396.JPEG +0 -0
  17. data/imagenette2-320/train/n01440764/ILSVRC2012_val_00010306.JPEG +0 -0
  18. data/imagenette2-320/train/n01440764/ILSVRC2012_val_00011233.JPEG +0 -0
  19. data/imagenette2-320/train/n02102040/ILSVRC2012_val_00000665.JPEG +0 -0
  20. data/imagenette2-320/train/n02102040/ILSVRC2012_val_00001968.JPEG +0 -0
  21. data/imagenette2-320/train/n02102040/ILSVRC2012_val_00002294.JPEG +0 -0
  22. data/imagenette2-320/train/n02102040/ILSVRC2012_val_00002315.JPEG +0 -0
  23. data/imagenette2-320/train/n02102040/ILSVRC2012_val_00004548.JPEG +0 -0
  24. data/imagenette2-320/train/n02102040/ILSVRC2012_val_00004553.JPEG +0 -0
  25. data/imagenette2-320/train/n02102040/ILSVRC2012_val_00007568.JPEG +0 -0
  26. data/imagenette2-320/train/n02102040/ILSVRC2012_val_00008334.JPEG +0 -0
  27. data/imagenette2-320/train/n02102040/ILSVRC2012_val_00010994.JPEG +0 -0
  28. data/imagenette2-320/train/n02102040/ILSVRC2012_val_00012689.JPEG +0 -0
  29. data/imagenette2-320/train/n02102040/ILSVRC2012_val_00014125.JPEG +0 -0
  30. data/imagenette2-320/train/n02979186/ILSVRC2012_val_00000557.JPEG +0 -0
  31. data/imagenette2-320/train/n02979186/ILSVRC2012_val_00002034.JPEG +0 -0
  32. data/imagenette2-320/train/n02979186/ILSVRC2012_val_00003944.JPEG +0 -0
  33. data/imagenette2-320/train/n02979186/ILSVRC2012_val_00005866.JPEG +0 -0
  34. data/imagenette2-320/train/n02979186/ILSVRC2012_val_00006787.JPEG +0 -0
  35. data/imagenette2-320/train/n02979186/ILSVRC2012_val_00007226.JPEG +0 -0
  36. data/imagenette2-320/train/n02979186/ILSVRC2012_val_00009404.JPEG +0 -0
  37. data/imagenette2-320/train/n02979186/ILSVRC2012_val_00009833.JPEG +0 -0
  38. data/imagenette2-320/train/n02979186/ILSVRC2012_val_00012468.JPEG +0 -0
  39. data/imagenette2-320/train/n02979186/ILSVRC2012_val_00013735.JPEG +0 -0
  40. data/imagenette2-320/train/n02979186/ILSVRC2012_val_00014287.JPEG +0 -0
  41. data/imagenette2-320/train/n03000684/ILSVRC2012_val_00000537.JPEG +0 -0
  42. data/imagenette2-320/train/n03000684/ILSVRC2012_val_00004034.JPEG +0 -0
  43. data/imagenette2-320/train/n03000684/ILSVRC2012_val_00005506.JPEG +0 -0
  44. data/imagenette2-320/train/n03000684/ILSVRC2012_val_00006043.JPEG +0 -0
  45. data/imagenette2-320/train/n03000684/ILSVRC2012_val_00006578.JPEG +0 -0
  46. data/imagenette2-320/train/n03000684/ILSVRC2012_val_00006669.JPEG +0 -0
  47. data/imagenette2-320/train/n03000684/ILSVRC2012_val_00006726.JPEG +0 -0
  48. data/imagenette2-320/train/n03000684/ILSVRC2012_val_00009206.JPEG +0 -0
  49. data/imagenette2-320/train/n03000684/ILSVRC2012_val_00017719.JPEG +0 -0
  50. data/imagenette2-320/train/n03000684/ILSVRC2012_val_00019137.JPEG +0 -0
.gitignore ADDED
@@ -0,0 +1,259 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ pip-wheel-metadata/
24
+ share/python-wheels/
25
+ *.egg-info/
26
+ .installed.cfg
27
+ *.egg
28
+ MANIFEST
29
+
30
+ # PyInstaller
31
+ # Usually these files are written by a python script from a template
32
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
33
+ *.manifest
34
+ *.spec
35
+
36
+ # Installer logs
37
+ pip-log.txt
38
+ pip-delete-this-directory.txt
39
+
40
+ # Unit test / coverage reports
41
+ htmlcov/
42
+ .tox/
43
+ .nox/
44
+ .coverage
45
+ .coverage.*
46
+ .cache
47
+ nosetests.xml
48
+ coverage.xml
49
+ *.cover
50
+ *.py,cover
51
+ .hypothesis/
52
+ .pytest_cache/
53
+
54
+ # Translations
55
+ *.mo
56
+ *.pot
57
+
58
+ # Django stuff:
59
+ *.log
60
+ local_settings.py
61
+ db.sqlite3
62
+ db.sqlite3-journal
63
+
64
+ # Flask stuff:
65
+ instance/
66
+ .webassets-cache
67
+
68
+ # Scrapy stuff:
69
+ .scrapy
70
+
71
+ # Sphinx documentation
72
+ docs/_build/
73
+
74
+ # PyBuilder
75
+ target/
76
+
77
+ # Jupyter Notebook
78
+ .ipynb_checkpoints
79
+
80
+ # IPython
81
+ profile_default/
82
+ ipython_config.py
83
+
84
+ # pyenv
85
+ .python-version
86
+
87
+ # pipenv
88
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
89
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
90
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
91
+ # install all needed dependencies.
92
+ #Pipfile.lock
93
+
94
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow
95
+ __pypackages__/
96
+
97
+ # Celery stuff
98
+ celerybeat-schedule
99
+ celerybeat.pid
100
+
101
+ # SageMath parsed files
102
+ *.sage.py
103
+
104
+ # Environments
105
+ .env
106
+ .venv
107
+ env/
108
+ venv/
109
+ ENV/
110
+ env.bak/
111
+ venv.bak/
112
+
113
+ # Spyder project settings
114
+ .spyderproject
115
+ .spyproject
116
+
117
+ # Rope project settings
118
+ .ropeproject
119
+
120
+ # mkdocs documentation
121
+ /site
122
+
123
+ # mypy
124
+ .mypy_cache/
125
+ .dmypy.json
126
+ dmypy.json
127
+
128
+ # Pyre type checker
129
+ .pyre/
130
+
131
+ !.vscode/*.code-snippets
132
+ !.vscode/extensions.json
133
+ !.vscode/launch.json
134
+ !.vscode/settings.json
135
+ !.vscode/tasks.json
136
+ *$py.class
137
+ *.code-workspace
138
+ *.cover
139
+ *.egg
140
+ *.egg-info/
141
+ *.iws
142
+ *.log
143
+ *.manifest
144
+ *.mo
145
+ *.pot
146
+ *.py,cover
147
+ *.py[cod]
148
+ *.sage.py
149
+ *.so
150
+ *.spec
151
+ *.vsix
152
+ .Python
153
+ .cache
154
+ .coverage
155
+ .coverage.*
156
+ .dmypy.json
157
+ .eggs/
158
+ .env
159
+ .history
160
+ .history/
161
+ .hypothesis/
162
+ .idea/$CACHE_FILE$
163
+ .idea/**/aws.xml
164
+ .idea/**/azureSettings.xml
165
+ .idea/**/contentModel.xml
166
+ .idea/**/dataSources.ids
167
+ .idea/**/dataSources.local.xml
168
+ .idea/**/dataSources/
169
+ .idea/**/dbnavigator.xml
170
+ .idea/**/dictionaries
171
+ .idea/**/dynamic.xml
172
+ .idea/**/gradle.xml
173
+ .idea/**/libraries
174
+ .idea/**/markdown-navigator-enh.xml
175
+ .idea/**/markdown-navigator.xml
176
+ .idea/**/markdown-navigator/
177
+ .idea/**/mongoSettings.xml
178
+ .idea/**/shelf
179
+ .idea/**/sonarIssues.xml
180
+ .idea/**/sonarlint/
181
+ .idea/**/sqlDataSources.xml
182
+ .idea/**/tasks.xml
183
+ .idea/**/uiDesigner.xml
184
+ .idea/**/usage.statistics.xml
185
+ .idea/**/workspace.xml
186
+ .idea/caches/build_file_checksums.ser
187
+ .idea/codestream.xml
188
+ .idea/httpRequests
189
+ .idea/replstate.xml
190
+ .idea/sonarlint/
191
+ .idea_modules/
192
+ .installed.cfg
193
+ .ionide
194
+ .ipynb_checkpoints
195
+ .mypy_cache/
196
+ .nox/
197
+ .pdm.toml
198
+ .pybuilder/
199
+ .pyre/
200
+ .pytest_cache/
201
+ .pytype/
202
+ .ropeproject
203
+ .scrapy
204
+ .spyderproject
205
+ .spyproject
206
+ .tox/
207
+ .venv
208
+ .vscode/*
209
+ .vscode/*.code-snippets
210
+ .webassets-cache
211
+ /site
212
+ ENV/
213
+ MANIFEST
214
+ __pycache__/
215
+ __pypackages__/
216
+ atlassian-ide-plugin.xml
217
+ build/
218
+ celerybeat-schedule
219
+ celerybeat.pid
220
+ cmake-build-*/
221
+ com_crashlytics_export_strings.xml
222
+ cover/
223
+ coverage.xml
224
+ crashlytics-build.properties
225
+ crashlytics.properties
226
+ cython_debug/
227
+ db.sqlite3
228
+ db.sqlite3-journal
229
+ develop-eggs/
230
+ dist/
231
+ dmypy.json
232
+ docs/_build/
233
+ downloads/
234
+ eggs/
235
+ env.bak/
236
+ env/
237
+ fabric.properties
238
+ htmlcov/
239
+ instance/
240
+ ipython_config.py
241
+ lib/
242
+ lib64/
243
+ local_settings.py
244
+ nosetests.xml
245
+ out/
246
+ parts/
247
+ pip-delete-this-directory.txt
248
+ pip-log.txt
249
+ profile_default/
250
+ sdist/
251
+ share/python-wheels/
252
+ target/
253
+ var/
254
+ venv.bak/
255
+ venv/
256
+ wheels/
257
+ Pipfile
258
+ .vscode
259
+ Pipfile.lock
README.md CHANGED
@@ -1,12 +1,13 @@
1
  ---
2
- title: Art Huggingface Poisoning
3
- emoji: 📉
4
- colorFrom: gray
5
- colorTo: gray
6
  sdk: gradio
7
  sdk_version: 4.15.0
8
  app_file: app.py
9
  pinned: false
 
10
  ---
11
 
12
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: Red-teaming Hugging Face with ART [Poisoning]
3
+ emoji: 🧪
4
+ colorFrom: red
5
+ colorTo: green
6
  sdk: gradio
7
  sdk_version: 4.15.0
8
  app_file: app.py
9
  pinned: false
10
+ license: mit
11
  ---
12
 
13
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
app.py ADDED
@@ -0,0 +1,333 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ '''
2
+ ART Gradio Example App [Evasion]
3
+
4
+ To run:
5
+ - clone the repository
6
+ - execute: gradio examples/gradio_app.py or python examples/gradio_app.py
7
+ - navigate to local URL e.g. http://127.0.0.1:7860
8
+ '''
9
+
10
+ import gradio as gr
11
+ import numpy as np
12
+ from carbon_theme import Carbon
13
+
14
+ import numpy as np
15
+ import torch
16
+ import transformers
17
+
18
+ from art.estimators.classification.hugging_face import HuggingFaceClassifierPyTorch
19
+ from art.attacks.evasion import ProjectedGradientDescentPyTorch, AdversarialPatchPyTorch
20
+ from art.utils import load_dataset
21
+
22
+ from art.attacks.poisoning import PoisoningAttackBackdoor
23
+ from art.attacks.poisoning.perturbations import insert_image
24
+
25
+ device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
26
+
27
+ css = """
28
+
29
+ .custom-text {
30
+ --text-md: 20px !important;
31
+ --text-sm: 18px !important;
32
+ --block-info-text-size: var(--text-sm);
33
+ --block-label-text-size: var(--text-sm);
34
+ --block-title-text-size: var(--text-md);
35
+ --body-text-size: var(--text-md);
36
+ --button-small-text-size: var(--text-md);
37
+ --checkbox-label-text-size: var(--text-md);
38
+ --input-text-size: var(--text-md);
39
+ --prose-text-size: var(--text-md);
40
+ --section-header-text-size: var(--text-md);
41
+ }
42
+ .input-image { margin: auto !important }
43
+ .plot-padding { padding: 20px; }
44
+ .eta-bar.svelte-1occ011.svelte-1occ011 {
45
+ background: #ccccff !important;
46
+ }
47
+ .center-text { text-align: center !important }
48
+ .larger-gap { gap: 100px !important; }
49
+ .symbols { text-align: center !important; margin: auto !important; }
50
+
51
+ div.svelte-15lo0d8>*, div.svelte-15lo0d8>.form > * {
52
+ min-width: 0px !important;
53
+ }
54
+ """
55
+
56
+ def sample_imagenette():
57
+ import torchvision
58
+ label_names = [
59
+ 'fish',
60
+ 'dog',
61
+ 'cassette player',
62
+ 'chainsaw',
63
+ 'church',
64
+ 'french horn',
65
+ 'garbage truck',
66
+ 'gas pump',
67
+ 'golf ball',
68
+ 'parachutte',
69
+ ]
70
+ transform = torchvision.transforms.Compose([
71
+ torchvision.transforms.Resize((224, 224)),
72
+ torchvision.transforms.ToTensor(),
73
+ ])
74
+ train_dataset = torchvision.datasets.ImageFolder(root="./data/imagenette2-320/train", transform=transform)
75
+ labels = np.asarray(train_dataset.targets)
76
+ classes = np.unique(labels)
77
+ samples_per_class = 1
78
+
79
+ x_subset = []
80
+ y_subset = []
81
+
82
+ for c in classes:
83
+ indices = np.where(labels == c)[0][:samples_per_class]
84
+ for i in indices:
85
+ x_subset.append(train_dataset[i][0])
86
+ y_subset.append(train_dataset[i][1])
87
+
88
+ x_subset = np.stack(x_subset)
89
+ y_subset = np.asarray(y_subset)
90
+
91
+ gallery_out = []
92
+ for i, im in enumerate(x_subset):
93
+ gallery_out.append( (im.transpose(1,2,0), label_names[y_subset[i]]) )
94
+ return gallery_out
95
+
96
+ def clf_poison_evaluate(*args):
97
+ label_names = [
98
+ 'fish',
99
+ 'dog',
100
+ 'cassette player',
101
+ 'chainsaw',
102
+ 'church',
103
+ 'french horn',
104
+ 'garbage truck',
105
+ 'gas pump',
106
+ 'golf ball',
107
+ 'parachutte',
108
+ ]
109
+
110
+ attack = args[0]
111
+ trigger_image = args[1]
112
+ target_class = args[2]
113
+
114
+ target_class = label_names.index(target_class)
115
+
116
+ model = transformers.AutoModelForImageClassification.from_pretrained(
117
+ 'facebook/deit-tiny-distilled-patch16-224',
118
+ ignore_mismatched_sizes=True,
119
+ force_download=True,
120
+ num_labels=10
121
+ )
122
+ optimizer = torch.optim.Adam(model.parameters(), lr=1e-4)
123
+ loss_fn = torch.nn.CrossEntropyLoss()
124
+
125
+ poison_hf_model = HuggingFaceClassifierPyTorch(
126
+ model=model,
127
+ loss=loss_fn,
128
+ optimizer=optimizer,
129
+ input_shape=(3, 224, 224),
130
+ nb_classes=10,
131
+ clip_values=(0, 1),
132
+ )
133
+
134
+ model_checkpoint_path = './poisoned_models/deit_imagenette_poisoned_model_'+str(target_class)+'.pt'
135
+ poison_hf_model.model.load_state_dict(torch.load(model_checkpoint_path, map_location=device))
136
+
137
+ import torchvision
138
+ transform = torchvision.transforms.Compose([
139
+ torchvision.transforms.Resize((224, 224)),
140
+ torchvision.transforms.ToTensor(),
141
+ ])
142
+ train_dataset = torchvision.datasets.ImageFolder(root="./data/imagenette2-320/train", transform=transform)
143
+ labels = np.asarray(train_dataset.targets)
144
+ classes = np.unique(labels)
145
+ samples_per_class = 10
146
+
147
+ x_subset = []
148
+ y_subset = []
149
+
150
+ for c in classes:
151
+ indices = np.where(labels == c)[0][:samples_per_class]
152
+ for i in indices:
153
+ x_subset.append(train_dataset[i][0])
154
+ y_subset.append(train_dataset[i][1])
155
+
156
+ x_subset = np.stack(x_subset)
157
+ y_subset = np.asarray(y_subset)
158
+
159
+ if attack == "Backdoor":
160
+ from PIL import Image
161
+ im = Image.fromarray(trigger_image)
162
+ im.save("./tmp.png")
163
+
164
+ def poison_func(x):
165
+ return insert_image(
166
+ x,
167
+ backdoor_path='./baby-on-board.png',
168
+ channels_first=True,
169
+ random=False,
170
+ x_shift=0,
171
+ y_shift=0,
172
+ size=(32, 32),
173
+ mode='RGB',
174
+ blend=0.8
175
+ )
176
+
177
+ backdoor = PoisoningAttackBackdoor(poison_func)
178
+ source_class = 0
179
+ poison_percent = 0.5
180
+
181
+ x_poison = np.copy(x_subset)
182
+ y_poison = np.copy(y_subset)
183
+ is_poison = np.zeros(len(x_subset)).astype(bool)
184
+
185
+ indices = np.where(y_subset == source_class)[0]
186
+ num_poison = int(poison_percent * len(indices))
187
+
188
+ for i in indices[:num_poison]:
189
+ x_poison[i], _ = backdoor.poison(x_poison[i], [])
190
+ y_poison[i] = target_class
191
+ is_poison[i] = True
192
+
193
+ poison_indices = np.where(is_poison)[0]
194
+ #poison_hf_model.fit(x_poison, y_poison, nb_epochs=2)
195
+
196
+ clean_x = x_poison[~is_poison]
197
+ clean_y = y_poison[~is_poison]
198
+
199
+ outputs = poison_hf_model.predict(clean_x)
200
+ clean_preds = np.argmax(outputs, axis=1)
201
+ clean_acc = np.mean(clean_preds == clean_y)
202
+
203
+ clean_out = []
204
+ for i, im in enumerate(clean_x):
205
+ clean_out.append( (im.transpose(1,2,0), label_names[clean_preds[i]]) )
206
+
207
+ poison_x = x_poison[is_poison]
208
+ poison_y = y_poison[is_poison]
209
+
210
+ outputs = poison_hf_model.predict(poison_x)
211
+ poison_preds = np.argmax(outputs, axis=1)
212
+ poison_acc = np.mean(poison_preds == poison_y)
213
+
214
+ poison_out = []
215
+ for i, im in enumerate(poison_x):
216
+ poison_out.append( (im.transpose(1,2,0), label_names[poison_preds[i]]) )
217
+
218
+
219
+ return clean_out, poison_out, clean_acc, poison_acc
220
+
221
+ def show_params(type):
222
+ '''
223
+ Show model parameters based on selected model type
224
+ '''
225
+ if type!="Example":
226
+ return gr.Column(visible=True)
227
+ return gr.Column(visible=False)
228
+
229
+ # e.g. To use a local alternative theme: carbon_theme = Carbon()
230
+ carbon_theme = Carbon()
231
+ with gr.Blocks(css=css, theme='Tshackelton/IBMPlex-DenseReadable') as demo:
232
+ import art
233
+ text = art.__version__
234
+
235
+ with gr.Row(elem_classes="custom-text"):
236
+ with gr.Column(scale=1,):
237
+ gr.Image(value="./art_lfai.png", show_label=False, show_download_button=False, width=100, show_share_button=False)
238
+ with gr.Column(scale=2):
239
+ gr.Markdown(f"<h1>🧪 Red-teaming HuggingFace with ART [Poisoning]</h1>", elem_classes="plot-padding")
240
+
241
+
242
+ gr.Markdown('''<p style="font-size: 20px; text-align: justify">ℹ️ Red-teaming in AI is an activity where we masquerade
243
+ as evil attackers 😈 and attempt to find vulnerabilities in our AI models. Identifying scenarios where
244
+ our AI models do not work as expected, or fail, is important as it helps us better understand
245
+ its limitations and vulnerability when deployed in the real world 🧐</p>''')
246
+ gr.Markdown('''<p style="font-size: 20px; text-align: justify">ℹ️ By attacking our AI models ourselves, we can better the risks associated with use
247
+ in the real world and implement mechanisms which can mitigate and protect our model. The example below demonstrates a
248
+ common red-team workflow to assess model vulnerability to data poisoning attacks 🧪</p>''')
249
+
250
+ gr.Markdown('''<p style="font-size: 18px; text-align: justify"><i>Check out the full suite of features provided by ART <a href="https://github.com/Trusted-AI/adversarial-robustness-toolbox"
251
+ target="blank_">here</a>.</i>
252
+ add link to notebook</p>''')
253
+
254
+ gr.Markdown('''<hr/>''')
255
+
256
+
257
+ with gr.Row(elem_classes=["larger-gap", "custom-text"]):
258
+ with gr.Column(scale=1):
259
+ gr.Markdown('''<p style="font-size: 20px; text-align: justify">ℹ️ First lets set the scene. You have a dataset of images, such as Imagenette.</p>''')
260
+ gr.Markdown('''<p style="font-size: 18px; text-align: justify"><i>Note: Imagenette is a subset of 10 easily classified classes from Imagenet as shown.</i></p>''')
261
+ gr.Markdown('''<p style="font-size: 20px; text-align: justify">ℹ️ Your goal is to have an AI model capable of classifying these images. So you
262
+ find a pre-trained model from Hugging Face,
263
+ such as Meta's Distilled Data-efficient Image Transformer, which has been trained on this data (or so you think ☠️).</p>''')
264
+ with gr.Column(scale=1):
265
+ gr.Markdown('''
266
+ <p style="font-size: 20px;"><b>Hugging Face dataset:</b>
267
+ <a href="https://huggingface.co/datasets/frgfm/imagenette" target="_blank">Imagenette</a></p>
268
+ <p style="font-size: 18px; padding-left: 20px;"><i>Imagenette labels:</i>
269
+ <i>{fish, dog, cassette player, chain saw, church, French horn, garbage truck, gas pump, golf ball, parachute}</i>
270
+ </p>
271
+ <p style="font-size: 20px;"><b>Hugging Face model:</b><br/>
272
+ <a href="https://huggingface.co/facebook/deit-tiny-patch16-224"
273
+ target="_blank">facebook/deit-tiny-distilled-patch16-224</a></p>
274
+ <br/>
275
+ <p style="font-size: 20px;">👀 take a look at the sample images from the Imagenette dataset and their respective labels.</p>
276
+ ''')
277
+ with gr.Column(scale=1):
278
+ gr.Gallery(label="Imagenette", preview=False, value=sample_imagenette(), height=420)
279
+
280
+ gr.Markdown('''<hr/>''')
281
+
282
+ gr.Markdown('''<p style="text-align: justify; font-size: 18px">ℹ️ Now as a responsible AI expert, you wish to assert that your model is not vulnerable to
283
+ attacks which might manipulate the prediction. For instance, fish become classified as dogs or golf balls. To do this, you will deploy
284
+ a backdoor poisoning attack against your own model and assess its performance.</p>''')
285
+
286
+ with gr.Row(elem_classes="custom-text"):
287
+ with gr.Column(scale=1):
288
+ attack = gr.Textbox(visible=True, value="Backdoor", label="Attack", interactive=False)
289
+ target_class = gr.Radio(label="Target class", info="The class you wish to force the model to predict.",
290
+ choices=['dog',
291
+ 'cassette player',
292
+ 'chainsaw',
293
+ 'church',
294
+ 'french horn',
295
+ 'garbage truck',
296
+ 'gas pump',
297
+ 'golf ball',
298
+ 'parachutte',], value='dog')
299
+ eval_btn_patch = gr.Button("Evaluate")
300
+ with gr.Row(elem_classes="custom-text"):
301
+ with gr.Column(scale=10):
302
+ clean_gallery = gr.Gallery(label="Clean", preview=False, show_download_button=True)
303
+ clean_accuracy = gr.Number(label="Clean Accuracy", precision=2)
304
+ with gr.Column(scale=1, min_width='0px', elem_classes='symbols'):
305
+ gr.Markdown('''➕''')
306
+ with gr.Column(scale=5):
307
+ trigger_image = gr.Image(label="Trigger Image", value="./baby-on-board.png", interactive=False)
308
+ with gr.Column(scale=1, min_width='0px'):
309
+ gr.Markdown('''🟰''', elem_classes='symbols')
310
+ with gr.Column(scale=10):
311
+ poison_gallery = gr.Gallery(label="Poisoned", preview=False, show_download_button=True)
312
+ poison_success = gr.Number(label="Poison Success", precision=2)
313
+
314
+ eval_btn_patch.click(clf_poison_evaluate, inputs=[attack, trigger_image, target_class],
315
+ outputs=[clean_gallery, poison_gallery, clean_accuracy, poison_success])
316
+
317
+
318
+
319
+
320
+
321
+ gr.Markdown('''<br/>''')
322
+
323
+ if __name__ == "__main__":
324
+
325
+ # For development
326
+ demo.launch(show_api=False, debug=True, share=False,
327
+ server_name="0.0.0.0",
328
+ server_port=7777,
329
+ ssl_verify=False,
330
+ max_threads=20)
331
+
332
+ # For deployment
333
+ '''demo.launch(share=True, ssl_verify=False)'''
art_lfai.png ADDED
baby-on-board.png ADDED
carbon_colors.py ADDED
@@ -0,0 +1,173 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+
4
+ class Color:
5
+ all = []
6
+
7
+ def __init__(
8
+ self,
9
+ c50: str,
10
+ c100: str,
11
+ c200: str,
12
+ c300: str,
13
+ c400: str,
14
+ c500: str,
15
+ c600: str,
16
+ c700: str,
17
+ c800: str,
18
+ c900: str,
19
+ c950: str,
20
+ name: str | None = None,
21
+ ):
22
+ self.c50 = c50
23
+ self.c100 = c100
24
+ self.c200 = c200
25
+ self.c300 = c300
26
+ self.c400 = c400
27
+ self.c500 = c500
28
+ self.c600 = c600
29
+ self.c700 = c700
30
+ self.c800 = c800
31
+ self.c900 = c900
32
+ self.c950 = c950
33
+ self.name = name
34
+ Color.all.append(self)
35
+
36
+ def expand(self) -> list[str]:
37
+ return [
38
+ self.c50,
39
+ self.c100,
40
+ self.c200,
41
+ self.c300,
42
+ self.c400,
43
+ self.c500,
44
+ self.c600,
45
+ self.c700,
46
+ self.c800,
47
+ self.c900,
48
+ self.c950,
49
+ ]
50
+
51
+
52
+ black = Color(
53
+ name="black",
54
+ c50="#000000",
55
+ c100="#000000",
56
+ c200="#000000",
57
+ c300="#000000",
58
+ c400="#000000",
59
+ c500="#000000",
60
+ c600="#000000",
61
+ c700="#000000",
62
+ c800="#000000",
63
+ c900="#000000",
64
+ c950="#000000",
65
+ )
66
+
67
+ blackHover = Color(
68
+ name="blackHover",
69
+ c50="#212121",
70
+ c100="#212121",
71
+ c200="#212121",
72
+ c300="#212121",
73
+ c400="#212121",
74
+ c500="#212121",
75
+ c600="#212121",
76
+ c700="#212121",
77
+ c800="#212121",
78
+ c900="#212121",
79
+ c950="#212121",
80
+ )
81
+
82
+ white = Color(
83
+ name="white",
84
+ c50="#ffffff",
85
+ c100="#ffffff",
86
+ c200="#ffffff",
87
+ c300="#ffffff",
88
+ c400="#ffffff",
89
+ c500="#ffffff",
90
+ c600="#ffffff",
91
+ c700="#ffffff",
92
+ c800="#ffffff",
93
+ c900="#ffffff",
94
+ c950="#ffffff",
95
+ )
96
+
97
+ whiteHover = Color(
98
+ name="whiteHover",
99
+ c50="#e8e8e8",
100
+ c100="#e8e8e8",
101
+ c200="#e8e8e8",
102
+ c300="#e8e8e8",
103
+ c400="#e8e8e8",
104
+ c500="#e8e8e8",
105
+ c600="#e8e8e8",
106
+ c700="#e8e8e8",
107
+ c800="#e8e8e8",
108
+ c900="#e8e8e8",
109
+ c950="#e8e8e8",
110
+ )
111
+
112
+ red = Color(
113
+ name="red",
114
+ c50="#fff1f1",
115
+ c100="#ffd7d9",
116
+ c200="#ffb3b8",
117
+ c300="#ff8389",
118
+ c400="#fa4d56",
119
+ c500="#da1e28",
120
+ c600="#a2191f",
121
+ c700="#750e13",
122
+ c800="#520408",
123
+ c900="#2d0709",
124
+ c950="#2d0709",
125
+ )
126
+
127
+ redHover = Color(
128
+ name="redHover",
129
+ c50="#540d11",
130
+ c100="#66050a",
131
+ c200="#921118",
132
+ c300="#c21e25",
133
+ c400="#b81922",
134
+ c500="#ee0713",
135
+ c600="#ff6168",
136
+ c700="#ff99a0",
137
+ c800="#ffc2c5",
138
+ c900="#ffe0e0",
139
+ c950="#ffe0e0",
140
+ )
141
+
142
+ blue = Color(
143
+ name="blue",
144
+ c50="#edf5ff",
145
+ c100="#d0e2ff",
146
+ c200="#a6c8ff",
147
+ c300="#78a9ff",
148
+ c400="#4589ff",
149
+ c500="#0f62fe",
150
+ c600="#0043ce",
151
+ c700="#002d9c",
152
+ c800="#001d6c",
153
+ c900="#001141",
154
+ c950="#001141",
155
+ )
156
+
157
+ blueHover = Color(
158
+ name="blueHover",
159
+
160
+ c50="#001f75",
161
+ c100="#00258a",
162
+ c200="#0039c7",
163
+ c300="#0053ff",
164
+ c400="#0050e6",
165
+ c500="#1f70ff",
166
+ c600="#5c97ff",
167
+ c700="#8ab6ff",
168
+ c800="#b8d3ff",
169
+ c900="#dbebff",
170
+ c950="#dbebff",
171
+ )
172
+
173
+
carbon_theme.py ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+ from typing import Iterable
4
+
5
+ from gradio.themes.base import Base
6
+ from gradio.themes.utils import colors, fonts, sizes
7
+ import carbon_colors
8
+
9
+
10
+ class Carbon(Base):
11
+ def __init__(
12
+ self,
13
+ *,
14
+ primary_hue: carbon_colors.Color | str = carbon_colors.white,
15
+ secondary_hue: carbon_colors.Color | str = carbon_colors.red,
16
+ neutral_hue: carbon_colors.Color | str = carbon_colors.blue,
17
+ spacing_size: sizes.Size | str = sizes.spacing_lg,
18
+ radius_size: sizes.Size | str = sizes.radius_none,
19
+ text_size: sizes.Size | str = sizes.text_md,
20
+ font: fonts.Font
21
+ | str
22
+ | Iterable[fonts.Font | str] = (
23
+ fonts.GoogleFont("IBM Plex Mono"),
24
+ fonts.GoogleFont("IBM Plex Sans"),
25
+ fonts.GoogleFont("IBM Plex Serif"),
26
+ ),
27
+ font_mono: fonts.Font
28
+ | str
29
+ | Iterable[fonts.Font | str] = (
30
+ fonts.GoogleFont("IBM Plex Mono"),
31
+ ),
32
+ ):
33
+ super().__init__(
34
+ primary_hue=primary_hue,
35
+ secondary_hue=secondary_hue,
36
+ neutral_hue=neutral_hue,
37
+ spacing_size=spacing_size,
38
+ radius_size=radius_size,
39
+ text_size=text_size,
40
+ font=font,
41
+ font_mono=font_mono,
42
+ )
43
+ self.name = "carbon"
44
+ super().set(
45
+ # Colors
46
+ slider_color="*neutral_900",
47
+ slider_color_dark="*neutral_500",
48
+ body_text_color="*neutral_900",
49
+ block_label_text_color="*body_text_color",
50
+ block_title_text_color="*body_text_color",
51
+ body_text_color_subdued="*neutral_700",
52
+ background_fill_primary_dark="*neutral_900",
53
+ background_fill_secondary_dark="*neutral_800",
54
+ block_background_fill_dark="*neutral_800",
55
+ input_background_fill_dark="*neutral_700",
56
+ # Button Colors
57
+ button_primary_background_fill=carbon_colors.blue.c500,
58
+ button_primary_background_fill_hover="*neutral_300",
59
+ button_primary_text_color="white",
60
+ button_primary_background_fill_dark="*neutral_600",
61
+ button_primary_background_fill_hover_dark="*neutral_600",
62
+ button_primary_text_color_dark="white",
63
+ button_secondary_background_fill="*button_primary_background_fill",
64
+ button_secondary_background_fill_hover="*button_primary_background_fill_hover",
65
+ button_secondary_text_color="*button_primary_text_color",
66
+ button_cancel_background_fill="*button_primary_background_fill",
67
+ button_cancel_background_fill_hover="*button_primary_background_fill_hover",
68
+ button_cancel_text_color="*button_primary_text_color",
69
+ checkbox_background_color=carbon_colors.black.c50,
70
+ checkbox_label_background_fill="*button_primary_background_fill",
71
+ checkbox_label_background_fill_hover="*button_primary_background_fill_hover",
72
+ checkbox_label_text_color="*button_primary_text_color",
73
+ checkbox_background_color_selected=carbon_colors.black.c50,
74
+ checkbox_border_width="1px",
75
+ checkbox_border_width_dark="1px",
76
+ checkbox_border_color=carbon_colors.white.c50,
77
+ checkbox_border_color_dark=carbon_colors.white.c50,
78
+
79
+ checkbox_border_color_focus=carbon_colors.blue.c900,
80
+ checkbox_border_color_focus_dark=carbon_colors.blue.c900,
81
+ checkbox_border_color_selected=carbon_colors.white.c50,
82
+ checkbox_border_color_selected_dark=carbon_colors.white.c50,
83
+
84
+ checkbox_background_color_hover=carbon_colors.black.c50,
85
+ checkbox_background_color_hover_dark=carbon_colors.black.c50,
86
+ checkbox_background_color_dark=carbon_colors.black.c50,
87
+ checkbox_background_color_selected_dark=carbon_colors.black.c50,
88
+ # Padding
89
+ checkbox_label_padding="16px",
90
+ button_large_padding="*spacing_lg",
91
+ button_small_padding="*spacing_sm",
92
+ # Borders
93
+ block_border_width="0px",
94
+ block_border_width_dark="1px",
95
+ shadow_drop_lg="0 1px 4px 0 rgb(0 0 0 / 0.1)",
96
+ block_shadow="*shadow_drop_lg",
97
+ block_shadow_dark="none",
98
+ # Block Labels
99
+ block_title_text_weight="600",
100
+ block_label_text_weight="600",
101
+ block_label_text_size="*text_md",
102
+ )
data/imagenette2-320/noisy_imagenette.csv ADDED
The diff for this file is too large to render. See raw diff
 
data/imagenette2-320/train/n01440764/ILSVRC2012_val_00000293.JPEG ADDED
data/imagenette2-320/train/n01440764/ILSVRC2012_val_00002138.JPEG ADDED
data/imagenette2-320/train/n01440764/ILSVRC2012_val_00003014.JPEG ADDED
data/imagenette2-320/train/n01440764/ILSVRC2012_val_00006697.JPEG ADDED
data/imagenette2-320/train/n01440764/ILSVRC2012_val_00007197.JPEG ADDED
data/imagenette2-320/train/n01440764/ILSVRC2012_val_00009346.JPEG ADDED
data/imagenette2-320/train/n01440764/ILSVRC2012_val_00009379.JPEG ADDED
data/imagenette2-320/train/n01440764/ILSVRC2012_val_00009396.JPEG ADDED
data/imagenette2-320/train/n01440764/ILSVRC2012_val_00010306.JPEG ADDED
data/imagenette2-320/train/n01440764/ILSVRC2012_val_00011233.JPEG ADDED
data/imagenette2-320/train/n02102040/ILSVRC2012_val_00000665.JPEG ADDED
data/imagenette2-320/train/n02102040/ILSVRC2012_val_00001968.JPEG ADDED
data/imagenette2-320/train/n02102040/ILSVRC2012_val_00002294.JPEG ADDED
data/imagenette2-320/train/n02102040/ILSVRC2012_val_00002315.JPEG ADDED
data/imagenette2-320/train/n02102040/ILSVRC2012_val_00004548.JPEG ADDED
data/imagenette2-320/train/n02102040/ILSVRC2012_val_00004553.JPEG ADDED
data/imagenette2-320/train/n02102040/ILSVRC2012_val_00007568.JPEG ADDED
data/imagenette2-320/train/n02102040/ILSVRC2012_val_00008334.JPEG ADDED
data/imagenette2-320/train/n02102040/ILSVRC2012_val_00010994.JPEG ADDED
data/imagenette2-320/train/n02102040/ILSVRC2012_val_00012689.JPEG ADDED
data/imagenette2-320/train/n02102040/ILSVRC2012_val_00014125.JPEG ADDED
data/imagenette2-320/train/n02979186/ILSVRC2012_val_00000557.JPEG ADDED
data/imagenette2-320/train/n02979186/ILSVRC2012_val_00002034.JPEG ADDED
data/imagenette2-320/train/n02979186/ILSVRC2012_val_00003944.JPEG ADDED
data/imagenette2-320/train/n02979186/ILSVRC2012_val_00005866.JPEG ADDED
data/imagenette2-320/train/n02979186/ILSVRC2012_val_00006787.JPEG ADDED
data/imagenette2-320/train/n02979186/ILSVRC2012_val_00007226.JPEG ADDED
data/imagenette2-320/train/n02979186/ILSVRC2012_val_00009404.JPEG ADDED
data/imagenette2-320/train/n02979186/ILSVRC2012_val_00009833.JPEG ADDED
data/imagenette2-320/train/n02979186/ILSVRC2012_val_00012468.JPEG ADDED
data/imagenette2-320/train/n02979186/ILSVRC2012_val_00013735.JPEG ADDED
data/imagenette2-320/train/n02979186/ILSVRC2012_val_00014287.JPEG ADDED
data/imagenette2-320/train/n03000684/ILSVRC2012_val_00000537.JPEG ADDED
data/imagenette2-320/train/n03000684/ILSVRC2012_val_00004034.JPEG ADDED
data/imagenette2-320/train/n03000684/ILSVRC2012_val_00005506.JPEG ADDED
data/imagenette2-320/train/n03000684/ILSVRC2012_val_00006043.JPEG ADDED
data/imagenette2-320/train/n03000684/ILSVRC2012_val_00006578.JPEG ADDED
data/imagenette2-320/train/n03000684/ILSVRC2012_val_00006669.JPEG ADDED
data/imagenette2-320/train/n03000684/ILSVRC2012_val_00006726.JPEG ADDED
data/imagenette2-320/train/n03000684/ILSVRC2012_val_00009206.JPEG ADDED
data/imagenette2-320/train/n03000684/ILSVRC2012_val_00017719.JPEG ADDED
data/imagenette2-320/train/n03000684/ILSVRC2012_val_00019137.JPEG ADDED