博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
手把手教你使用TensorFlow生成对抗样本 | 附源码
阅读量:7071 次
发布时间:2019-06-28

本文共 8454 字,大约阅读时间需要 28 分钟。

更多深度文章,请关注:

如果说卷积神经网络是昔日影帝的话,那么生成对抗已然成为深度学习研究领域中一颗新晋的耀眼新星,它将彻底地改变我们认知世界的方式。对抗学习训练为指导人工智能完成复杂任务提供了一个全新的思路,生成对抗图片能够非常轻松的愚弄之前训练好的分类器,因此如何利用生成对抗图片提高系统的鲁棒性是一个很有研究的热点问题。

神经网络合成的容易让人大吃一惊,这是因为对输入进行小巧精心制作的扰动可能导致神经网络以任意选择的方式输入进行错误地分类。鉴于对抗样本因此这是一个值得关注的安全问题。比如说人脸识别,若一张对抗图像也被识别为真人的话,就会出现一些安全隐患及之后带来的巨大损失。对生成对抗图像感兴趣的读者可以关注一下最近的Kaggle挑战赛NIPS,相关的信息可以参看博主的另外一篇:

在这篇文章中,将手把手带领读者利实现一个简单的算法合成对抗样本之后建立一个鲁棒的对抗性例子

本文是一个可执行的可以并自己实验操作一下示例

建立

我们选择攻击在训练的网络。首先我们从加载预先训练的网络。这部分不是很有趣,所以请随意跳过本部分

 
import tensorflow as tfimport tensorflow.contrib.slim as slimimport tensorflow.contrib.slim.nets as netstf.logging.set_verbosity(tf.logging.ERROR)sess = tf.InteractiveSession()

首先,设置输入图像。使用tf.Variable而不是使用tf.placeholder,这是因为要确保它是可训练的。当我们需要时,仍然可以输入它。

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

接下来,加载Inception v3模型。

def inception(image, reuse):    preprocessed = tf.multiply(tf.subtract(tf.expand_dims(image, 0), 0.5), 2.0)    arg_scope = nets.inception.inception_v3_arg_scope(weight_decay=0.0)    with slim.arg_scope(arg_scope):        logits, _ = nets.inception.inception_v3(            preprocessed, 1001, is_training=False, reuse=reuse)        logits = logits[:,1:] # ignore background class        probs = tf.nn.softmax(logits) # probabilities    return logits, probslogits, probs = inception(image, reuse=False)

接下来,加载预训练的权重。这个Inception v3的top-5确率为93.9%。

 
import tempfilefrom urllib.request import urlretrieveimport tarfileimport osdata_dir = tempfile.mkdtemp()inception_tarball, _ = urlretrieve(    'http://download.tensorflow.org/models/inception_v3_2016_08_28.tar.gz')tarfile.open(inception_tarball, 'r:gz').extractall(data_dir)restore_vars = [    var for var in tf.global_variables()    if var.name.startswith('InceptionV3/')]saver = tf.train.Saver(restore_vars)saver.restore(sess, os.path.join(data_dir, 'inception_v3.ckpt'))

接下来,编写一些代码来显示图像,对它进行分类显示分类结果。

 
import jsonimport matplotlib.pyplot as pltimagenet_json, _ = urlretrieve(    'http://www.anishathalye.com/media/2017/07/25/imagenet.json')with open(imagenet_json) as f:    imagenet_labels = json.load(f)def classify(img, correct_class=None, target_class=None):    fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 8))    fig.sca(ax1)    p = sess.run(probs, feed_dict={image: img})[0]    ax1.imshow(img)    fig.sca(ax1)        topk = list(p.argsort()[-10:][::-1])    topprobs = p[topk]    barlist = ax2.bar(range(10), topprobs)    if target_class in topk:        barlist[topk.index(target_class)].set_color('r')    if correct_class in topk:        barlist[topk.index(correct_class)].set_color('g')    plt.sca(ax2)    plt.ylim([0, 1.1])    plt.xticks(range(10),               [imagenet_labels[i][:15] for i in topk],               rotation='vertical')    fig.subplots_adjust(bottom=0.2)    plt.show()

示例图像

加载示例图像,并确保它被正确分类。

 
import PILimport numpy as npimg_path, _ = urlretrieve('http://www.anishathalye.com/media/2017/07/25/cat.jpg')img_class = 281img = PIL.Image.open(img_path)big_dim = max(img.width, img.height)wide = img.width > img.heightnew_w = 299 if not wide else int(img.width * 299 / img.height)new_h = 299 if wide else int(img.height * 299 / img.width)img = img.resize((new_w, new_h)).crop((0, 0, 299, 299))img = (np.asarray(img) / 255.0).astype(np.float32)classify(img, correct_class=img_class)

5262cfb93234605d7b5a26286ad133ceda23228e

