PyTorch 的对抗性攻击
项目描述
对抗性攻击-PyTorch
Torchattacks是一个 PyTorch 库,它提供对抗性攻击以生成对抗性示例。它包含类似于 PyTorch 的界面和功能,使 PyTorch 用户更容易实施对抗性攻击 ( README [KOR] )。
易于实施
import torchattacks
atk = torchattacks.PGD(model, eps=8/255, alpha=2/255, steps=4)
adv_images = atk(images, labels)
易于修改
from torchattacks.attack import Attack
class CustomAttack(Attack):
def __init__(self, model):
super().__init__("CustomAttack", model)
def forward(self, images, labels=None):
adv_images = # Custom attack method
return adv_images
有用的功能
atk.set_mode_targeted_least_likely(kth_min) # Targeted attack
atk.set_return_type(type='int') # Return values [0, 255]
atk = torchattacks.MultiAttack([atk1, ..., atk99]) # Combine attacks
atk.save(data_loader, save_path=None, verbose=True, return_verbose=False) # Save adversarial images
目录
要求和安装
:剪贴板:要求
- PyTorch 版本 >=1.4.0
- Python 版本 >=3.6
:hammer: 安装
pip install torchattacks
入门
:warning: 注意事项
- 在用于攻击之前,所有图像都应该使用 transform[to.Tensor()] 缩放到 [0, 1]。为了便于使用对抗性攻击,攻击过程中不包括反向规范化。要应用输入规范化,请向模型添加规范化层。请参考代码或nbviewer。
(N, C)所有模型都应该只返回一个where向量C = number of classes。考虑到torchvision.models中的大多数模型返回一个向量(N,C),其中N是输入的数量,C是类的数量,torchattacks也只支持有限的输出形式。请仔细检查模型输出的形状。在模型返回多个输出的情况下,请参考demo。torch.backends.cudnn.deterministic = True获得具有固定随机种子的相同对抗样本。GPU [讨论]上的浮点张量的某些操作是不确定的。如果您想使用相同的输入获得相同的结果,请运行torch.backends.cudnn.deterministic = True[ref]。
:rocket: 演示
给定模型、图像和标签,对抗性图像可以生成如下:
import torchattacks
atk = torchattacks.PGD(model, eps=8/255, alpha=2/255, steps=4)
adv_images = atk(images, labels)
Torchattacks 支持以下功能:
目标模式
- 随机目标标签:
# random labels as target labels.
atk.set_mode_targeted_random(n_classses)
- 最不可能的标签:
# label with the k-th smallest probability used as target labels.
atk.set_mode_targeted_least_likely(kth_min)
- 通过自定义函数:
# label from mapping function
atk.set_mode_targeted_by_function(target_map_function=lambda images, labels:(labels+1)%10)
- 返回默认值:
atk.set_mode_default()
返回类型
- 返回具有整数值 (0-255) 的对抗性图像。
atk.set_return_type(type='int')
- 返回具有浮点值 (0-1) 的对抗性图像。
atk.set_return_type(type='float')
保存对抗性图像
# Save
atk.save(data_loader, save_path="./data/sample.pt", verbose=True)
# Load
import torch
from torch.utils.data import DataLoader, TensorDataset
adv_images, labels = torch.load("./data/sample.pt")
# If set_return_type was 'int',
# adv_data = TensorDataset(adv_images.float()/255, labels)
# else,
adv_data = TensorDataset(adv_images, labels)
adv_loader = DataLoader(adv_data, batch_size=128, shuffle=False)
攻击期间的训练/评估
# For RNN-based models, we cannot calculate gradients with eval mode.
# Thus, it should be changed to the training mode during the attack.
atk.set_training_mode(model_training=False, batchnorm_training=False, dropout_training=False)
进行一组攻击
- 强力攻击
atk1 = torchattacks.FGSM(model, eps=8/255)
atk2 = torchattacks.PGD(model, eps=8/255, alpha=2/255, iters=40, random_start=True)
atk = torchattacks.MultiAttack([atk1, atk2])
- Binary serach for CW
atk1 = torchattacks.CW(model, c=0.1, steps=1000, lr=0.01)
atk2 = torchattacks.CW(model, c=1, steps=1000, lr=0.01)
atk = torchattacks.MultiAttack([atk1, atk2])
- Random restarts
atk1 = torchattacks.PGD(model, eps=8/255, alpha=2/255, iters=40, random_start=True)
atk2 = torchattacks.PGD(model, eps=8/255, alpha=2/255, iters=40, random_start=True)
atk = torchattacks.MultiAttack([atk1, atk2])
这是火炬攻击的演示。
- 使用 ImageNet 进行白盒攻击(代码,nbviewer):使用torchattacks使用ImageNet 数据集制作对抗性示例来欺骗 ResNet-18。
- 使用 CIFAR10 进行传输攻击(代码,nbviewer):此演示提供了具有两种不同模型的黑盒攻击示例。首先,使用 CIFAR10 从holdout 模型制作对抗性数据集,并将其保存为torch 数据集。其次,使用对抗性数据集攻击目标模型。
- 使用 MNIST 进行对抗训练(代码,nbviewer):此代码显示了如何使用此存储库进行对抗训练。此代码中使用了 MNIST 数据集和自定义模型。使用 PGD 进行对抗训练,然后应用 FGSM 来评估模型。
Torchattacks 还支持与其他攻击包的协作。
傻瓜
https://github.com/bethgelab/foolbox
from torchattacks.attack import Attack
import foolbox as fb
# L2BrendelBethge
class L2BrendelBethge(Attack):
def __init__(self, model):
super(L2BrendelBethge, self).__init__("L2BrendelBethge", model)
self.fmodel = fb.PyTorchModel(self.model, bounds=(0,1), device=self.device)
self.init_attack = fb.attacks.DatasetAttack()
self.adversary = fb.attacks.L2BrendelBethgeAttack(init_attack=self.init_attack)
self._attack_mode = 'only_default'
def forward(self, images, labels):
images, labels = images.to(self.device), labels.to(self.device)
# DatasetAttack
batch_size = len(images)
batches = [(images[:batch_size//2], labels[:batch_size//2]),
(images[batch_size//2:], labels[batch_size//2:])]
self.init_attack.feed(model=self.fmodel, inputs=batches[0][0]) # feed 1st batch of inputs
self.init_attack.feed(model=self.fmodel, inputs=batches[1][0]) # feed 2nd batch of inputs
criterion = fb.Misclassification(labels)
init_advs = self.init_attack.run(self.fmodel, images, criterion)
# L2BrendelBethge
adv_images = self.adversary.run(self.fmodel, images, labels, starting_points=init_advs)
return adv_images
atk = L2BrendelBethge(model)
atk.save(data_loader=test_loader, save_path="_temp.pt", verbose=True)
对抗性鲁棒性工具箱 (ART)
https://github.com/IBM/adversarial-robustness-toolbox
import torch.nn as nn
import torch.optim as optim
from torchattacks.attack import Attack
import art.attacks.evasion as evasion
from art.classifiers import PyTorchClassifier
# SaliencyMapMethod (or Jacobian based saliency map attack)
class JSMA(Attack):
def __init__(self, model, theta=1/255, gamma=0.15, batch_size=128):
super(JSMA, self).__init__("JSMA", model)
self.classifier = PyTorchClassifier(
model=self.model, clip_values=(0, 1),
loss=nn.CrossEntropyLoss(),
optimizer=optim.Adam(self.model.parameters(), lr=0.01),
input_shape=(1, 28, 28), nb_classes=10)
self.adversary = evasion.SaliencyMapMethod(classifier=self.classifier,
theta=theta, gamma=gamma,
batch_size=batch_size)
self.target_map_function = lambda labels: (labels+1)%10
self._attack_mode = 'only_default'
def forward(self, images, labels):
adv_images = self.adversary.generate(images, self.target_map_function(labels))
return torch.tensor(adv_images).to(self.device)
atk = JSMA(model)
atk.save(data_loader=test_loader, save_path="_temp.pt", verbose=True)
:fire: 已实施论文列表
括号中的距离度量。
| 姓名 | 纸 | 评论 |
|---|---|---|
| FGSM (林夫) |
解释和利用对抗性示例(Goodfellow 等人,2014 年) | |
| BIM (林夫) |
物理世界中的对抗性示例(Kurakin 等人,2016 年) | 基本迭代方法或迭代-FSGM |
| 顺时针 (L2) |
评估神经网络的鲁棒性(Carlini 等人,2016 年) | |
| RFGSM (林夫) |
集成对抗训练:攻击和防御(Tramèr 等人,2017 年) | 随机初始化 + FGSM |
| PGD (Linf) |
迈向抵抗对抗性攻击的深度学习模型(Mardry 等人,2017 年) | 投影梯度法 |
| PGD L2 (L2) |
迈向抵抗对抗性攻击的深度学习模型(Mardry 等人,2017 年) | 投影梯度法 |
| MIFGSM (林夫) |
用 Momentum 提升对抗性攻击 ( Dong et al., 2017 ) | : heart_eyes: 贡献者zhuangzi926 huitailangyz |
| TPGD (林夫) |
稳健性和准确性之间的理论上原则性权衡(Zhang 等人,2019 年) | |
| EOTPGD (Linf) |
评论“Adv-BNN:通过鲁棒贝叶斯神经网络改进对抗防御”(Zimmermann,2019 年) | EOT +PGD |
| APGD (Linf, L2) |
使用各种无参数攻击的集合对对抗鲁棒性进行可靠评估(Croce 等人,2020) | |
| APGDT (Linf, L2) |
使用各种无参数攻击的集合对对抗鲁棒性进行可靠评估(Croce 等人,2020) | 有针对性的APGD |
| FAB (Linf, L2, L1) |
具有快速自适应边界攻击的最小失真对抗样本(Croce 等人,2019 年) | |
| 广场 (Linf,L2) |
方形攻击:通过随机搜索进行的高效查询黑盒对抗攻击(Andriushchenko 等人,2019 年) | |
| 自动攻击( Linf ,L2) |
使用各种无参数攻击的集合对对抗鲁棒性进行可靠评估(Croce 等人,2020) | APGD+APGDT+FAB+方形 |
| 深愚者 (L2) |
DeepFool:一种简单而准确的欺骗深度神经网络的方法(Moosavi-Dezfooli 等人,2016 年) | |
| 单像素 (L0) |
一种欺骗深度神经网络的像素攻击(Su et al., 2019) | |
| 稀疏傻瓜 (L0) |
SparseFool:几个像素就有很大的不同(Modas 等人,2019 年) | |
| DIFGSM (林夫) |
通过输入多样性提高对抗性示例的可迁移性 ( Xie et al., 2019 ) | :heart_eyes: 投稿人淘白 |
| TIFGSM (林夫) |
通过平移不变攻击规避对可转移对抗样本的防御(Dong 等人,2019 年) | :heart_eyes: 投稿人淘白 |
| 抖动 (Linf) |
探索鲁棒神经网络的错误分类以增强对抗性攻击 ( Schwinn, Leo, et al., 2021 ) | |
| 像素 (L0) |
Pixle:一种基于重新排列像素的快速有效的黑盒攻击(Pomponi, Jary, et al., 2022) |
性能比较
为了公平比较,使用了Robustbench。至于比较包,选择了当前更新和引用最多的方法:
在 CIFAR10 的前 50 张图像上,对每次攻击和经过时间的稳健准确度。对于 L2 攻击,记录对抗图像和原始图像之间的平均 L2 距离。所有实验均在 GeForce RTX 2080 上完成。最新版本请参考这里(代码、nbviewer)。
| 攻击 | 包裹 | 标准 | 黄2020Fast | Rice2020过拟合 | 评论 |
|---|---|---|---|---|---|
| FGSM(林夫) | 火炬攻击 | 34%(54 毫秒) | 48% (5ms) | 62%(82 毫秒) | |
| 傻瓜* | 34%(15 毫秒) | 48% (8ms) | 62%(30 毫秒) | ||
| 艺术 | 34%(214 毫秒) | 48%(59 毫秒) | 62%(768 毫秒) | ||
| PGD (Linf) | 火炬攻击 | 0%(174 毫秒) | 44%(52 毫秒) | 58%(1348 毫秒) | :crown:最快 |
| 傻瓜* | 0%(354 毫秒) | 44%(56 毫秒) | 58%(1856 毫秒) | ||
| 艺术 | 0%(1384 毫秒) | 44% (437ms) | 58%(4704 毫秒) | ||
| CW † (L2) | 火炬攻击 | 0% / 0.40 (2596ms) |
14% / 0.61 (3795ms) |
22% / 0.56 (43484ms) |
:crown:最高 成功率:crown:最快 |
| 傻瓜* | 0% / 0.40 (2668ms) |
32% / 0.41 (3928ms) |
34% / 0.43 (44418ms) |
||
| 艺术 | 0% / 0.59 (196738ms) |
24% / 0.70 (66067ms) |
26% / 0.65 (694972ms) |
||
| PGD (L2) | 火炬攻击 | 0% / 0.41 (184ms) | 68% / 0.5 (52ms) |
70% / 0.5 (1377ms) |
:crown:最快的 |
| 傻瓜* | 0% / 0.41 (396ms) | 68% / 0.5 (57ms) |
70% / 0.5 (1968ms) |
||
| 艺术 | 0% / 0.40 (1364ms) | 68% / 0.5 (429ms) |
70% / 0.5 (4777ms) |
*请注意,Foolbox 同时返回准确率和对抗性图像,因此生成对抗性图像的实际时间可能比记录短。
†考虑到 const 的二进制搜索算法c可能很耗时,torchattacks 支持 MutliAttack 进行网格搜索c。
引文
如果你使用这个包,请引用以下 BibTex ( SemanticScholar , GoogleScholar ):
@article{kim2020torchattacks,
title={Torchattacks: A pytorch repository for adversarial attacks},
author={Kim, Hoki},
journal={arXiv preprint arXiv:2010.01950},
year={2020}
}
贡献
任何形式的贡献总是受欢迎的!:脸红:
如果您有兴趣在此 repo 中添加新的攻击或修复一些问题,请查看CONTRIBUTING.md。
推荐站点和套餐
-
对抗性攻击包:
- https://github.com/IBM/adversarial-robustness-toolbox:IBM 制作的对抗性攻防包。TensorFlow、Keras、Pyotrch 可用。
- https://github.com/bethgelab/foolbox : Bethge Lab制作的对抗性攻击包。TensorFlow、Pyotrch 可用。
- https://github.com/tensorflow/cleverhans:Google Brain 制作的对抗性攻击包。TensorFlow 可用。
- https://github.com/BorealisAI/advertorch:由BorealisAI制作的对抗性攻击包。Pytorch 可用。
- https://github.com/DSE-MSU/DeepRobust:由BorealisAI制作的对抗性攻击(尤其是在 GNN 上)包。Pytorch 可用。
- https://github.com/fra31/auto-attack:一组被认为是现存最强的攻击。TensorFlow、Pyotrch 可用。
-
对抗性防御排行榜:
-
对抗性攻击和防御论文:
- https://nicholas.carlini.com/writing/2019/all-adversarial-example-papers.html:由 Nicholas Carlini 撰写的所有 (arXiv) 对抗性示例论文的完整列表。
- https://github.com/chawins/Adversarial-Examples-Reading-List:Chawin Sitawarin 制作的对抗性示例阅读列表。
-
等:
- https://github.com/Harry24k/gnn-meta-attack:对图神经网络的对抗性中毒攻击。
- https://github.com/ChandlerBang/awesome-graph-attack-papers:图神经网络攻击论文。