我是靠谱客的博主 无辜纸鹤,最近开发中收集的这篇文章主要介绍对抗样本库之foolbox,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

目录

      • 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使用

实验步骤:

  1. 构建并训练网络模型
  2. 使用foolbox加载数据集(由于封装比较方便,因此单独讲下)
  3. CW进行有目标以及无目标实例
  4. 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所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(45)

评论列表共有 0 条评论

立即
投稿
返回
顶部