对抗样本

给定一个图像X,神经网络输出标签上的概率分布P(y|X)。当手工制作对抗输入时,我们想要找到一个X'使得logP(y'|X')被最大化为目标标签y'输入将被错误分类为目标类通过约束一些ℓ∞半径为ε的箱,要求‖X- X'‖∞≤ε我们可以确保X'原始X看起来不太一样

在这个框架中,对抗样本是解决一个约束优化问题,可以使用投影梯度下降来解决,基本上是用训练网络本身相同的技术。算法很简单:

首先将对抗样本初始化为X'←X。然后,重复以下过程直到收敛:

1. X'←X^+α⋅logP(y'|X')

2. X'←clip(X',X - ε,X+ε)

初始化

首先从最简单的部分开始:编写一个TensorFlow op进行相应的初始化。

 
x = tf.placeholder(tf.float32, (299, 299, 3))x_hat = image # our trainable adversarial inputassign_op = tf.assign(x_hat, x)

梯度下降步骤

接下来,编写梯度下降步骤以最大化目标类的对数概率(或)。

 
learning_rate = tf.placeholder(tf.float32, ())y_hat = tf.placeholder(tf.int32, ())labels = tf.one_hot(y_hat, 1000)loss = tf.nn.softmax_cross_entropy_with_logits(logits=logits, labels=[labels])optim_step = tf.train.GradientDescentOptimizer(    learning_rate).minimize(loss, var_list=[x_hat])

投影步骤

最后,编写投影步骤,使得对抗样本在视觉上与原始图像相似。另外,将其限定[01]范围内保持有效的图像。

 
epsilon = tf.placeholder(tf.float32, ())below = x - epsilonabove = x + epsilonprojected = tf.clip_by_value(tf.clip_by_value(x_hat, below, above), 0, 1)with tf.control_dependencies([projected]):    project_step = tf.assign(x_hat, projected)

执行

最后,准备合成一个对抗样本。我们任意选择“鳄梨酱”(imagenet class 924)作为我们的目标类。

 
demo_epsilon = 2.0/255.0 # a really small perturbationdemo_lr = 1e-1demo_steps = 100demo_target = 924 # "guacamole"# initialization stepsess.run(assign_op, feed_dict={x: img})# projected gradient descentfor i in range(demo_steps):    # gradient descent step    _, loss_value = sess.run(        [optim_step, loss],        feed_dict={learning_rate: demo_lr, y_hat: demo_target})    # project step    sess.run(project_step, feed_dict={x: img, epsilon: demo_epsilon})    if (i+1) % 10 == 0:        print('step %d, loss=%g' % (i+1, loss_value))    adv = x_hat.eval() # retrieve the adversarial example
结果如下
 
step 10, loss=4.18923step 20, loss=0.580237step 30, loss=0.0322334step 40, loss=0.0209522step 50, loss=0.0159688step 60, loss=0.0134457step 70, loss=0.0117799step 80, loss=0.0105757step 90, loss=0.00962179step 100, loss=0.00886694

这种对抗图像与原始图像在视觉上无法区分,没有可见的人为加工。但是它会以很高的概率分类为“鳄梨酱”。

 
classify(adv, correct_class=img_class, target_class=demo_target)

a713c0142dc9c7fe63442402faca292c983fb78f

鲁棒的对抗样本

现在来看一个更高级的例子。遵循我们的方法来以找到猫图像的单一扰动,这在某些选择的变换分布下同时对抗可以选择任何可微分变换的分布在这篇文章中,我们将合成一个单一的对抗输入,设置θ∈[- π/4,π/4],这对旋转是鲁棒的

继续下面的工作之前,检查一下之前的例子是否能对抗旋转,比如说设置角度为θ=π/8

 
ex_angle = np.pi/8angle = tf.placeholder(tf.float32, ())rotated_image = tf.contrib.image.rotate(image, angle)rotated_example = rotated_image.eval(feed_dict={image: adv, angle: ex_angle})classify(rotated_example, correct_class=img_class, target_class=demo_target)

25ab4cd7164975cddbd462feb80252f2b2c3b5ad

看起来我们之前生成的对抗样本不是旋转不变的!

