AI 安全之对抗样本入门 (37):打造对抗样本工具箱 3.6&3.7

阅读数:6 2019 年 11 月 30 日 15:14

AI安全之对抗样本入门(37):打造对抗样本工具箱 3.6&3.7

(使用预训练模型)

内容简介
第 1 章介绍了深度学习的基础知识,重点介绍了与对抗样本相关的梯度、优化器、反向传递等知识点。
第 2 章介绍了如何搭建学习对抗样本的软硬件环境,虽然 GPU 不是必需的,但是使用 GPU 可以更加快速地验证你的想法。
第 3 章概括介绍了常见的深度学习框架,从 TensorFlow、Keras、PyTorch 到 MXNet。
第 4 章介绍了图像处理领域的基础知识,这部分知识对于理解对抗样本领域的一些常见图像处理技巧非常有帮助。
第 5 章介绍了常见的白盒攻击算法,从基础的 FGSM、DeepFool 到经典的 JSMA 和 CW。
第 6 章介绍了常见的黑盒攻击算法。
第 7 章介绍了对抗样本在目标识别领域的应用。
第 8 章介绍了对抗样本的常见抵御算法,与对抗样本一样,抵御对抗样本的技术也非常有趣。
第 9 章介绍了常见的对抗样本工具以及如何搭建 NIPS 2017 对抗防御环境和轻量级攻防对抗环境 robust-ml,通过这章读者可以了解如何站在巨人的肩膀上,快速生成自己的对抗样本,进行攻防对抗。

在对深度学习模型生成对抗样本时,我们会经常使用预训练好的模型。主流的深度学习框架为了方便用户使用,都积极开放了经典模型以供下载。其中最多的还是机器视觉相关的图像分类与目标识别模型,比如:

  • ResNet50
  • VGG16
  • InceptionV3

下面我们将举例介绍如何使用预训练模型对指定的图片进行分类预测,预测的主角是一头小猪(见图 3-9)。

复制代码
from IPython.display import Image,display
path = "../picture/pig.jpg"
display(Image(filename=path))
  1. 使用 Keras 进行图片分类

Keras 的应用模块 Application 提供了带有预训练权重的 Keras 模型,这些模型可以用来进行预测、特征提取。模型的预训练权重将下载到~/.keras/models/ 并在载入模型时自动载入。

AI安全之对抗样本入门(37):打造对抗样本工具箱 3.6&3.7

图 3-9 小猪示例图片

加载需要的 Python 库,并对图像进行预处理。使用基于 Imagenet 数据集训练的 ResNet50 模型,图片大小转换成(224, 224),由于是彩色图片,事实上输入模型的图片形状为(224, 224, 3)。

复制代码
from keras.applications.resnet50 import ResNet50
from keras.preprocessing import image
from keras.applications.resnet50 import preprocess_input, decode_predictions
import numpy as np
model = ResNet50(weights='imagenet')
img_path = path
img = image.load_img(img_path, target_size=(224, 224))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
x = preprocess_input(x)

对图片进行预测,打印 top3 的预测结果,预测概率最大的是 hog,即猪。

复制代码
preds = model.predict(x)
print('Predicted:', decode_predictions(preds, top=3)[0])
Predicted:
[('n02395406', 'hog', 0.98398596),
('n02396427', 'wild_boar', 0.0074134255),
('n03935335', 'piggy_bank', 0.006954492)]
  1. 使用 PyTorch 进行图片分类

PyTorch 通过 torchvision 库封装了对预训练模型的下载和使用,这些模型可以用来进行预测、特征提取。模型的预训练权重将下载到~/.torch/models/ 并在载入模型时自动载入。

加载需要的 Python 库,并对图像进行预处理。使用基于 Imagenet 数据集训练的 ResNet50 模型,图片大小转换成(224, 224),由于是彩色图片,并且 PyTorch 在处理图片格式时信道放在第一个维度,所以事实上输入模型的图片形状为(3, 224, 224)。需要特别指出的是,PyTorch 加载预训练模型后默认是训练模式,所以在进行图片预测时需要手工调用 eval 方法进入预测模式,关闭反向传递。

复制代码
import os
import numpy as np
import torch
import torch.nn
import torchvision.models as models
from torch.autograd import Variable
import torch.cuda
import torchvision.transforms as transforms
from PIL import Image
#手工调用 eval 方法进入预测模式
resnet50=models.resnet50(pretrained=True).eval()
img=Image.open(path)
img=img.resize((224,224))
img = np.array(img).copy().astype(np.float32)

