专栏名称: 机器之心
专业的人工智能媒体和产业服务平台
目录
相关文章推荐
AI范儿  ·  Manus 没有秘密,70 ... ·  昨天  
AI范儿  ·  Manus 没有秘密,70 ... ·  昨天  
机器学习研究组订阅  ·  奥特曼自曝全新OpenAI写作模型:第一次被 ... ·  昨天  
爱可可-爱生活  ·  【[7.5k星]TypeScript-Go: ... ·  2 天前  
宝玉xp  ·  回复@八月_Yuki:其实是 ... ·  3 天前  
51好读  ›  专栏  ›  机器之心

教程 | 经得住考验的「假图片」:用TensorFlow为神经网络生成对抗样本

机器之心  · 公众号  · AI  · 2017-08-12 09:33

正文

选自arXiv

作者:Anish Athalye

机器之心编译

参与:李泽南


用于识别图片中物体的神经网络可以被精心设计的对抗样本欺骗,而这些在人类看起来没有什么问题的图片是如何产生的呢?最近,来自 OpenAI 的研究者 Anish Athalye 等人撰文介绍了他们使用 TensorFlow 制作「假图片」的方法。


为神经网络加入对抗样本是一个简单而有意义的工作:仔细设计的「扰动」输入可以让神经网络受到分类任务上的挑战。这些对抗样本如果应用到现实世界中可能会导致安全问题,因此非常值得关注。



仅仅加入一些特殊的噪点,图像识别系统就会把大熊猫认作是长臂猿——而且是 99% 置信度。想象一下,如果无人驾驶汽车遇到了这种情况……


在本文中,我们将简要介绍用于合成对抗样本的算法,并将演示如何将其应用到 TensorFlow 中,构建稳固对抗样本的方法。


Jupyter notebook 可执行文件:http://www.anishathalye.com/media/2017/07/25/adversarial.ipynb


设置


我们选择攻击用 ImageNet 训练的 Inception v3 模型。在这一节里,我们会从 TF-slim 图像分类库中加载一个预训练的神经网络。

  1. import tensorflow as tf

  2. import tensorflow.contrib.slim as slim

  3. import tensorflow.contrib.slim.nets as nets



  1. tf.logging.set_verbosity(tf.logging.ERROR)

  2. sess = tf.InteractiveSession()


首先,我们需要设置一张输入图片。我们使用 tf.Variable 而非 tf.placeholder 是因为我们会需要让数据可被训练,这样我们就可以在需要时继续输入。


  1. image = tf.Variable(tf.zeros((299, 299, 3)))


随后,我们加载 Inception v3 模型。


  1. def inception(image, reuse):

  2.    preprocessed = tf.multiply(tf.subtract(tf.expand_dims(image, 0), 0.5), 2.0)

  3.    arg_scope = nets.inception.inception_v3_arg_scope(weight_decay=0.0)

  4.    with slim.arg_scope(arg_scope):

  5.        logits, _ = nets.inception.inception_v3(

  6.            preprocessed, 1001, is_training=False, reuse=reuse)

  7.        logits = logits[:,1:] # ignore background class

  8.        probs = tf.nn.softmax(logits) # probabilities

  9.    return logits, probs

  10. logits, probs = inception(image, reuse=False)



接下来,我们加载预训练权重。这种 Inception v3 模型的 top-5 正确率为 93.9%。


  1. import tempfile

  2. from urllib.request import urlretrieve

  3. import tarfile

  4. import os


  1. data_dir = tempfile.mkdtemp()

  2. inception_tarball, _ = urlretrieve(

  3.    'http://download.tensorflow.org/models/inception_v3_2016_08_28.tar.gz')

  4. tarfile.open(inception_tarball, 'r:gz').extractall(data_dir)


  1. restore_vars = [

  2.    var for var in tf.global_variables()

  3.    if var.name.startswith('InceptionV3/')

  4. ]

  5. saver = tf.train.Saver(restore_vars)

  6. saver.restore(sess, os.path.join(data_dir, 'inception_v3.ckpt'))


接下来,我们编写代码来显示一张图片,对其进行分类,并显示分类结果。


  1. import json

  2. import matplotlib.pyplot as plt



  1. imagenet_json, _ = urlretrieve(

  2.    'http://www.anishathalye.com/media/2017/07/25/imagenet.json')

  3. with open(imagenet_json) as f:

  4.    imagenet_labels = json.load( f)


  1. def classify(img, correct_class=None, target_class=None):

  2.    fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 8))

  3.    fig.sca(ax1)

  4.    p = sess.run(probs, feed_dict={image: img})[0]

  5.    ax1.imshow(img)

  6.    fig.sca(ax1)

  7.    topk = list(p.argsort()[-10:][::-1])

  8.    topprobs = p[topk]

  9.    barlist = ax2.bar(range(10), topprobs)

  10.    if target_class in topk:

  11.        barlist[topk.index(target_class)].set_color('r')

  12.    if correct_class in topk:

  13.        barlist[topk .index(correct_class)].set_color('g')

  14.    plt.sca(ax2)

  15.    plt.ylim([0, 1.1])

  16.    plt.xticks(range(10),

  17.               [imagenet_labels[i][:15] for i in topk],

  18.               rotation='vertical')

  19.    fig.subplots_adjust(bottom=0.2)

  20.    plt.show()


示例图片


我们加载示例图片,并确认它们已被正确分类。


  1. import PIL

  2. import numpy as np


  1. img_path, _ = urlretrieve('http://www.anishathalye.com/media/2017/07/25/cat.jpg')

  2. img_class = 281

  3. img = PIL.Image.open(img_path)

  4. big_dim = max(img.width , img.height)

  5. wide = img.width > img.height

  6. new_w = 299 if not wide else int(img.width * 299 / img.height)

  7. new_h = 299 if wide else int(img.height * 299 / img.width)

  8. img = img.resize((new_w, new_h)).crop((0, 0, 299, 299))

  9. img = (np.asarray(img) / 255.0).astype(np.float32)


  1. classify(img, correct_class=img_class







请到「今天看啥」查看全文