那么,如何使一个对抗样本对变换的分布是鲁棒?给定一些换分布T我们可以最大化Et~TlogP(y'|t(X'))约束条件为‖X- X'‖∞≤ε。可以通过投影梯度下降来解决这个优化问题,注意到Et~TlogP(y'|t(X'))Et~TlogP(y'|t(X'))相等,并在每个梯度下降步骤中来逼近样本。

可以使用一个技巧TensorFlow为我们做到这一点而不是通过手动实现梯度采样得到我们可以模拟基于采样的梯度下降,作为随机分类器的集合中的梯度下降,随机分类器从分布中随机抽取并在分类之前换输入。

 
num_samples = 10average_loss = 0for i in range(num_samples):    rotated = tf.contrib.image.rotate(        image, tf.random_uniform((), minval=-np.pi/4, maxval=np.pi/4))    rotated_logits, _ = inception(rotated, reuse=True)    average_loss += tf.nn.softmax_cross_entropy_with_logits(        logits=rotated_logits, labels=labels) / num_samples

我们可以重复使用assign_opproject_step,但为了这个新目标必须写一个新的optim_step

 

最后,我们准备运行PGD来产生对抗输入。前面的例子一样,选择“鳄梨酱”作为我们的目标类。

demo_epsilon = 8.0/255.0 # still a pretty small perturbationdemo_lr = 2e-1demo_steps = 300demo_target = 924 # "guacamole"# initialization stepsess.run(assign_op, feed_dict={x: img})# projected gradient descentfor i in range(demo_steps):    # gradient descent step    _, loss_value = sess.run(        [optim_step, average_loss],        feed_dict={learning_rate: demo_lr, y_hat: demo_target})    # project step    sess.run(project_step, feed_dict={x: img, epsilon: demo_epsilon})    if (i+1) % 50 == 0:        print('step %d, loss=%g' % (i+1, loss_value))    adv_robust = x_hat.eval() # retrieve the adversarial example

结果如下

step 50, loss=0.0804289step 100, loss=0.0270499step 150, loss=0.00771527step 200, loss=0.00350717step 250, loss=0.00656128step 300, loss=0.00226182

这种对抗图像被高度信任地归类为“鳄梨酱”,即使是旋转的情况下

rotated_example = rotated_image.eval(feed_dict={image: adv_robust, angle: ex_angle})classify(rotated_example, correct_class=img_class, target_class=demo_target)

89955316941bb5671df76e016a20bddb4c4423d9

评估

下面来看一下在整个角度范围内产生的鲁棒对抗样本的旋转不变性,看P(y'|x')θ∈[- π/4,π/4]

thetas = np.linspace(-np.pi/4, np.pi/4, 301)p_naive = []p_robust = []for theta in thetas:    rotated = rotated_image.eval(feed_dict={image: adv_robust, angle: theta})    p_robust.append(probs.eval(feed_dict={image: rotated})[0][demo_target])        rotated = rotated_image.eval(feed_dict={image: adv, angle: theta})    p_naive.append(probs.eval(feed_dict={image: rotated})[0][demo_target])robust_line, = plt.plot(thetas, p_robust, color='b', linewidth=2, label='robust')naive_line, = plt.plot(thetas, p_naive, color='r', linewidth=2, label='naive')plt.ylim([0, 1.05])plt.xlabel('rotation angle')plt.ylabel('target class probability')plt.legend(handles=[robust_line, naive_line], loc='lower right')plt.show()

f1b92341a1f20106d505ffa02ed3a6f2e6c7f458

从图中蓝色曲线可以看到,生成的对抗样本是超级有效的。

作者信息

Anish Athalye:MIT在读博士生,对分布式系统、系统安全及人工智能感兴趣。

e2e399c8957ca9bfc3d7b1a44937f72c675edad0

学术:

Email

Github: 

本文由北邮老师推荐,组织翻译。

文章原标题《A Step-by-Step Guide to Synthesizing Adversarial Examples》,作者:Anish Athalye译者:海棠,审阅:

文章为简译,更为详细的内容,请查看

 

转载地址:http://flell.baihongyu.com/

你可能感兴趣的文章
从倒卖软件到批发“云”,SaaS还有多远?
查看>>
新一代服务器打造绿色环保数据中心
查看>>
美军花费460亿构建网络安全数字弹药库!
查看>>
专访唐沐:智能家居要先让发烧友玩起来
查看>>
《浅谈架构之路:前后端分离模式》
查看>>
如何理解CMDB的套路
查看>>
企业为什么要把安全工作外包?
查看>>
OA系统选型时这些OA服务需考虑
查看>>
"联想帝国"为何被一位自媒体写手给难住了?
查看>>
10个大数据领域的杰出公司
查看>>
小心物联网带来的信息安全问题,政府需介入规范
查看>>
Facebook 为 iPhone 开发独立“活动”应用程序
查看>>
五类和六类网络的区别
查看>>
全云时代论调过时?边缘计算来抢饭碗
查看>>
云创大数据亮相第四届中国-亚欧安博会
查看>>
Netflix横扫了北美,却难以征服亚洲和中国
查看>>
英国批准建设KaoPark大型数据中心园区
查看>>
广州企业“掘金”万亿大数据市场
查看>>
《企业级ios应用开发实战》一2.6 在模拟器上运行应用程序
查看>>
打造智能家居的第一步:实现万物互联
查看>>