对抗样本库之cleverhans

1 前言

  • 对抗样本库,即进行对抗样本攻击或防御的工具。cleverhans,foolbox,advertorch这三个对抗样本库是比较常用的。github搜索关键字即可找到。
  • cleverhans在github有5k个star,foolbox 2k个star,advertorch 1k个star。通过该信息自然大家都会选择使用cleverfans。
  • cleverhans在之前的版本中只支持tensorflow。如果习惯使用tensorflow,完全可以pip install cleverhans == v3.1.0,下载之前的版本,其中包括很全面的对抗样本攻击。
  • 相较而言,我更喜欢使用torch,这就需要下载cleverhans的最新版本,直接pip install cleverhans即可。这个版本兼容torch,tensorflow以及jax,但是这个版本的库仍然在github维护中,其中只包括部分对抗样本攻击实现。
  • 因此本文会介绍在cleverhans最新版本下,如何使用torch来实现对抗样本的攻击。

2 cleverhans使用

实验步骤:

  1. 构建并训练网络模型
  2. 使用cleverhans实现PGD,DeepFool以及CW攻击
  3. 可视化
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
# 生成对抗样本的个数
adver_nums = 1000


# 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()
      # 如下有两种你形式表达,一种是原生,一种是使用optim优化函数直接更新参数
      # 为什么原生的训练方式没有效果???代表参数没有更新,就离谱。
      # 下面的detach与requires_grad_有讲究哦,终于明白了;但是为什么下面代码不能work还是没搞懂
      # for params in model.parameters():
      #   params = (params - learning_rate * params.grad).detach().requires_grad_()
      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 cleverhans攻击及可视化
  • 以下代码完成CW,PGD以及DeepFool 攻击
from cleverhans.torch.attacks.fast_gradient_method import fast_gradient_method  
from cleverhans.torch.attacks.carlini_wagner_l2 import carlini_wagner_l2
from cleverhans.torch.attacks.projected_gradient_descent import projected_gradient_descent

def PGD(model):
  adver_example = None
  adver_target = None
  clean_example = None
  clean_target = None
  for i,(data,target) in enumerate(test_loader):
    if i>=1:
      break
    # model_fn = lambda x:F.nll_loss(model(x),target.to(device))
    adver_example = projected_gradient_descent(model, data.to(device),0.1,0.05,40,np.inf)
    adver_target = torch.max(model(adver_example),1)[1]
    clean_example = data
    clean_target = target
  return adver_example,adver_target,clean_example,clean_target,'PGD attack'

def FGSM(model):
  adver_example = None
  adver_target = None
  clean_example = None
  clean_target = None
  for i,(data,target) in enumerate(test_loader):
    if i>=1:
      break
    # model_fn = lambda x:F.nll_loss(model(x),target.to(device))
    adver_example = fast_gradient_method(model, data.to(device), 0.1, np.inf)
    adver_target = torch.max(model(adver_example),1)[1]
    clean_example = data
    clean_target = target
  return adver_example,adver_target,clean_example,clean_target,'FGSM attack'

def CW(model):
  adver_example = None
  adver_target = None
  clean_example = None
  clean_target = None
  for i,(data,target) in enumerate(test_loader):
    if i>=1:
      break
    # model_fn = lambda x:F.nll_loss(model(x),target.to(device))
    adver_example = carlini_wagner_l2(model, data.to(device), 10, y = torch.tensor([3]*batch_size,device = device) ,targeted = True)
    adver_target = torch.max(model(adver_example),1)[1]
    clean_example = data
    clean_target = target
  return adver_example,adver_target,clean_example,clean_target,'CW attack'
# print (adver_target.shape)

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')

adver_example,adver_target,clean_example,clean_target,attack_name= FGSM(simple_model)
plot_clean_and_adver(adver_example,adver_target,clean_example,clean_target,attack_name)

