1. 磐创AI-开放猫官方网站首页
  2. 系列教程
  3. PyTorch

PyTorch专栏(十二):一文综述图像对抗算法

本文是全系列中第21 / 24篇:Pytorch 专栏

PyTorch专栏(十二):一文综述图像对抗算法

作者 | News

编辑 | 奇予纪

出品 | 磐创AI团队出品

【磐创AI 导读】:本篇文章讲解了PyTorch专栏的第四章中的生成对抗示例。本教程将提高您对ML(机器学习)模型的安全漏洞的认知,并将深入了解对抗性机器学习的热门话题。查看专栏历史文章,请点击下方蓝色字体进入相应链接阅读。查看关于本专栏的介绍:PyTorch专栏开篇。想要更多电子杂志的机器学习,深度学习资源,大家欢迎点击上方蓝字关注我们的公众号:磐创AI


专栏目录:
第一章:PyTorch之简介与下载
  • PyTorch简介
  • PyTorch环境搭建
第二章:PyTorch之60分钟入门
第三章:PyTorch之入门强化
第四章:PyTorch之图像篇
  • 微调基于torchvision 0.3的目标检测模型
  • 微调TorchVision模型
  • 空间变换器网络
  • 使用PyTorch进行神经传递
  • 生成对抗示例
  • 使用ONNX将模型转移至Caffe2和移动端
第五章:PyTorch之文本篇
  • 聊天机器人教程
  • 使用字符级RNN生成名字
  • 使用字符级RNN进行名字分类
  • 在深度学习和NLP中使用Pytorch
  • 使用Sequence2Sequence网络和注意力进行翻译
第六章:PyTorch之生成对抗网络
第七章:PyTorch之强化学习


PyTorch专栏(十二):一文综述图像对抗算法

生成对抗示例

本教程将提高您对ML(机器学习)模型的安全漏洞的认识,并将深入了解对抗性机器学习的热门话题。您可能会惊讶地发现,为图像添加难以察觉的扰动会导致模型性能大不相同。鉴于这是一个教程,我们将通过图像分类器上的示例探讨该主题。具体来说,我们将使用第一种也是最流行的攻击方法之一,即快速梯度符号攻击算法(FGSM)来迷惑 MNIST 分类器。

1.威胁模型

对于上下文,有许多类别的对抗性攻击,每种攻击具有不同的目标和对攻击者知识的假设。然而,通常,总体目标是向输入数据添加最少量的扰动以引起期望的错误分类。

对攻击者的知识有几种假设,其中两种是:白盒子和黑盒子。白盒攻击假定攻击者具有对模型的全部知识和访问权限,包括体系结构、输入、输出和权重。黑盒攻击假设攻击者只能访问模型的输入和输出,并且对底层架构或权重一无所知。还有几种类型的目标,包括错误分类和源/目标错误分类。错误分类的目标意味着攻击者只希望输出分类错误,但不关心新分类是什么。源/目标错误分类意味着攻击者想要更改最初属于特定源类的图像,以便将其归类为特定目标类。

FGSM 攻击是一种白盒攻击,其目标是错误分类。有了这些背景信息,我们现在可以详细讨论攻击。

2.FGSM(Fast Gradient Sign Attack)