在 Keras 处理图片时,我们没有进行任何标准化的处理,这是因为这一步被 Keras 的 keras.applications.resnet50.preprocess_input 封装了,而在 PyTorch 中需要我们手工进行标准化。

复制代码
mean = [0.485, 0.456, 0.406]
std = [0.229, 0.224, 0.225]
img /= 255.0
img = (img - mean) / std
img = img.transpose(2, 0, 1)
img=np.expand_dims(img, axis=0)
img = Variable(torch.from_numpy(img).float())

对图片进行预测,预测标签索引是 341,对应的是 hog,即猪。

复制代码
label=np.argmax(resnet50(img).data.cpu().numpy())
print("label={}".format(label))
label=341

预测的标签与分类物体名称的对应关系可以参考下列内容。

复制代码
https://s3.amazonaws.com/deep-learning-models/image-models/imagenet_class_index.json

也可以使用 PyTorch 的 API 完成从分类标签值到物品名称之间的转换。

复制代码
print('Predicted:', decode_predictions(resnet50(img).data.cpu().numpy(),
top=3)[0])
Predicted:
[('n02395406', 'hog', 15.661886),
('n02396427', 'wild_boar', 10.353137),
('n03935335', 'piggy_bank', 10.098382)]
  1. 使用 MXNet 进行图片分类

MXNet 通过 gluon 库封装了对预训练模型的下载和使用,这些模型可以用来进行预测、特征提取。模型的预训练权重将下载到~/.mxnet/models/ 并在载入模型时自动载入,更多模型可以参考以下链接。

复制代码
http://mxnet.incubator.apache.org/versions/master/api/python/gluon/model_zoo.html

加载需要的 Python 库,并对图像进行预处理。使用基于 Imagenet 数据集训练的 ResNet50 模型,图片大小转换成(224, 224),由于是彩色图片,并且 MXNet 在处理图片格式时信道放在第一个维度,所以事实上输入模型的图片形状为(3, 224, 224)。

复制代码
from mxnet import gluon
import mxnet as mx
from mxnet.gluon import nn
from mxnet import ndarray as nd
from mxnet import autograd
import numpy as np
resnet=mx.gluon.model_zoo.vision.resnet50_v2(pretrained=True)
img=Image.open(path)
img=img.resize((224,224))
img = np.array(img).copy().astype(np.float32)

MXNet 对图像的预处理与 Pytorch 一样需要手工进行。

复制代码
mean = [0.485, 0.456, 0.406]
std = [0.229, 0.224, 0.225]
img /= 255.0
img = (img - mean) / std
img = img.transpose(2, 0, 1)

对图片进行预测,预测标签索引是 341,对应的是 hog,即猪。

复制代码
img=np.expand_dims(img, axis=0)
array = mx.nd.array(img)
outputs=resnet(array).asnumpy()
label = np.argmax(outputs)
print(label)
  1. 使用 TensorFlow 进行图片分类

TensorFlow 的模型多以 pb 文件形式保存。以 Inception 为例,模型文件为 pb 格式,其中的 classify_image_graph_def.pb 文件就是训练好的 Inception 模型,imagenet_synset_to_human_label_map.txt 是类别文件。

复制代码
wget
http://download.tensorflow.org/models/image/imagenet/inception-2015-12-05.tgz
tar -zxvf inception-2015-12-05.tgz
x classify_image_graph_def.pb
x cropped_panda.jpg
x imagenet_2012_challenge_label_map_proto.pbtxt
x imagenet_synset_to_human_label_map.txt
x LICENSE

图片数据的预处理在 Inception 的计算图中完成。

复制代码
path = "../picture/pig.jpg"
image_data = tf.gfile.FastGFile(path, "rb").read()

加载 pb 文件,在会话中还原完整的计算图以及网络中的各层参数。

复制代码
session=tf.Session()
def create_graph(dirname):
with tf.gfile.FastGFile(dirname, 'rb') as f:
graph_def = session.graph_def
graph_def.ParseFromString(f.read())
_ = tf.import_graph_def(graph_def, name='')
create_graph("models/classify_image_graph_def.pb")
session.run(tf.global_variables_initializer())

获取输入节点和输出节点,运行计算图获得结果,预测标签是 hog,即猪。

