{ "info": { "author": "Harry Kim <24k.harry@gmail.com>", "author_email": "", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 3.6", "Topic :: Scientific/Engineering :: Artificial Intelligence", "Topic :: Scientific/Engineering :: Visualization" ], "description": "# Adversarial-Attacks-PyTorch\n\n
\n\n[Torchattacks](https://adversarial-attacks-pytorch.readthedocs.io/en/latest/index.html) is a PyTorch library that provides *adversarial attacks* to generate *adversarial examples*. It contains *PyTorch-like* interface and functions that make it easier for PyTorch users to implement adversarial attacks ([README [KOR]](https://github.com/Harry24k/adversairal-attacks-pytorch/blob/master/README_KOR.md)).\n\n\n\n\n```python\nimport torchattacks\natk = torchattacks.PGD(model, eps=8/255, alpha=2/255, steps=4)\nadv_images = atk(images, labels)\n```\n
\n\n```python\nfrom torchattacks.attack import Attack\nclass CustomAttack(Attack):\n def __init__(self, model):\n super().__init__(\"CustomAttack\", model)\n\n def forward(self, images, labels=None):\n adv_images = # Custom attack method\n return adv_images\n```\n
\n\n```python\natk.set_mode_targeted_least_likely(kth_min) # Targeted attack\natk.set_return_type(type='int') # Return values [0, 255]\natk = torchattacks.MultiAttack([atk1, ..., atk99]) # Combine attacks\natk.save(data_loader, save_path=None, verbose=True, return_verbose=False) # Save adversarial images\n```\n
\n\nRefer to [Performance Comparison](#Performance-Comparison).\n\n
\n\n* Random target label:\n```python\n# random labels as target labels.\natk.set_mode_targeted_random(n_classses)\n```\n\n* Least likely label:\n```python\n# label with the k-th smallest probability used as target labels.\natk.set_mode_targeted_least_likely(kth_min)\n```\n\n* By custom function:\n```python\n# label from mapping function\natk.set_mode_targeted_by_function(target_map_function=lambda images, labels:(labels+1)%10)\n```\n\n* Return to default:\n```python\natk.set_mode_default()\n```\n\n
\n\n* Return adversarial images with integer value (0-255).\n```python\natk.set_return_type(type='int')\n```\n\n* Return adversarial images with float value (0-1).\n```python\natk.set_return_type(type='float')\n```\n\n
\n\n```python\n# Save\natk.save(data_loader, save_path=\"./data/sample.pt\", verbose=True)\n\n# Load\nimport torch\nfrom torch.utils.data import DataLoader, TensorDataset\nadv_images, labels = torch.load(\"./data/sample.pt\")\n\n# If set_return_type was 'int',\n# adv_data = TensorDataset(adv_images.float()/255, labels)\n# else,\nadv_data = TensorDataset(adv_images, labels)\nadv_loader = DataLoader(adv_data, batch_size=128, shuffle=False)\n```\n\n
\n\n```python\n# For RNN-based models, we cannot calculate gradients with eval mode.\n# Thus, it should be changed to the training mode during the attack.\natk.set_training_mode(model_training=False, batchnorm_training=False, dropout_training=False)\n```\n\n
\n\n* Strong attacks\n```python\natk1 = torchattacks.FGSM(model, eps=8/255)\natk2 = torchattacks.PGD(model, eps=8/255, alpha=2/255, iters=40, random_start=True)\natk = torchattacks.MultiAttack([atk1, atk2])\n```\n\n* Binary serach for CW\n```python\natk1 = torchattacks.CW(model, c=0.1, steps=1000, lr=0.01)\natk2 = torchattacks.CW(model, c=1, steps=1000, lr=0.01)\natk = torchattacks.MultiAttack([atk1, atk2])\n```\n\n* Random restarts\n```python\natk1 = torchattacks.PGD(model, eps=8/255, alpha=2/255, iters=40, random_start=True)\natk2 = torchattacks.PGD(model, eps=8/255, alpha=2/255, iters=40, random_start=True)\natk = torchattacks.MultiAttack([atk1, atk2])\n```\n\n
\n\nhttps://github.com/bethgelab/foolbox\n\n```python\nfrom torchattacks.attack import Attack\nimport foolbox as fb\n\n# L2BrendelBethge\nclass L2BrendelBethge(Attack):\n def __init__(self, model):\n super(L2BrendelBethge, self).__init__(\"L2BrendelBethge\", model)\n self.fmodel = fb.PyTorchModel(self.model, bounds=(0,1), device=self.device)\n self.init_attack = fb.attacks.DatasetAttack()\n self.adversary = fb.attacks.L2BrendelBethgeAttack(init_attack=self.init_attack)\n self._attack_mode = 'only_default'\n\n def forward(self, images, labels):\n images, labels = images.to(self.device), labels.to(self.device)\n\n # DatasetAttack\n batch_size = len(images)\n batches = [(images[:batch_size//2], labels[:batch_size//2]),\n (images[batch_size//2:], labels[batch_size//2:])]\n self.init_attack.feed(model=self.fmodel, inputs=batches[0][0]) # feed 1st batch of inputs\n self.init_attack.feed(model=self.fmodel, inputs=batches[1][0]) # feed 2nd batch of inputs\n criterion = fb.Misclassification(labels)\n init_advs = self.init_attack.run(self.fmodel, images, criterion)\n\n # L2BrendelBethge\n adv_images = self.adversary.run(self.fmodel, images, labels, starting_points=init_advs)\n return adv_images\n\natk = L2BrendelBethge(model)\natk.save(data_loader=test_loader, save_path=\"_temp.pt\", verbose=True)\n```\n\n
\n\nhttps://github.com/IBM/adversarial-robustness-toolbox\n\n\n```python\nimport torch.nn as nn\nimport torch.optim as optim\n\nfrom torchattacks.attack import Attack\n\nimport art.attacks.evasion as evasion\nfrom art.classifiers import PyTorchClassifier\n\n# SaliencyMapMethod (or Jacobian based saliency map attack)\nclass JSMA(Attack):\n def __init__(self, model, theta=1/255, gamma=0.15, batch_size=128):\n super(JSMA, self).__init__(\"JSMA\", model)\n self.classifier = PyTorchClassifier(\n model=self.model, clip_values=(0, 1),\n loss=nn.CrossEntropyLoss(),\n optimizer=optim.Adam(self.model.parameters(), lr=0.01),\n input_shape=(1, 28, 28), nb_classes=10)\n self.adversary = evasion.SaliencyMapMethod(classifier=self.classifier,\n theta=theta, gamma=gamma,\n batch_size=batch_size)\n self.target_map_function = lambda labels: (labels+1)%10\n self._attack_mode = 'only_default'\n\n def forward(self, images, labels):\n adv_images = self.adversary.generate(images, self.target_map_function(labels))\n return torch.tensor(adv_images).to(self.device)\n\natk = JSMA(model)\natk.save(data_loader=test_loader, save_path=\"_temp.pt\", verbose=True)\n```\n\n