概述
目录
- 1 前言
- 2 foolbox使用
- 2.1 构建并训练模型
- 2.2 foolbox加载数据
- 2.3 CW有目标及无目标实例
- 2.4. foolbox杂谈
- 3 总结
- 附录
1 前言
- 对抗样本库的一些基本介绍,大家可以看cleverhans的前言部分
- foolbox支持tensorflow,pytorch以及jax框架,包含大量对抗样本攻击方式。
- 这里主要介绍使用torch+foolbox来实现对抗样本攻击。使用pip install foolbox 进行安装。
官网资料:
- github foolbox库
- foolbox Getting Started
- foolbox API 文档
2 foolbox使用
实验步骤:
- 构建并训练网络模型
- 使用foolbox加载数据集(由于封装比较方便,因此单独讲下)
- CW进行有目标以及无目标实例
- foolbox杂谈
2.1 构建并训练模型
from __future__ import print_function
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchvision import datasets, transforms
import numpy as np
import matplotlib.pyplot as plt
from tqdm import tqdm
# 加载mnist数据集
test_loader = torch.utils.data.DataLoader(
datasets.MNIST('../data', train=False, download=True, transform=transforms.Compose([
transforms.ToTensor(),
])),
batch_size=10, shuffle=True)
train_loader = torch.utils.data.DataLoader(
datasets.MNIST('../data', train=True, download=True, transform=transforms.Compose([
transforms.ToTensor(),
])),
batch_size=10, shuffle=True)
# 超参数设置
batch_size = 10
epoch = 1
learning_rate = 0.001
# LeNet Model definition
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.conv1 = nn.Conv2d(1, 10, kernel_size=5)
self.conv2 = nn.Conv2d(10, 20, kernel_size=5)
self.conv2_drop = nn.Dropout2d()
self.fc1 = nn.Linear(320, 50)
self.fc2 = nn.Linear(50, 10)
def forward(self, x):
x = F.relu(F.max_pool2d(self.conv1(x), 2))
x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2))
x = x.view(-1, 320)
x = F.relu(self.fc1(x))
x = F.dropout(x, training=self.training)
x = self.fc2(x)
return F.log_softmax(x, dim=1)
# 选择设备
device = torch.device("cuda" if (torch.cuda.is_available()) else "cpu")
# 初始化网络,并定义优化器
simple_model = Net().to(device)
optimizer1 = torch.optim.SGD(simple_model.parameters(),lr = learning_rate,momentum=0.9)
print (simple_model)
# 训练模型
def train(model,optimizer):
for i in range(epoch):
for j,(data,target) in tqdm(enumerate(train_loader)):
data = data.to(device)
target = target.to(device)
logit = model(data)
loss = F.nll_loss(logit,target)
model.zero_grad()
# 如下:因为其中的loss是单个tensor就不能用加上一个tensor的维度限制
loss.backward()
optimizer.step()
if j % 1000 == 0:
print ('第{}个数据,loss值等于{}'.format(j,loss))
train(simple_model,optimizer1)
# eval eval ,老子被你害惨了
# 训练完模型后,要加上,固定DROPOUT层
simple_model.eval()
# 模型测试
def test(model,name):
correct_num = torch.tensor(0).to(device)
for j,(data,target) in tqdm(enumerate(test_loader)):
data = data.to(device)
target = target.to(device)
logit = model(data)
pred = logit.max(1)[1]
num = torch.sum(pred==target)
correct_num = correct_num + num
print (correct_num)
print ('n{} correct rate is {}'.format(name,correct_num/10000))
test(simple_model,'simple model')
Output:
2.2 foolbox加载数据
import foolbox as fb
from foolbox.criteria import TargetedMisclassification
# 通过fb.PyTorchModel封装成的类,其fmodel使用与我们训练的simple_model基本一样
fmodel = fb.PyTorchModel(simple_model,bounds=(0,1))
# 如下代码dataset可以选择cifar10,cifar100,imagenet,mnist等。其图像格式是channel_first
# 由于fmodel设置了bounds,如下代码fb.utils.samples获得的数据,会自动将其转化为bounds范围中
images, labels = fb.utils.samples(fmodel, dataset='mnist', batchsize=10)
print (images.shape)
print (labels.shape)
- 如上代码 dataset 可以选择 cifar10,cifar100,imagenet,mnist 等。其图像格式是channel_first。foolbox将数据集包装的确实方便,就单独拎出来讲了。
Output:
2.3 CW有目标及无目标实例
import time
# 画图而已
def plot_clean_and_adver(adver_example,adver_target,clean_example,clean_target,attack_name):
n_cols = 2
n_rows = 5
cnt = 1
cnt1 = 1
plt.figure(figsize=(4*n_rows,2*n_cols))
for i in range(n_cols):
for j in range(n_rows):
plt.subplot(n_cols,n_rows*2,cnt1)
plt.xticks([])
plt.yticks([])
if j == 0:
plt.ylabel(attack_name,size=15)
plt.title("{} -> {}".format(clean_target[cnt-1], adver_target[cnt-1]))
plt.imshow(clean_example[cnt-1].reshape(28,28).to('cpu').detach().numpy(),cmap='gray')
plt.subplot(n_cols,n_rows*2,cnt1+1)
plt.xticks([])
plt.yticks([])
# plt.title("{} -> {}".format(clean_target[cnt], adver_target[cnt]))
plt.imshow(adver_example[cnt-1].reshape(28,28).to('cpu').detach().numpy(),cmap='gray')
cnt = cnt + 1
cnt1 = cnt1 + 2
plt.show()
print ('n')
# CW有目标攻击实现
def CW_target():
start = time.time()
criterion = TargetedMisclassification(torch.tensor([4]*batch_size,device = device))
# 如下一行代码,定义攻击类型,其中攻击参数在此给定,参考github相应源码
attack = fb.attacks.L2CarliniWagnerAttack()
# 如下一行代码所示,实现有目标攻击。如下写法具有普适性
raw, clipped, is_adv = attack(fmodel,images.to(device),epsilons=0.2,criterion = criterion)
adver_target = torch.max(fmodel(raw),1)[1]
plot_clean_and_adver(raw,adver_target,images,labels,'CW targeted')
end = time.time()
print ('CW target running {} seconds using google colab GPU'.format((end-start)))
# CW无目标攻击实现
def CW_untarget():
start = time.time()
# criterion = TargetedMisclassification(torch.tensor([4]*batch_size,device = device))
# 如下一行代码,定义攻击类型,其中攻击参数在此给定,参考github相应源码
attack = fb.attacks.L2CarliniWagnerAttack()
# 如下一行代码所示,实现无目标攻击。如下写法具有普适性
raw, clipped, is_adv = attack(fmodel,images.to(device),labels.to(device),epsilons=0.2)
adver_target = torch.max(fmodel(raw),1)[1]
plot_clean_and_adver(raw,adver_target,images,labels,'CW untargeted')
end = time.time()
print ('CW untargeted running {} seconds using google colab GPU'.format((end-start)))
CW_target()
CW_untarget()
- 如上fmodel = fb.PyTorchModel(model,bounds=(0,1)),将我们自己训练出来的模型适配foolbox的torch模型
- 通过 attack = fb.attacks.L2CarliniWagnerAttack() 定义攻击方式。其参数均在类中的__init__中有初始化,也可自己设置。那有什么超参数呢?转至github查看
最关键的代码解释如下:
- 无目标攻击 raw, clipped, is_adv = attack(fmodel,data.to(device),target.to(device),epsilons=0.1)
- 有目标攻击: raw, clipped, is_adv = attack(fmodel,data.to(device),epsilons=0.15,criterion = criterion)
- 可以发现 有无目标攻击 有一点不同就是是否含有target,其实这很好理解。无目标攻击需要样本target,告诉模型,只要最终判定的类别不为target即可;有目标攻击提供criterion参数,告诉了模型该如何定向分类
- 如上还能发现epsilons参数都存在,该参数是必要参数。这是设定了像素点最大变化大小。如上attack实际返回了三个变量。raw就是正常攻击产生的对抗样本,clipped就是通过epsilons剪裁生成的对抗样本。is_adv包含每个样本的布尔值,指示raw中哪些样本它们既被错误分类又在干净样本周围的 epsilon 内。看不懂?见官网表述
Output:
2.4. foolbox杂谈
# 准确率测试
# 该函数就是模型的test,将images与labels输入就能判断,模型正确分类的准确率。
# 在这里images大小是(10,1,28,28),labels大小是(10)
fb.utils.accuracy(fmodel, images, labels)
Output:
3 总结
- 通过介绍CW的有目标与无目标的实现方法。照葫芦画瓢,我们也就能实现任意的对抗样本攻击算法。
- 使用foolbox+torch调用对抗样本攻击算法是很简单的。也基本能生成常用的对抗样本。
- 在写论文的过程中,实验部分会占大量时间。我们可以直接调用对抗样本库进行性能测试,站在巨人肩膀上看世界。另:也能读github上的源代码更加深刻理解相应的对抗样本攻击算法。
附录
MY Coding:
- google colab平台实现
最后
以上就是无辜纸鹤为你收集整理的对抗样本库之foolbox的全部内容,希望文章能够帮你解决对抗样本库之foolbox所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复