复制代码
logits=session.graph.get_tensor_by_name('softmax/logits:0')
x = session.graph.get_tensor_by_name('DecodeJpeg/contents:0')
predictions=session.run(logits,feed_dict={x:image_data})
predictions = np.squeeze(predictions)
top_k = predictions.argsort()[-3:][::-1]
for node_id in top_k:
human_string = node_lookup.id_to_string(node_id)
score = predictions[node_id]
print('%s (score = %.5f)' % (human_string, score))

以下代码展示了一个技巧,可以把 pb 文件的结构打印出来,有利于识别整个计算图的输入 / 输出。

复制代码
tensorlist=[n.name for n in session.graph_def.node]
print(tensorlist)

TensorFlow 还提供了大量 ckpt 格式的预训练模型,也需要手工下载后加载使用。ckpt 文件相当于只保存了网络的参数,如果要完整使用,需要自行定义网络的结构。

复制代码
wget http://download.tensorflow.org/models/resnet_v2_50_2017_04_14.tar.gz
tar -zxvf resnet_v2_50_2017_04_14.tar.gz

TensorFlow 提供了大量工具函数便于使用预训练模型,需要单独安装并设置到系统路径。

复制代码
git clone https://github.com/tensorflow/models/

通常设置系统路径最简单的方式是在代码里指定,比如:

复制代码
sys.path.append("models/models/research/slim/")

TensorFlow 通过 slim 定义了大量常见的网络结构,以 resnet 为例,就在 slim/nets/resnet_v2 完成了其网络定义。

复制代码
from nets import resnet_v2

slim 对数据预处理以及归一化做了封装,可以直接调用相应的 API 完成。TensorFlow 的预训练模型在预测时需要显式指定 is_training=False 来关闭反向传递。

复制代码
path = "../picture/pig.jpg"
image = tf.image.decode_jpeg(tf.gfile.FastGFile(path,'rb').read(), channels=3)
image_size = resnet_v2_50.default_image_size
processed_image = inception_preprocessing.preprocess_image(image, image_size,
image_size, is_training=False)
processed_images = tf.expand_dims(processed_image, 0)

使用 tf.train.Saver 从 ckpt 文件中加载网络参数值,需要指出的是 resnet_v1 版本是从 Caffe 转换得来的,resnet_v2 版本是 Google 自己训练的,物体类别不是 1000 而是 1001。

复制代码
with slim.arg_scope(resnet_v2.resnet_arg_scope()):
logits, _ = resnet_v2.resnet_v2_50(processed_images, num_classes=1001,
is_training=False)
probabilities = tf.nn.softmax(logits)
saver=tf.train.Saver()
with tf.Session() as sess:
saver.restore(sess,'models/resnet_v2_50/resnet_v2_50.ckpt')

然后输入图像数据,运行计算图进行预测。

复制代码
np_image, probabilities = sess.run([image, probabilities])
probabilities = probabilities[0, 0:]
sorted_inds = [i[0] for i in sorted(enumerate(-probabilities), key=lambda x:x[1])]

输出对应的预测结果,预测为猪的概率为 99.08%。

复制代码
Probability 99.08% => [hog, pig, grunter, squealer, Sus scrofa]
Probability 0.84% => [piggy bank, penny bank]
Probability 0.03% => [wild boar, boar, Sus scrofa]
Probability 0.01% => [French bulldog]
Probability 0.01% => [hippopotamus, hippo, river horse, Hippopotamus amphibius]

值得一提的是,slim 封装了将标签数据转换成物体名称的操作,省去了手工解析的过程。

复制代码
names = imagenet.create_readable_names_for_imagenet_labels()
for i in range(5):
index = sorted_inds[i]
print('Probability %0.2f%% => [%s]'
% (probabilities[index] * 100, names[index]))

(本章小结)

读者通过本章可以掌握深度学习框架中的张量和计算图的概念,目前主流的深度学习框架在底层设计上几乎都是基于张量和计算图的。本章具体介绍如何基于 TensorFlow、Keras、PyTorch 和 MXNet 来解决经典的手写数字识别的问题,详细介绍了如何构建前向计算过程和使用反向传递过程。本章最后介绍了如何使用预训练模型进行图片的预测。

AI安全之对抗样本入门(37):打造对抗样本工具箱 3.6&3.7

购书地址 https://item.jd.com/12532163.html?dist=jd

评论

发布