# CW能实现有目标以及无目标攻击
adver_example,adver_target,clean_example,clean_target,attack_name= CW(simple_model)
plot_clean_and_adver(adver_example,adver_target,clean_example,clean_target,attack_name)


adver_example,adver_target,clean_example,clean_target,attack_name= PGD(simple_model)
plot_clean_and_adver(adver_example,adver_target,clean_example,clean_target,attack_name)
  • 如上代码,调用cleverhans的攻击函数很简单。如FGM攻击方式,只需调用如下代码即可 f a s t _ g r a d i e n t _ m e t h o d ( m o d e l , d a t a . t o ( d e v i c e ) , 0.1 , n p . i n f ) fast\_gradient\_method(model, data.to(device), 0.1, np.inf) fast_gradient_method(model,data.to(device),0.1,np.inf)。其中 m o d e l model model 就是自己训练的模型, d a t a data data 就是干净样本数据, n p . i n f np.inf np.inf 就是 L ∞ L_\infty L 攻击,那个 0.1 0.1 0.1 就是epsilon ( ϵ \epsilon ϵ) 。
  • 由于cleverhans的攻击源代码是函数(而非类)实现,使用起来就更加方便。可能你会有这样的疑问?那不同攻击方式的参数如何设置,如何进行有目标攻击以及无目标攻击?Simple,just go down
  • 直接去cleverhans中的github页面,跳转。进入相应的攻击的文件,其函数输入变量的注释写的很清楚。如下图(只截图部分):
    在这里插入图片描述

Output:
在这里插入图片描述在这里插入图片描述

3 总结

  1. 我对torch的心是不会变的。但是cleverhans(v4.0.0)+torch 仅仅只能实现一点点对抗样本攻击,就这几个对抗样本攻击跳转。当然如果你的偏好是tensorflow,那就使用cleverhans v3.1.0版本的吧,里面的攻击方式很全面。
  2. 说到这里,可以看出cleverhans(v4.0.0)+torch已经不能满足我的欲望。因此 foolbox+torch的使用之旅即将开始!!!

附录

参考资料:

  1. cleverhans 源码库
  2. cleverhans blogs,并没什么用。

源代码:

  • 5
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
对抗样本是指通过对输入数据进行微小改动,就能够欺骗人工智能系统,导致系统产生误判或错误行为的样本。对抗样本是AI安全领域的一个重要问题,因为它可能导致人工智能系统在实际应用中产生严重后果。 对抗样本生成方法有很多,包括添加噪音、修改像素值等。对抗样本的目的是让系统误判,以此来测试和评估AI系统的安全性和鲁棒性。对抗样本的设计是一个技术活,需要深入理解AI模型的工作原理,并且具备一定的数学和算法基础。 对抗样本研究的目标之一是找到一种普遍适用于各种AI模型的对抗样本生成方法。目前已经有一些方法被提出,如FGSM(快速梯度符号法)、PGD(投影梯度下降法)等。这些方法通过在输入样本中添加或修改一些微小的扰动,能够使得AI系统出现误判。 AI安全领域研究对抗样本的目的是提高AI系统的鲁棒性和安全性。通过研究对抗样本,可以帮助发现和修复AI系统在实际应用中存在的漏洞和缺陷。同时,对抗样本的研究也有助于推动AI系统的发展,使其更加健壮和可靠。 然而,对抗样本也可能被恶意使用,例如攻击识别系统、篡改图像等。因此,研究对抗样本不仅要关注如何生成对抗样本,还要关注如何防御和抵抗对抗样本攻击。AI安全研究者需要不断改进算法和技术,提高AI系统的对抗样本鲁棒性。 总之,对抗样本是AI安全领域的一个重要问题。研究对抗样本有助于发现和修复AI系统的漏洞和缺陷,提高AI系统的鲁棒性和安全性。然而,对抗样本研究也需要关注如何防御和抵抗对抗样本攻击,以确保AI系统能够在实际应用中的安全可靠性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值