├── Adversarial_Examples_EfficientNet_AdvProp.ipynb
├── Adversarial_Examples_EfficientNet_NST.ipynb
├── Adversarial_Training_NSL.ipynb
├── Adversarial_Training_NSL_NST.ipynb
├── GANs_w_Adversaries.ipynb
├── Image_Adversaries_Basics.ipynb
├── Optimizer_Susceptibility.ipynb
├── Optimizer_Susceptibility_Targeted_Attacks.ipynb
└── README.md
/GANs_w_Adversaries.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "nbformat": 4,
3 | "nbformat_minor": 0,
4 | "metadata": {
5 | "colab": {
6 | "name": "GANs_w_Adversaries.ipynb",
7 | "provenance": [],
8 | "collapsed_sections": [],
9 | "authorship_tag": "ABX9TyPzL9ozeev9OckSAqDJDlEu",
10 | "include_colab_link": true
11 | },
12 | "kernelspec": {
13 | "name": "python3",
14 | "display_name": "Python 3"
15 | },
16 | "accelerator": "GPU"
17 | },
18 | "cells": [
19 | {
20 | "cell_type": "markdown",
21 | "metadata": {
22 | "id": "view-in-github",
23 | "colab_type": "text"
24 | },
25 | "source": [
26 | " "
27 | ]
28 | },
29 | {
30 | "cell_type": "code",
31 | "metadata": {
32 | "id": "evdgWJ1M6k1Q",
33 | "colab_type": "code",
34 | "colab": {
35 | "base_uri": "https://localhost:8080/",
36 | "height": 34
37 | },
38 | "outputId": "6d7f9843-e2ee-4f37-d3fd-1dcfd7b11030"
39 | },
40 | "source": [
41 | "# Import TensorFlow as verify the version\n",
42 | "import tensorflow as tf\n",
43 | "print(tf.__version__)"
44 | ],
45 | "execution_count": 1,
46 | "outputs": [
47 | {
48 | "output_type": "stream",
49 | "text": [
50 | "2.2.0-rc3\n"
51 | ],
52 | "name": "stdout"
53 | }
54 | ]
55 | },
56 | {
57 | "cell_type": "code",
58 | "metadata": {
59 | "id": "pZgEZWIj6zfz",
60 | "colab_type": "code",
61 | "outputId": "75dc5438-9f81-4077-d613-073d9e5f06f8",
62 | "colab": {
63 | "base_uri": "https://localhost:8080/",
64 | "height": 306
65 | }
66 | },
67 | "source": [
68 | "# Which GPU?\n",
69 | "!nvidia-smi"
70 | ],
71 | "execution_count": 2,
72 | "outputs": [
73 | {
74 | "output_type": "stream",
75 | "text": [
76 | "Fri Apr 17 13:39:47 2020 \n",
77 | "+-----------------------------------------------------------------------------+\n",
78 | "| NVIDIA-SMI 440.64.00 Driver Version: 418.67 CUDA Version: 10.1 |\n",
79 | "|-------------------------------+----------------------+----------------------+\n",
80 | "| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |\n",
81 | "| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |\n",
82 | "|===============================+======================+======================|\n",
83 | "| 0 Tesla P100-PCIE... Off | 00000000:00:04.0 Off | 0 |\n",
84 | "| N/A 43C P0 30W / 250W | 0MiB / 16280MiB | 0% Default |\n",
85 | "+-------------------------------+----------------------+----------------------+\n",
86 | " \n",
87 | "+-----------------------------------------------------------------------------+\n",
88 | "| Processes: GPU Memory |\n",
89 | "| GPU PID Type Process name Usage |\n",
90 | "|=============================================================================|\n",
91 | "| No running processes found |\n",
92 | "+-----------------------------------------------------------------------------+\n"
93 | ],
94 | "name": "stdout"
95 | }
96 | ]
97 | },
98 | {
99 | "cell_type": "code",
100 | "metadata": {
101 | "id": "IL7QdHbH7ptO",
102 | "colab_type": "code",
103 | "colab": {}
104 | },
105 | "source": [
106 | "# Other imports\n",
107 | "from tensorflow.keras.layers import *\n",
108 | "from tensorflow.keras.models import *\n",
109 | "from imutils import build_montages\n",
110 | "from sklearn.utils import shuffle \n",
111 | "from tqdm import tqdm\n",
112 | "import matplotlib.pyplot as plt\n",
113 | "import numpy as np\n",
114 | "import cv2"
115 | ],
116 | "execution_count": 0,
117 | "outputs": []
118 | },
119 | {
120 | "cell_type": "code",
121 | "metadata": {
122 | "id": "tOxVL1Qz61pZ",
123 | "colab_type": "code",
124 | "outputId": "8016147d-2396-478e-ff3c-a0bfdb7f3957",
125 | "colab": {
126 | "base_uri": "https://localhost:8080/",
127 | "height": 170
128 | }
129 | },
130 | "source": [
131 | "# Load data\n",
132 | "((X_train, _), (X_test, _)) = tf.keras.datasets.fashion_mnist.load_data()\n",
133 | "X_train.shape, X_test.shape"
134 | ],
135 | "execution_count": 4,
136 | "outputs": [
137 | {
138 | "output_type": "stream",
139 | "text": [
140 | "Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/train-labels-idx1-ubyte.gz\n",
141 | "32768/29515 [=================================] - 0s 0us/step\n",
142 | "Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/train-images-idx3-ubyte.gz\n",
143 | "26427392/26421880 [==============================] - 0s 0us/step\n",
144 | "Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/t10k-labels-idx1-ubyte.gz\n",
145 | "8192/5148 [===============================================] - 0s 0us/step\n",
146 | "Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/t10k-images-idx3-ubyte.gz\n",
147 | "4423680/4422102 [==============================] - 0s 0us/step\n"
148 | ],
149 | "name": "stdout"
150 | },
151 | {
152 | "output_type": "execute_result",
153 | "data": {
154 | "text/plain": [
155 | "((60000, 28, 28), (10000, 28, 28))"
156 | ]
157 | },
158 | "metadata": {
159 | "tags": []
160 | },
161 | "execution_count": 4
162 | }
163 | ]
164 | },
165 | {
166 | "cell_type": "code",
167 | "metadata": {
168 | "id": "SzylG4pp7CoC",
169 | "colab_type": "code",
170 | "colab": {}
171 | },
172 | "source": [
173 | "# Add a channel dimension so that it is compatible with Conv2D\n",
174 | "X_train = X_train.reshape(-1, 28, 28, 1)\n",
175 | "X_test = X_test.reshape(-1, 28, 28, 1)"
176 | ],
177 | "execution_count": 0,
178 | "outputs": []
179 | },
180 | {
181 | "cell_type": "code",
182 | "metadata": {
183 | "id": "LW9QNjXw7J9n",
184 | "colab_type": "code",
185 | "colab": {}
186 | },
187 | "source": [
188 | "# Combine the train and test images and scale the the image pixel values to [-1, 1]\n",
189 | "trainImages = np.concatenate([X_train, X_test])\n",
190 | "trainImages = (trainImages.astype(\"float\") - 127.5) / 127.5"
191 | ],
192 | "execution_count": 0,
193 | "outputs": []
194 | },
195 | {
196 | "cell_type": "code",
197 | "metadata": {
198 | "id": "tXPxzNQL7l8K",
199 | "colab_type": "code",
200 | "colab": {}
201 | },
202 | "source": [
203 | "# Define the Hyperparameters\n",
204 | "latent_dim = 100\n",
205 | "height = 28\n",
206 | "width = 28\n",
207 | "nb_channels = 1"
208 | ],
209 | "execution_count": 0,
210 | "outputs": []
211 | },
212 | {
213 | "cell_type": "code",
214 | "metadata": {
215 | "id": "G4I6oLeX7xVa",
216 | "colab_type": "code",
217 | "colab": {}
218 | },
219 | "source": [
220 | "# Generator\n",
221 | "def generator_network():\n",
222 | " generator = Sequential()\n",
223 | " inputShape = (7, 7, 64)\n",
224 | " chanDim = -1\n",
225 | "\n",
226 | " generator.add(Dense(input_dim=latent_dim, units=512))\n",
227 | " generator.add(LeakyReLU())\n",
228 | " generator.add(BatchNormalization())\n",
229 | "\n",
230 | " generator.add(Dense(7 * 7 * 64))\n",
231 | " generator.add(LeakyReLU())\n",
232 | " generator.add(BatchNormalization())\n",
233 | "\n",
234 | " generator.add(Reshape(inputShape))\n",
235 | " generator.add(Conv2DTranspose(32, (5, 5), strides=(2, 2),\n",
236 | " padding=\"same\"))\n",
237 | " generator.add((LeakyReLU()))\n",
238 | " generator.add(BatchNormalization(axis=chanDim))\n",
239 | "\n",
240 | " generator.add(Conv2DTranspose(nb_channels, (5, 5), strides=(2, 2),\n",
241 | " padding=\"same\", activation=\"tanh\"))\n",
242 | "\n",
243 | " return generator"
244 | ],
245 | "execution_count": 0,
246 | "outputs": []
247 | },
248 | {
249 | "cell_type": "code",
250 | "metadata": {
251 | "id": "d5B5vEWY7y5M",
252 | "colab_type": "code",
253 | "outputId": "65836cdc-7c24-4ea5-9351-0fe4ea4c1e56",
254 | "colab": {
255 | "base_uri": "https://localhost:8080/",
256 | "height": 527
257 | }
258 | },
259 | "source": [
260 | "# Instantiate the Generator network\n",
261 | "generator = generator_network()\n",
262 | "generator.summary()"
263 | ],
264 | "execution_count": 9,
265 | "outputs": [
266 | {
267 | "output_type": "stream",
268 | "text": [
269 | "Model: \"sequential\"\n",
270 | "_________________________________________________________________\n",
271 | "Layer (type) Output Shape Param # \n",
272 | "=================================================================\n",
273 | "dense (Dense) (None, 512) 51712 \n",
274 | "_________________________________________________________________\n",
275 | "leaky_re_lu (LeakyReLU) (None, 512) 0 \n",
276 | "_________________________________________________________________\n",
277 | "batch_normalization (BatchNo (None, 512) 2048 \n",
278 | "_________________________________________________________________\n",
279 | "dense_1 (Dense) (None, 3136) 1608768 \n",
280 | "_________________________________________________________________\n",
281 | "leaky_re_lu_1 (LeakyReLU) (None, 3136) 0 \n",
282 | "_________________________________________________________________\n",
283 | "batch_normalization_1 (Batch (None, 3136) 12544 \n",
284 | "_________________________________________________________________\n",
285 | "reshape (Reshape) (None, 7, 7, 64) 0 \n",
286 | "_________________________________________________________________\n",
287 | "conv2d_transpose (Conv2DTran (None, 14, 14, 32) 51232 \n",
288 | "_________________________________________________________________\n",
289 | "leaky_re_lu_2 (LeakyReLU) (None, 14, 14, 32) 0 \n",
290 | "_________________________________________________________________\n",
291 | "batch_normalization_2 (Batch (None, 14, 14, 32) 128 \n",
292 | "_________________________________________________________________\n",
293 | "conv2d_transpose_1 (Conv2DTr (None, 28, 28, 1) 801 \n",
294 | "=================================================================\n",
295 | "Total params: 1,727,233\n",
296 | "Trainable params: 1,719,873\n",
297 | "Non-trainable params: 7,360\n",
298 | "_________________________________________________________________\n"
299 | ],
300 | "name": "stdout"
301 | }
302 | ]
303 | },
304 | {
305 | "cell_type": "code",
306 | "metadata": {
307 | "id": "pDZxoMb58IpK",
308 | "colab_type": "code",
309 | "colab": {}
310 | },
311 | "source": [
312 | "# Discriminator\n",
313 | "def disc_network():\n",
314 | " disc = Sequential()\n",
315 | " inputShape = (height, width, nb_channels)\n",
316 | "\n",
317 | " disc.add(Conv2D(32, (5, 5), padding=\"same\", strides=(2, 2),\n",
318 | " input_shape=inputShape))\n",
319 | " disc.add(LeakyReLU(alpha=0.2))\n",
320 | "\n",
321 | " disc.add(Conv2D(64, (5, 5), padding=\"same\", strides=(2, 2)))\n",
322 | " disc.add(LeakyReLU(alpha=0.2))\n",
323 | "\n",
324 | " disc.add(Flatten())\n",
325 | " disc.add(Dense(512))\n",
326 | " disc.add(LeakyReLU(alpha=0.2))\n",
327 | " disc.add(Dropout(0.3))\n",
328 | " disc.add(Dense(1))\n",
329 | " disc.add(Activation(\"sigmoid\"))\n",
330 | " \n",
331 | " return disc"
332 | ],
333 | "execution_count": 0,
334 | "outputs": []
335 | },
336 | {
337 | "cell_type": "code",
338 | "metadata": {
339 | "id": "0sGntIQF8XjR",
340 | "colab_type": "code",
341 | "outputId": "c1878583-1da7-43ed-bdce-548c68f4093e",
342 | "colab": {
343 | "base_uri": "https://localhost:8080/",
344 | "height": 493
345 | }
346 | },
347 | "source": [
348 | "# Instantiate the Discriminator network\n",
349 | "disc = disc_network()\n",
350 | "disc.summary()"
351 | ],
352 | "execution_count": 11,
353 | "outputs": [
354 | {
355 | "output_type": "stream",
356 | "text": [
357 | "Model: \"sequential_1\"\n",
358 | "_________________________________________________________________\n",
359 | "Layer (type) Output Shape Param # \n",
360 | "=================================================================\n",
361 | "conv2d (Conv2D) (None, 14, 14, 32) 832 \n",
362 | "_________________________________________________________________\n",
363 | "leaky_re_lu_3 (LeakyReLU) (None, 14, 14, 32) 0 \n",
364 | "_________________________________________________________________\n",
365 | "conv2d_1 (Conv2D) (None, 7, 7, 64) 51264 \n",
366 | "_________________________________________________________________\n",
367 | "leaky_re_lu_4 (LeakyReLU) (None, 7, 7, 64) 0 \n",
368 | "_________________________________________________________________\n",
369 | "flatten (Flatten) (None, 3136) 0 \n",
370 | "_________________________________________________________________\n",
371 | "dense_2 (Dense) (None, 512) 1606144 \n",
372 | "_________________________________________________________________\n",
373 | "leaky_re_lu_5 (LeakyReLU) (None, 512) 0 \n",
374 | "_________________________________________________________________\n",
375 | "dropout (Dropout) (None, 512) 0 \n",
376 | "_________________________________________________________________\n",
377 | "dense_3 (Dense) (None, 1) 513 \n",
378 | "_________________________________________________________________\n",
379 | "activation (Activation) (None, 1) 0 \n",
380 | "=================================================================\n",
381 | "Total params: 1,658,753\n",
382 | "Trainable params: 1,658,753\n",
383 | "Non-trainable params: 0\n",
384 | "_________________________________________________________________\n"
385 | ],
386 | "name": "stdout"
387 | }
388 | ]
389 | },
390 | {
391 | "cell_type": "code",
392 | "metadata": {
393 | "id": "Hxuad7i28dUr",
394 | "colab_type": "code",
395 | "colab": {}
396 | },
397 | "source": [
398 | "# Optimizer for the Disc\n",
399 | "disc_opt = tf.keras.optimizers.RMSprop(lr=0.0008, clipvalue=1.0, decay=1e-8)\n",
400 | "disc.compile(optimizer=disc_opt, loss=\"binary_crossentropy\")"
401 | ],
402 | "execution_count": 0,
403 | "outputs": []
404 | },
405 | {
406 | "cell_type": "code",
407 | "metadata": {
408 | "id": "1Nrlh3Tw8hJq",
409 | "colab_type": "code",
410 | "colab": {}
411 | },
412 | "source": [
413 | "# GAN\n",
414 | "disc.trainable = False\n",
415 | "gan_input = Input(shape=(latent_dim, ))\n",
416 | "gan_output = disc(generator(gan_input))\n",
417 | "gan = Model(gan_input, gan_output)\n",
418 | "\n",
419 | "gan_opt = tf.keras.optimizers.RMSprop(lr=0.0008, clipvalue=1.0, decay=1e-8)\n",
420 | "gan.compile(loss=\"binary_crossentropy\", optimizer=gan_opt)"
421 | ],
422 | "execution_count": 0,
423 | "outputs": []
424 | },
425 | {
426 | "cell_type": "code",
427 | "metadata": {
428 | "id": "9m5MrmSt8m2I",
429 | "colab_type": "code",
430 | "outputId": "748200ae-3b8b-4a25-aab2-49f6bb7b0c89",
431 | "colab": {
432 | "base_uri": "https://localhost:8080/",
433 | "height": 255
434 | }
435 | },
436 | "source": [
437 | "# Summary of the GAN architecture\n",
438 | "gan.summary()"
439 | ],
440 | "execution_count": 14,
441 | "outputs": [
442 | {
443 | "output_type": "stream",
444 | "text": [
445 | "Model: \"model\"\n",
446 | "_________________________________________________________________\n",
447 | "Layer (type) Output Shape Param # \n",
448 | "=================================================================\n",
449 | "input_1 (InputLayer) [(None, 100)] 0 \n",
450 | "_________________________________________________________________\n",
451 | "sequential (Sequential) (None, 28, 28, 1) 1727233 \n",
452 | "_________________________________________________________________\n",
453 | "sequential_1 (Sequential) (None, 1) 1658753 \n",
454 | "=================================================================\n",
455 | "Total params: 3,385,986\n",
456 | "Trainable params: 1,719,873\n",
457 | "Non-trainable params: 1,666,113\n",
458 | "_________________________________________________________________\n"
459 | ],
460 | "name": "stdout"
461 | }
462 | ]
463 | },
464 | {
465 | "cell_type": "code",
466 | "metadata": {
467 | "id": "-v6L5Zv48yh2",
468 | "colab_type": "code",
469 | "colab": {}
470 | },
471 | "source": [
472 | "# More hyperparameters\n",
473 | "epochs = 10000\n",
474 | "batch_size = 20"
475 | ],
476 | "execution_count": 0,
477 | "outputs": []
478 | },
479 | {
480 | "cell_type": "code",
481 | "metadata": {
482 | "id": "M1OMjLS581nQ",
483 | "colab_type": "code",
484 | "outputId": "83c9e1d7-73ac-40c7-a657-e5b09ed9ac3d",
485 | "colab": {
486 | "base_uri": "https://localhost:8080/",
487 | "height": 374
488 | }
489 | },
490 | "source": [
491 | "# Start training\n",
492 | "################\n",
493 | "start = 0\n",
494 | "for epoch in tqdm(range(epochs)):\n",
495 | " # Sample random noise from a normal distribution\n",
496 | " benchmark_noise = np.random.normal(size=(batch_size, latent_dim))\n",
497 | " # Map this noise to images via the generator network\n",
498 | " generated_images = generator.predict(benchmark_noise)\n",
499 | " \n",
500 | " # Calculate where to stop the current epoch, segregate the current batch\n",
501 | " # of real images and combine them with the fake ones\n",
502 | " stop = start + batch_size\n",
503 | " real_images = trainImages[start:stop]\n",
504 | " combined_images = np.concatenate([generated_images, real_images])\n",
505 | " \n",
506 | " # 1 -> Fake images, 0 -> Real images\n",
507 | " # Add a bit of random noise to the labels\n",
508 | " labels = np.array(([1] * batch_size) + ([0] * batch_size)).astype(\"float\")\n",
509 | " labels += 0.05 * np.random.random(labels.shape)\n",
510 | " \n",
511 | " # Shuffle the datapoints of the newly created dataset\n",
512 | " (combined_images, labels) = shuffle(combined_images, labels)\n",
513 | " \n",
514 | " # Train the discriminator on these new dataset\n",
515 | " d_loss = disc.train_on_batch(combined_images, labels)\n",
516 | " \n",
517 | " # Again sample random noise from a normal distribution &\n",
518 | " # set the labels to such that they resemble real images to fool\n",
519 | " # discriminator\n",
520 | " random_latent_vectors = np.random.normal(size=(batch_size, latent_dim))\n",
521 | " fake_labels = np.array([0] * batch_size)\n",
522 | " \n",
523 | " # Train the GAN with this random noise and fake labels, but only\n",
524 | " # update the weights of generator\n",
525 | " a_loss = gan.train_on_batch(random_latent_vectors, fake_labels)\n",
526 | " \n",
527 | " # Set the next batch\n",
528 | " start += batch_size\n",
529 | " if start > len(trainImages) - batch_size:\n",
530 | " start = 0\n",
531 | " \n",
532 | " # Logging\n",
533 | " if epoch % 500 == 0:\n",
534 | " print(f\"Step: {epoch} Disc Loss: {d_loss} Adv Loss: {a_loss}\")\n",
535 | " images = ((generated_images * 127.5) + 127.5).astype(\"int\")\n",
536 | " images = np.repeat(images, 3, axis=-1)\n",
537 | " vis = build_montages(images, (28, 28), (4, 5))[0]\n",
538 | " cv2.imwrite(\"vis\" + str(epoch) + \".png\", vis)"
539 | ],
540 | "execution_count": 16,
541 | "outputs": [
542 | {
543 | "output_type": "stream",
544 | "text": [
545 | " 0%| | 3/10000 [00:08<17:03:54, 6.15s/it]"
546 | ],
547 | "name": "stderr"
548 | },
549 | {
550 | "output_type": "stream",
551 | "text": [
552 | "Step: 0 Disc Loss: 0.687881350517273 Adv Loss: 0.14508673548698425\n"
553 | ],
554 | "name": "stdout"
555 | },
556 | {
557 | "output_type": "stream",
558 | "text": [
559 | " 5%|▌ | 503/10000 [00:33<07:38, 20.73it/s]"
560 | ],
561 | "name": "stderr"
562 | },
563 | {
564 | "output_type": "stream",
565 | "text": [
566 | "Step: 500 Disc Loss: 0.47640880942344666 Adv Loss: 1.350799798965454\n"
567 | ],
568 | "name": "stdout"
569 | },
570 | {
571 | "output_type": "stream",
572 | "text": [
573 | " 10%|█ | 1003/10000 [00:57<07:16, 20.63it/s]"
574 | ],
575 | "name": "stderr"
576 | },
577 | {
578 | "output_type": "stream",
579 | "text": [
580 | "Step: 1000 Disc Loss: 0.49821704626083374 Adv Loss: 1.7119624614715576\n"
581 | ],
582 | "name": "stdout"
583 | },
584 | {
585 | "output_type": "stream",
586 | "text": [
587 | " 15%|█▌ | 1504/10000 [01:21<07:10, 19.76it/s]"
588 | ],
589 | "name": "stderr"
590 | },
591 | {
592 | "output_type": "stream",
593 | "text": [
594 | "Step: 1500 Disc Loss: 0.49107104539871216 Adv Loss: 1.8809871673583984\n"
595 | ],
596 | "name": "stdout"
597 | },
598 | {
599 | "output_type": "stream",
600 | "text": [
601 | " 20%|██ | 2003/10000 [01:46<06:39, 20.03it/s]"
602 | ],
603 | "name": "stderr"
604 | },
605 | {
606 | "output_type": "stream",
607 | "text": [
608 | "Step: 2000 Disc Loss: 0.536552906036377 Adv Loss: 2.172856569290161\n"
609 | ],
610 | "name": "stdout"
611 | },
612 | {
613 | "output_type": "stream",
614 | "text": [
615 | " 25%|██▌ | 2503/10000 [02:10<06:07, 20.42it/s]"
616 | ],
617 | "name": "stderr"
618 | },
619 | {
620 | "output_type": "stream",
621 | "text": [
622 | "Step: 2500 Disc Loss: 0.2591400444507599 Adv Loss: 2.582822561264038\n"
623 | ],
624 | "name": "stdout"
625 | },
626 | {
627 | "output_type": "stream",
628 | "text": [
629 | " 30%|███ | 3004/10000 [02:34<05:43, 20.37it/s]"
630 | ],
631 | "name": "stderr"
632 | },
633 | {
634 | "output_type": "stream",
635 | "text": [
636 | "Step: 3000 Disc Loss: 0.4406290054321289 Adv Loss: 2.676551342010498\n"
637 | ],
638 | "name": "stdout"
639 | },
640 | {
641 | "output_type": "stream",
642 | "text": [
643 | " 35%|███▌ | 3503/10000 [02:59<05:14, 20.67it/s]"
644 | ],
645 | "name": "stderr"
646 | },
647 | {
648 | "output_type": "stream",
649 | "text": [
650 | "Step: 3500 Disc Loss: 0.28072601556777954 Adv Loss: 2.271653413772583\n"
651 | ],
652 | "name": "stdout"
653 | },
654 | {
655 | "output_type": "stream",
656 | "text": [
657 | " 40%|████ | 4004/10000 [03:24<04:51, 20.54it/s]"
658 | ],
659 | "name": "stderr"
660 | },
661 | {
662 | "output_type": "stream",
663 | "text": [
664 | "Step: 4000 Disc Loss: 0.4415341317653656 Adv Loss: 2.348633050918579\n"
665 | ],
666 | "name": "stdout"
667 | },
668 | {
669 | "output_type": "stream",
670 | "text": [
671 | " 45%|████▌ | 4505/10000 [03:48<04:24, 20.80it/s]"
672 | ],
673 | "name": "stderr"
674 | },
675 | {
676 | "output_type": "stream",
677 | "text": [
678 | "Step: 4500 Disc Loss: 0.3864983022212982 Adv Loss: 1.804436445236206\n"
679 | ],
680 | "name": "stdout"
681 | },
682 | {
683 | "output_type": "stream",
684 | "text": [
685 | " 50%|█████ | 5004/10000 [04:12<04:02, 20.63it/s]"
686 | ],
687 | "name": "stderr"
688 | },
689 | {
690 | "output_type": "stream",
691 | "text": [
692 | "Step: 5000 Disc Loss: 0.25370922684669495 Adv Loss: 2.260925054550171\n"
693 | ],
694 | "name": "stdout"
695 | },
696 | {
697 | "output_type": "stream",
698 | "text": [
699 | " 55%|█████▌ | 5504/10000 [04:37<03:38, 20.59it/s]"
700 | ],
701 | "name": "stderr"
702 | },
703 | {
704 | "output_type": "stream",
705 | "text": [
706 | "Step: 5500 Disc Loss: 0.4161396622657776 Adv Loss: 1.7695811986923218\n"
707 | ],
708 | "name": "stdout"
709 | },
710 | {
711 | "output_type": "stream",
712 | "text": [
713 | " 60%|██████ | 6002/10000 [05:01<03:32, 18.82it/s]"
714 | ],
715 | "name": "stderr"
716 | },
717 | {
718 | "output_type": "stream",
719 | "text": [
720 | "Step: 6000 Disc Loss: 0.40372294187545776 Adv Loss: 2.133988618850708\n"
721 | ],
722 | "name": "stdout"
723 | },
724 | {
725 | "output_type": "stream",
726 | "text": [
727 | " 65%|██████▌ | 6502/10000 [05:26<02:46, 21.03it/s]"
728 | ],
729 | "name": "stderr"
730 | },
731 | {
732 | "output_type": "stream",
733 | "text": [
734 | "Step: 6500 Disc Loss: 0.3453351855278015 Adv Loss: 1.365769863128662\n"
735 | ],
736 | "name": "stdout"
737 | },
738 | {
739 | "output_type": "stream",
740 | "text": [
741 | " 70%|███████ | 7003/10000 [05:51<02:22, 20.99it/s]"
742 | ],
743 | "name": "stderr"
744 | },
745 | {
746 | "output_type": "stream",
747 | "text": [
748 | "Step: 7000 Disc Loss: 0.3185539245605469 Adv Loss: 2.548447608947754\n"
749 | ],
750 | "name": "stdout"
751 | },
752 | {
753 | "output_type": "stream",
754 | "text": [
755 | " 75%|███████▌ | 7505/10000 [06:15<02:02, 20.36it/s]"
756 | ],
757 | "name": "stderr"
758 | },
759 | {
760 | "output_type": "stream",
761 | "text": [
762 | "Step: 7500 Disc Loss: 0.2985878586769104 Adv Loss: 2.064674139022827\n"
763 | ],
764 | "name": "stdout"
765 | },
766 | {
767 | "output_type": "stream",
768 | "text": [
769 | " 80%|████████ | 8004/10000 [06:40<01:38, 20.28it/s]"
770 | ],
771 | "name": "stderr"
772 | },
773 | {
774 | "output_type": "stream",
775 | "text": [
776 | "Step: 8000 Disc Loss: 0.42655688524246216 Adv Loss: 1.4810914993286133\n"
777 | ],
778 | "name": "stdout"
779 | },
780 | {
781 | "output_type": "stream",
782 | "text": [
783 | " 85%|████████▌ | 8503/10000 [07:04<01:13, 20.34it/s]"
784 | ],
785 | "name": "stderr"
786 | },
787 | {
788 | "output_type": "stream",
789 | "text": [
790 | "Step: 8500 Disc Loss: 0.52017742395401 Adv Loss: 1.9420932531356812\n"
791 | ],
792 | "name": "stdout"
793 | },
794 | {
795 | "output_type": "stream",
796 | "text": [
797 | " 90%|█████████ | 9004/10000 [07:28<00:49, 20.22it/s]"
798 | ],
799 | "name": "stderr"
800 | },
801 | {
802 | "output_type": "stream",
803 | "text": [
804 | "Step: 9000 Disc Loss: 0.5068351030349731 Adv Loss: 2.759629011154175\n"
805 | ],
806 | "name": "stdout"
807 | },
808 | {
809 | "output_type": "stream",
810 | "text": [
811 | " 95%|█████████▌| 9503/10000 [07:53<00:24, 20.39it/s]"
812 | ],
813 | "name": "stderr"
814 | },
815 | {
816 | "output_type": "stream",
817 | "text": [
818 | "Step: 9500 Disc Loss: 0.4068868160247803 Adv Loss: 2.576944351196289\n"
819 | ],
820 | "name": "stdout"
821 | },
822 | {
823 | "output_type": "stream",
824 | "text": [
825 | "100%|██████████| 10000/10000 [08:17<00:00, 20.08it/s]\n"
826 | ],
827 | "name": "stderr"
828 | }
829 | ]
830 | },
831 | {
832 | "cell_type": "markdown",
833 | "metadata": {
834 | "id": "PE6PpKI-9n-d",
835 | "colab_type": "text"
836 | },
837 | "source": [
838 | "## Generate images using the trained generator from random noise"
839 | ]
840 | },
841 | {
842 | "cell_type": "code",
843 | "metadata": {
844 | "id": "uHQaTTWv-0oQ",
845 | "colab_type": "code",
846 | "outputId": "67f2323a-8fa1-45bb-882d-c2c181cf9837",
847 | "colab": {
848 | "base_uri": "https://localhost:8080/",
849 | "height": 34
850 | }
851 | },
852 | "source": [
853 | "# Sample random noise from a normal distribution\n",
854 | "benchmark_noise = np.random.normal(size=(batch_size, latent_dim))\n",
855 | "# Map this noise to images via the generator network\n",
856 | "generated_images = generator.predict(benchmark_noise)\n",
857 | "# Scale back\n",
858 | "images = ((generated_images * 127.5) + 127.5).astype(\"int\")\n",
859 | "images.shape"
860 | ],
861 | "execution_count": 17,
862 | "outputs": [
863 | {
864 | "output_type": "execute_result",
865 | "data": {
866 | "text/plain": [
867 | "(20, 28, 28, 1)"
868 | ]
869 | },
870 | "metadata": {
871 | "tags": []
872 | },
873 | "execution_count": 17
874 | }
875 | ]
876 | },
877 | {
878 | "cell_type": "code",
879 | "metadata": {
880 | "id": "mofASNk8_EFA",
881 | "colab_type": "code",
882 | "outputId": "b01c837c-4c52-44da-fccb-ed539e9e661a",
883 | "colab": {
884 | "base_uri": "https://localhost:8080/",
885 | "height": 265
886 | }
887 | },
888 | "source": [
889 | "# How do the images look like?\n",
890 | "random_idx = np.random.choice(images.shape[0], 1)\n",
891 | "image_1 = images[random_idx].reshape(28, 28)\n",
892 | "plt.imshow(image_1, cmap=plt.cm.binary)\n",
893 | "plt.show()"
894 | ],
895 | "execution_count": 20,
896 | "outputs": [
897 | {
898 | "output_type": "display_data",
899 | "data": {
900 | "image/png": "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\n",
901 | "text/plain": [
902 | ""
903 | ]
904 | },
905 | "metadata": {
906 | "tags": [],
907 | "needs_background": "light"
908 | }
909 | }
910 | ]
911 | },
912 | {
913 | "cell_type": "markdown",
914 | "metadata": {
915 | "id": "wlHCVh3F9v4c",
916 | "colab_type": "text"
917 | },
918 | "source": [
919 | "## Forming adversarial examples\n",
920 | "\n",
921 | "- Train an image classifier\n",
922 | "- Form examples"
923 | ]
924 | },
925 | {
926 | "cell_type": "code",
927 | "metadata": {
928 | "id": "zj9UF_j1X2hq",
929 | "colab_type": "code",
930 | "colab": {}
931 | },
932 | "source": [
933 | "# Define a utility function for the image classifier\n",
934 | "def get_train_model():\n",
935 | " model = Sequential([\n",
936 | " Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)),\n",
937 | " MaxPooling2D((2,2)),\n",
938 | " Conv2D(64, (3, 3), activation='relu'),\n",
939 | " MaxPooling2D((2,2)),\n",
940 | " Conv2D(64, (3, 3), activation='relu')\n",
941 | " ])\n",
942 | "\n",
943 | " model.add(Flatten())\n",
944 | " model.add(Dense(64, activation='relu'))\n",
945 | " model.add(Dense(10, activation='softmax'))\n",
946 | "\n",
947 | " model.compile(optimizer='adam',\n",
948 | " loss='sparse_categorical_crossentropy',\n",
949 | " metrics=['accuracy'])\n",
950 | " \n",
951 | " return model"
952 | ],
953 | "execution_count": 0,
954 | "outputs": []
955 | },
956 | {
957 | "cell_type": "code",
958 | "metadata": {
959 | "id": "pp5HxWUMYh3d",
960 | "colab_type": "code",
961 | "colab": {
962 | "base_uri": "https://localhost:8080/",
963 | "height": 357
964 | },
965 | "outputId": "5175eec8-5405-4ef7-bfd6-4a61f0409b7e"
966 | },
967 | "source": [
968 | "# Load the dataset again\n",
969 | "((X_train, y_train), (X_test, y_test)) = tf.keras.datasets.fashion_mnist.load_data()\n",
970 | "X_train = X_train.reshape(-1, 28, 28, 1)\n",
971 | "X_test = X_test.reshape(-1, 28, 28, 1)\n",
972 | "\n",
973 | "# Normalize the dataset\n",
974 | "X_train = X_train / 255.\n",
975 | "X_test = X_test / 255.\n",
976 | "\n",
977 | "# Train the model\n",
978 | "apparel_model = get_train_model()\n",
979 | "history = apparel_model.fit(X_train, y_train,\n",
980 | " validation_data=(X_test, y_test),\n",
981 | " batch_size=128,\n",
982 | " epochs=10)"
983 | ],
984 | "execution_count": 23,
985 | "outputs": [
986 | {
987 | "output_type": "stream",
988 | "text": [
989 | "Epoch 1/10\n",
990 | "469/469 [==============================] - 3s 5ms/step - loss: 0.6266 - accuracy: 0.7707 - val_loss: 0.4383 - val_accuracy: 0.8426\n",
991 | "Epoch 2/10\n",
992 | "469/469 [==============================] - 2s 5ms/step - loss: 0.3936 - accuracy: 0.8590 - val_loss: 0.3717 - val_accuracy: 0.8689\n",
993 | "Epoch 3/10\n",
994 | "469/469 [==============================] - 2s 5ms/step - loss: 0.3366 - accuracy: 0.8773 - val_loss: 0.3378 - val_accuracy: 0.8768\n",
995 | "Epoch 4/10\n",
996 | "469/469 [==============================] - 2s 5ms/step - loss: 0.3023 - accuracy: 0.8899 - val_loss: 0.3114 - val_accuracy: 0.8879\n",
997 | "Epoch 5/10\n",
998 | "469/469 [==============================] - 2s 5ms/step - loss: 0.2772 - accuracy: 0.8987 - val_loss: 0.2831 - val_accuracy: 0.8976\n",
999 | "Epoch 6/10\n",
1000 | "469/469 [==============================] - 2s 5ms/step - loss: 0.2554 - accuracy: 0.9061 - val_loss: 0.2868 - val_accuracy: 0.8981\n",
1001 | "Epoch 7/10\n",
1002 | "469/469 [==============================] - 2s 5ms/step - loss: 0.2396 - accuracy: 0.9118 - val_loss: 0.2729 - val_accuracy: 0.9005\n",
1003 | "Epoch 8/10\n",
1004 | "469/469 [==============================] - 2s 5ms/step - loss: 0.2231 - accuracy: 0.9176 - val_loss: 0.2683 - val_accuracy: 0.9022\n",
1005 | "Epoch 9/10\n",
1006 | "469/469 [==============================] - 2s 5ms/step - loss: 0.2101 - accuracy: 0.9229 - val_loss: 0.2726 - val_accuracy: 0.9050\n",
1007 | "Epoch 10/10\n",
1008 | "469/469 [==============================] - 2s 5ms/step - loss: 0.1986 - accuracy: 0.9264 - val_loss: 0.2580 - val_accuracy: 0.9076\n"
1009 | ],
1010 | "name": "stdout"
1011 | }
1012 | ]
1013 | },
1014 | {
1015 | "cell_type": "code",
1016 | "metadata": {
1017 | "id": "rYlYWtXkaFT0",
1018 | "colab_type": "code",
1019 | "colab": {
1020 | "base_uri": "https://localhost:8080/",
1021 | "height": 279
1022 | },
1023 | "outputId": "65ebb743-aae2-4560-ea4e-8b6c432602a1"
1024 | },
1025 | "source": [
1026 | "# Plot training progress\n",
1027 | "plt.plot(history.history[\"loss\"], label=\"train_loss\")\n",
1028 | "plt.plot(history.history[\"val_loss\"], label=\"val_loss\")\n",
1029 | "plt.plot(history.history[\"accuracy\"], label=\"train_acc\")\n",
1030 | "plt.plot(history.history[\"val_accuracy\"], label=\"val_acc\")\n",
1031 | "plt.xlabel(\"Epoch #\")\n",
1032 | "plt.ylabel(\"Loss/Accuracy\")\n",
1033 | "plt.legend(loc=\"lower left\")\n",
1034 | "plt.show()"
1035 | ],
1036 | "execution_count": 27,
1037 | "outputs": [
1038 | {
1039 | "output_type": "display_data",
1040 | "data": {
1041 | "image/png": "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\n",
1042 | "text/plain": [
1043 | ""
1044 | ]
1045 | },
1046 | "metadata": {
1047 | "tags": [],
1048 | "needs_background": "light"
1049 | }
1050 | }
1051 | ]
1052 | },
1053 | {
1054 | "cell_type": "code",
1055 | "metadata": {
1056 | "id": "DhA9iS9JcUx1",
1057 | "colab_type": "code",
1058 | "colab": {}
1059 | },
1060 | "source": [
1061 | "# Define class labels\n",
1062 | "LABELS = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',\n",
1063 | " 'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']"
1064 | ],
1065 | "execution_count": 0,
1066 | "outputs": []
1067 | },
1068 | {
1069 | "cell_type": "code",
1070 | "metadata": {
1071 | "id": "7C7hRsy_a7K5",
1072 | "colab_type": "code",
1073 | "colab": {}
1074 | },
1075 | "source": [
1076 | "# Create adversarial example\n",
1077 | "############################\n",
1078 | "\n",
1079 | "# Clipping utility so that the pixel values stay within [0,1]\n",
1080 | "EPS = 1./10000\n",
1081 | "\n",
1082 | "def clip_eps(delta_tensor):\n",
1083 | " return tf.clip_by_value(delta_tensor, clip_value_min=-EPS, clip_value_max=EPS)\n",
1084 | "\n",
1085 | "def generate_adversaries_targeted(image_tensor, delta, \n",
1086 | " true_index, target_index, model):\n",
1087 | " # Loss and optimizer\n",
1088 | " scc_loss = tf.keras.losses.SparseCategoricalCrossentropy()\n",
1089 | " optimizer = tf.keras.optimizers.Adam(learning_rate=2e-1)\n",
1090 | "\n",
1091 | " for t in range(300):\n",
1092 | " plt.show()\n",
1093 | " with tf.GradientTape() as tape:\n",
1094 | " tape.watch(delta)\n",
1095 | " inp = (image_tensor + delta)/255\n",
1096 | " predictions = model(inp, training=False)\n",
1097 | " loss = (- scc_loss(tf.convert_to_tensor([true_index]), predictions) + \n",
1098 | "\t scc_loss(tf.convert_to_tensor([target_index]), predictions))\n",
1099 | " if t % 20 == 0:\n",
1100 | " print(t, loss.numpy())\n",
1101 | " # plt.imshow(50*delta.numpy().squeeze()+0.5)\n",
1102 | " \n",
1103 | " # Get the gradients\n",
1104 | " gradients = tape.gradient(loss, delta)\n",
1105 | " \n",
1106 | " # Update the weights\n",
1107 | " optimizer.apply_gradients([(gradients, delta)])\n",
1108 | "\n",
1109 | " # Clip so that the delta values are within [0,1]\n",
1110 | " delta.assign_add(clip_eps(delta))\n",
1111 | "\n",
1112 | " return delta\n",
1113 | "\n",
1114 | "def perturb_image(image, true, target, model):\n",
1115 | " # Load and preprocess image but a but without any `preprocess_input`\n",
1116 | " plt.imshow((image.reshape(28, 28)), cmap=plt.cm.binary)\n",
1117 | "\n",
1118 | " # Add batch dim\n",
1119 | " image = np.expand_dims(image, 0)\n",
1120 | "\n",
1121 | " # Generate predictions before any adversaries\n",
1122 | " unsafe_preds = model.predict(image)\n",
1123 | " print('Predicted before adv.:', LABELS[unsafe_preds[0].argmax()])\n",
1124 | "\n",
1125 | " # Initialize the perturbation quantity\n",
1126 | " image_tensor = tf.constant(image*255, dtype=tf.float32)\n",
1127 | " delta = tf.Variable(tf.zeros_like(image_tensor), trainable=True)\n",
1128 | "\n",
1129 | " # Get the adversary vector\n",
1130 | " delta_tensor = generate_adversaries_targeted(image_tensor, delta, true, target, model)\n",
1131 | "\n",
1132 | " # See if the image changes\n",
1133 | " plt.imshow((image_tensor + delta_tensor).numpy().squeeze()/255, cmap=plt.cm.binary)\n",
1134 | " plt.show()\n",
1135 | "\n",
1136 | " # Generate prediction\n",
1137 | " perturbed_image = (image_tensor + delta_tensor)/255\n",
1138 | " preds = model.predict(perturbed_image)\n",
1139 | " print('Predicted:', LABELS[preds[0].argmax()])\n",
1140 | "\n",
1141 | " return (image_tensor + delta_tensor)/255"
1142 | ],
1143 | "execution_count": 0,
1144 | "outputs": []
1145 | },
1146 | {
1147 | "cell_type": "code",
1148 | "metadata": {
1149 | "id": "G5t8ILAjc_8s",
1150 | "colab_type": "code",
1151 | "colab": {
1152 | "base_uri": "https://localhost:8080/",
1153 | "height": 819
1154 | },
1155 | "outputId": "581e465f-c513-4fe9-bfe2-feff5d4a25dc"
1156 | },
1157 | "source": [
1158 | "# Randomly select an image\n",
1159 | "idx = int(np.random.choice(X_train.shape, 1))\n",
1160 | "sample_image = X_train[idx]\n",
1161 | "\n",
1162 | "# Let's go (target -> Sandal (idx: 5))\n",
1163 | "print(\"Original label \",LABELS[y_train[idx]])\n",
1164 | "perturbed_image = perturb_image(sample_image, y_train[idx], 5, apparel_model)"
1165 | ],
1166 | "execution_count": 82,
1167 | "outputs": [
1168 | {
1169 | "output_type": "stream",
1170 | "text": [
1171 | "Original label T-shirt/top\n",
1172 | "Predicted before adv.: T-shirt/top\n"
1173 | ],
1174 | "name": "stdout"
1175 | },
1176 | {
1177 | "output_type": "display_data",
1178 | "data": {
1179 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAPsAAAD4CAYAAAAq5pAIAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+j8jraAAARqklEQVR4nO3dXYyV5bUH8P8SGEAG+ZBxBMFDJZAomgLZGU8saTxpTlFugBtSLionNtILSVpDYo1e1JuTqJH21ORIpEpKj9XSSDliYk7wIAQbTeMGQUA4Dhq0AsLwLfIN61zMSzPFedca9rPf/W5n/X/JZGb22u/ez2zmz7tnr/08j6gqiKj/u67sARBRYzDsREEw7ERBMOxEQTDsREEMbOSdjRkzRidOnNjIu+wXzp49a9Y///zz3NqoUaPMY6+//nqzLiJJdWvsx44dM48dPHiwWb/55pvN+oABA8x6f7R3714cPny413+UpLCLyH0AfgNgAIAXVfUp6/oTJ05EtVpNucvCeC1I75e6SLt27TLrixcvzq3Nnz/fPHb69OlmvaWlxawPHGj/Cu3cuTO3tmbNGvPY2267zaw/+uijZn3kyJFmvT+qVCq5tZqfxovIAAD/CeB+AHcAWCAid9R6e0RUrJS/2TsA7FHVT1X1PIA/AphTn2ERUb2lhP0WAH/r8f0X2WX/QEQWiUhVRKpdXV0Jd0dEKQp/NV5Vl6tqRVUrbW1tRd8dEeVICfs+ABN6fD8+u4yImlBK2N8HMFlEviMiLQB+BGBtfYZFRPUmKbPeRGQ2gP9Ad+tthar+u3X9SqWiRbXeymydffDBB2Z91apVZn316tVm3esXnzp1Krd25swZ89ijR4+a9SJNmTLFrF93nX0u2r17t1m3+vCzZs0yj12yZIlZv+uuu8x6WSqVCqrVav377Kr6JoA3U26DiBqDb5clCoJhJwqCYScKgmEnCoJhJwqCYScKoqHz2YuU2kc/efKkWX/ggQdya9u2bTOP9d4D0NraataHDh1q1q05616P/uLFi2b9xIkTZt2bD2/df+q/WUdHh1m35tK/++675rEbN2406zNnzjTrL7/8slkvA8/sREEw7ERBMOxEQTDsREEw7ERBMOxEQfSb1luqefPmmXVrueb29nbzWK/FdOnSJbOesiSyd9teW/DGG29Muv2U+05ltSyHDBliHuv9m73zzjtm3VsR+PbbbzfrReCZnSgIhp0oCIadKAiGnSgIhp0oCIadKAiGnSiIMH32zZs3m3Wrjw4AY8aMya1500Q93nLP+/bZe29Yx1++fNk81tuF1euje8s9W86fP2/WBw0aZNaHDx9u1sePH59b835uj/dzv/jii2Z96dKlSfdfC57ZiYJg2ImCYNiJgmDYiYJg2ImCYNiJgmDYiYII02ffsGGDWT937pxZt5Yl9nquXq978ODBZv2ZZ54x62PHjs2tTZgwwTx2//79Nd824P9sVq/c67NbW1EDwJYtW8z6c889l1tra2szj71w4YJZ9/7NvW24y+izJ4VdRPYC+ArAJQAXVbVSj0ERUf3V48z+L6p6uA63Q0QF4t/sREGkhl0BrBORzSKyqLcriMgiEamKSLWrqyvx7oioVqlhn6mqMwDcD+BhEfn+1VdQ1eWqWlHViveiCBEVJynsqrov+3wIwBoA9k57RFSamsMuIsNEZPiVrwH8EMCOeg2MiOor5dX4dgBrsvW1BwJ4RVX/py6jKsBrr71m1r212a1+sjc3+vTp02Z9xIgRZv2hhx4y6+vWrcutefP4H3zwQbP+wgsvmPWpU6eadev9Cd5c+ZtuusmsP/LII2b9+eefz615fXRr3AAwbNgws757926z/vHHH+fWpkyZYh5bq5rDrqqfAvhuHcdCRAVi640oCIadKAiGnSgIhp0oCIadKIgwU1y3bdtm1r2poFabyJse6zlx4kTS8bNmzcqttba2msd6Wws/++yzZt3b6vqNN97IrXlLcE+fPt2se1NcrZao1w71prB6de/36b333sutFdV645mdKAiGnSgIhp0oCIadKAiGnSgIhp0oCIadKIh+02ffvn27WfdWyfGmuFp9dm+qprcl8+jRo826Z+fOnbk1b5nqAwcOmPUnnnjCrKuqWbeWkvaOtXrRfWEtg+0toe39PmRTu3MNHTrUrG/atCm3tnDhQvPYWvHMThQEw04UBMNOFATDThQEw04UBMNOFATDThREv+mzP/3002bd63V7SwOnzI0eMmSIWbd60QBQrVbN+pEjR3JrR48eNY/1llQ+ePCgWffGbv3s3pbNx48fN+urVq0y68eOHcuteX1w7769473H1Vviuwg8sxMFwbATBcGwEwXBsBMFwbATBcGwEwXBsBMF0W/6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\n",
1180 | "text/plain": [
1181 | ""
1182 | ]
1183 | },
1184 | "metadata": {
1185 | "tags": [],
1186 | "needs_background": "light"
1187 | }
1188 | },
1189 | {
1190 | "output_type": "stream",
1191 | "text": [
1192 | "0 16.117859\n",
1193 | "20 16.117216\n",
1194 | "40 16.099031\n",
1195 | "60 12.984386\n",
1196 | "80 9.905032\n",
1197 | "100 6.4673576\n",
1198 | "120 3.6043863\n",
1199 | "140 1.7249596\n",
1200 | "160 0.06058836\n",
1201 | "180 -1.2979188\n",
1202 | "200 -2.7338905\n",
1203 | "220 -4.0762415\n",
1204 | "240 -6.040269\n",
1205 | "260 -8.053326\n",
1206 | "280 -10.19889\n"
1207 | ],
1208 | "name": "stdout"
1209 | },
1210 | {
1211 | "output_type": "display_data",
1212 | "data": {
1213 | "image/png": "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\n",
1214 | "text/plain": [
1215 | ""
1216 | ]
1217 | },
1218 | "metadata": {
1219 | "tags": [],
1220 | "needs_background": "light"
1221 | }
1222 | },
1223 | {
1224 | "output_type": "stream",
1225 | "text": [
1226 | "Predicted: Sandal\n"
1227 | ],
1228 | "name": "stdout"
1229 | }
1230 | ]
1231 | },
1232 | {
1233 | "cell_type": "markdown",
1234 | "metadata": {
1235 | "id": "j13P4BcF9zo1",
1236 | "colab_type": "text"
1237 | },
1238 | "source": [
1239 | "## Seeing if the adversarial examples are misclassified by the Discriminator of the GAN"
1240 | ]
1241 | },
1242 | {
1243 | "cell_type": "code",
1244 | "metadata": {
1245 | "id": "6UBKDYOnj_-p",
1246 | "colab_type": "code",
1247 | "colab": {
1248 | "base_uri": "https://localhost:8080/",
1249 | "height": 34
1250 | },
1251 | "outputId": "c8a16505-a3b2-4cde-d532-7babf638f397"
1252 | },
1253 | "source": [
1254 | "# 0 -> Real image 1-> Fake image\n",
1255 | "disc.predict_classes(perturbed_image)"
1256 | ],
1257 | "execution_count": 85,
1258 | "outputs": [
1259 | {
1260 | "output_type": "execute_result",
1261 | "data": {
1262 | "text/plain": [
1263 | "array([[1]], dtype=int32)"
1264 | ]
1265 | },
1266 | "metadata": {
1267 | "tags": []
1268 | },
1269 | "execution_count": 85
1270 | }
1271 | ]
1272 | },
1273 | {
1274 | "cell_type": "markdown",
1275 | "metadata": {
1276 | "id": "-fdOzykGoOaW",
1277 | "colab_type": "text"
1278 | },
1279 | "source": [
1280 | "The generator is able to predict the perturbed image as a fake one. **But this does not draw any conclusion since we used a relatively simple and small dataset.**"
1281 | ]
1282 | }
1283 | ]
1284 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Adversarial Examples in Deep Learning
2 |
3 | Deep Learning has brought us tremendous achievements in the field of Computer Vision. In spite of the impeccable success, modern Deep Learning systems are still prone to adversaries. Let's talk in terms of Computer Vision. Consider an image of a polar bear and an instance of it (X1). A Deep Learning-based image classifier is able to successfully X1 as a polar bear. Now consider another instance of a polar bear X2 which is a slightly perturbed version of X1. To the human eyes, it would still be a polar bear but for that same image classifier, it would be an ant. These perturbations are referred to as image adversaries.
4 |
5 |
6 |
7 | This repository contains code for a short crash-course related adversarial examples in deep learning. The crash course would include introduction to adversarial examples, training models that are adversarial-aware, situations where adversarial-aware models could fail, and so on.
8 |
9 | The crash course would be presented in form of [Weights and Biases reports](https://docs.wandb.com/reports). The first report in this line is now up -
10 | - [An Introduction to Adversarial Examples in Deep Learning](https://app.wandb.ai/authors/adv-dl/reports/An-Introduction-to-Adversarial-Examples-in-Deep-Learning--VmlldzoyMTQwODM)
11 |
12 | ## Contents (to be updated):
13 | - `Image_Adversaries_Basics.ipynb`: Shows how to create adversaries that can fool a ResNet50 model pre-trained on ImageNet. Includes both vanilla and targeted attacks.
14 | - `Adversarial_Training_NSL.ipynb`: Shows how to train adversarially robust image classifiers using [`Neural Structured Learning`](https://www.tensorflow.org/neural_structured_learning).
15 | - `GANs_w_Adversaries.ipynb`: Shows how to incorporate GANs (plain old DCGAN) to tackle adversarial situations.
16 | - `Optimizer_Susceptibility.ipynb`: Studies the susceptibility of different optimizers against simple attacks.
17 | - `Optimizer_Susceptibility_Targeted_Attacks.ipynb`: Studies the susceptibility of different optimizers against targeted attacks.
18 |
19 | **Note**: The materials are strictly for learning purpose and should not be considered for production systems.
20 |
21 | ## Coded in:
22 | - TensorFlow 2.x (at time of writing Google Colab had TensorFlow `2.3.0`)
23 |
24 | ## References:
25 | - [J. Z. Kolter and A. Madry: Adversarial Robustness - Theory and Practice (NeurIPS 2018 Tutorial)](https://adversarial-ml-tutorial.org/)
26 | - Chapter 10 (Adversarial examples), [GANs in Action](https://www.manning.com/books/gans-in-action)
27 | - [Introduction to Adversarial Machine Learning](https://blog.floydhub.com/introduction-to-adversarial-machine-learning/)
28 | - [Adversarial example using FGSM](https://www.tensorflow.org/tutorials/generative/adversarial_fgsm)
29 | - [Adversarial regularization for image classification](https://www.tensorflow.org/neural_structured_learning/tutorials/adversarial_keras_cnn_mnist)
30 |
--------------------------------------------------------------------------------