快速梯度标志攻击(FGSM),是迄今为止最早和最受欢迎的对抗性攻击之一,它由 Goodfellow 等人在[Explaining and Harnessing Adversarial Examples]
(https://arxiv.org/abs/1412.6572)中提出,是一种简单但是有效的对抗样本生成算法。它旨在通过利用模型学习的方式和渐变来攻击神经网络。这个想法很简单,攻击调整输入数据以基于相同的反向传播梯度来最大化损失,而不是通过基于反向传播的梯度调整权重来最小化损失。换句话说,攻击是利用损失函数的梯度,然后调整输入数据以最大化损失。

在进入代码之前,先讲一下著名的 FGSM 熊猫示例并提取一些符号。

PyTorch专栏(十二):一文综述图像对抗算法

从图中可以看出,PyTorch专栏(十二):一文综述图像对抗算法是正确分类为“熊猫”的原始输入图像,PyTorch专栏(十二):一文综述图像对抗算法PyTorch专栏(十二):一文综述图像对抗算法的基本事实标签,
PyTorch专栏(十二):一文综述图像对抗算法代表模型参数,PyTorch专栏(十二):一文综述图像对抗算法是用于训练网络的损失。攻击是反向将梯度传播回输入数据以计算PyTorch专栏(十二):一文综述图像对抗算法

然后,它在一个方向上(即PyTorch专栏(十二):一文综述图像对抗算法)调整输入数据(图中的PyTorch专栏(十二):一文综述图像对抗算法或0.007),这将使损失最大化。然后,当目标网络仍然明显是“熊猫”时,由此产生的扰动图像PyTorch专栏(十二):一文综述图像对抗算法被错误地分类为“长臂猿”。

3.实现

在本节中,我们将讨论教程的输入参数,定义被攻击的模型,然后编写攻击代码并运行一些测试。

3.1 引入相关包

  1. from __future__ import print_function

  2. import torch

  3. import torch.nn as nn

  4. import torch.nn.functional as F

  5. import torch.optim as optim

  6. from torchvision import datasets, transforms

  7. import numpy as np

  8. import matplotlib.pyplot as plt

3.2 输入

本教程只有三个输入,定义如下:

  • epsilons:用于运行的epsilon值列表。在列表中保留0非常重要,因为它表示原始测试集上的模型性能。而且,我们期望epsilon越大,扰动就越明显,但就降低模型精度方面而言攻击越有效。由于此处的数据范围为[0,1],因此epsilon值不应超过1。

  • pretrained_model:pytorch/examples/mnist训练的预训练 MNIST模型的路径。为简单起见,请在此处下载预训练模型。

  • use_cuda:如果需要和可使用CUDA的布尔标志。注意,带有CUDA的GPU对本教程并不重要,因为本教程使用CPU不会花费太多时间。

epsilons = [0, .05, .1, .15, .2, .25, .3]pretrained_model = "data/lenet_mnist_model.pth"use_cuda=True

3.3 被攻击的模型

如上所述,受攻击的模型与pytorch/examples/mnist中的 MNIST 模型相同。您可以训练并保存自己的 MNIST 模型,也可以下载并使用提供的模型。此处的 Net 定义和测试数据加载器已从 MNIST 示例中复制。

本小节的目的是定义模型和数据加载器,然后初始化模型并加载预训练的权重。

  1. # 定义LeNet模型

  2. class Net(nn.Module):

  3. def __init__(self):

  4. super(Net, self).__init__()

  5. self.conv1 = nn.Conv2d(1, 10, kernel_size=5)

  6. self.conv2 = nn.Conv2d(10, 20, kernel_size=5)

  7. self.conv2_drop = nn.Dropout2d()

  8. self.fc1 = nn.Linear(320, 50)

  9. self.fc2 = nn.Linear(50, 10)


  10. def forward(self, x):

  11. x = F.relu(F.max_pool2d(self.conv1(x), 2))

  12. x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2))

  13. x = x.view(-1, 320)

  14. x = F.relu(self.fc1(x))

  15. x = F.dropout(x, training=self.training)

  16. x = self.fc2(x)

  17. return F.log_softmax(x, dim=1)


  18. #声明 MNIST 测试数据集何数据加载

  19. test_loader = torch.utils.data.DataLoader(

  20. datasets.MNIST('../data', train=False, download=True, transform=transforms.Compose([

  21. transforms.ToTensor(),

  22. ])),

  23. batch_size=1, shuffle=True)


  24. # 定义我们正在使用的设备

  25. print("CUDA Available: ",torch.cuda.is_available())

  26. device = torch.device("cuda" if (use_cuda and torch.cuda.is_available()) else "cpu")


  27. # 初始化网络

  28. model = Net().to(device)


  29. # 加载已经预训练的模型

  30. model.load_state_dict(torch.load(pretrained_model, map_location='cpu'))


  31. # 在评估模式下设置模型。在这种情况下,这适用于Dropout图层

  32. model.eval()

  • 输出结果:

  1. Downloading http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz to ../data/MNIST/raw/train-images-idx3-ubyte.gz

  2. Extracting ../data/MNIST/raw/train-images-idx3-ubyte.gz

  3. Downloading http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz to ../data/MNIST/raw/train-labels-idx1-ubyte.gz

  4. Extracting ../data/MNIST/raw/train-labels-idx1-ubyte.gz

  5. Downloading http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz to ../data/MNIST/raw/t10k-images-idx3-ubyte.gz

  6. Extracting ../data/MNIST/raw/t10k-images-idx3-ubyte.gz

  7. Downloading http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz to ../data/MNIST/raw/t10k-labels-idx1-ubyte.gz

  8. Extracting ../data/MNIST/raw/t10k-labels-idx1-ubyte.gz

  9. Processing...

  10. Done!

  11. CUDA Available: True