分享

使用深度学习生成恶意样本的方法

本帖最后由 levycui 于 2019-5-21 20:19 编辑
问题导读:
1、如何理解应用FGSM算法?
2、如何理解应用IGSM算法?
3、如何使用BasicIterativeMethod函数实现IGSM算法?
3、如何理解应用DeepFool算法?




〇、深度学习的恶意样本(Adversarial Example)

随着深度学习研究的深入,相关应用已经在许多领域展现出惊人的表现。一方面,深度学习的强大能力着实吸引着学术界和产业界的眼球。另外一方面,深度学习的安全问题也开始引起广泛地关注。对于一个给定的深度神经网络,经过训练,它可能在具体任务上(例如图像识别)表现出较高的准确率。但是在原本能够被正确分类的图像中引入稍许(人眼不易察觉)扰动,神经网络模型就可能被误导,从而得出错误的分类结果。例如,下图中最左侧的熊猫图片本来可以被正确分类,向其中加入一定的扰动,结果会得到右侧的熊猫图片。在人眼看来,它仍然是熊猫,但是神经网络模型却以相当高的置信率将其识别成了长臂猿。最右侧这个经过精心调整的能够误导神经网络模型的图像就被称为是恶意样本(Adversarial Example),或简称AE。
2019-05-21_195405.jpg
本文主要介绍几种流行的恶意样本(Adversarial Example)的生成方法,以下实验代码采用Python语言,环境是Ubuntu 18.04,深度学习模型以残差神经网络ResNet为例,它是基于Keras框架实现的。


一、预备工作:CIFAR10与ResNet

Adversarial Example可以攻击各种深度学习应用,包括图像、声音、视频、甚至文本(在NLP领域)等。本文主要以图像的分类/识别任务为例来生成恶意样本。所选择之数据集为经典的CIFAR10(来自文献【1】),如下图所示。该数据集中的图像均为32×32的彩色图像,所有图像都被分成飞机、汽车、鸟、猫等10个类别(分类标签为0~9)。
2019-05-21_195520.jpg
我们以文献【3】中的代码为基础训练了一个专门用于对CIFAR10中之图像进行识别的分类器,特别地,这里的分类器指的是一个32层的残差神经网络ResNet。在下面的代码中,我们使用load_model()函数直接将训练好的ResNet模型导入。此外,下面的代码中还引入了一些后面将会用到的package,其中,art包是由IBM公司开发的AE工具箱(Adversarial Robustness Toolbox),参见文献【2】,在应用它之前,必须确认已经将其成功安装。
[mw_shl_code=python,true]from os.path import abspath
import sys
import os
import tensorflow as tf
sys.path.append(abspath('.'))

import keras
import numpy as np
import pickle

import matplotlib.pyplot as plt
%matplotlib inline

from keras.datasets import cifar10
from keras.models import load_model
from keras.utils import to_categorical

from art.classifiers import KerasClassifier
from art.attacks.fast_gradient import FastGradientMethod
from art.attacks.iterative_method import BasicIterativeMethod
from art.attacks.saliency_map import SaliencyMapMethod
from art.attacks import DeepFool

my_model = load_model('cifar10_ResNet32v1_model.189.h5')

(x_train, y_train), (x_test, y_test) = cifar10.load_data()
x_train = x_train.astype('float32') / 255
x_test = x_test.astype('float32') / 255
x_train_mean = np.mean(x_train, axis=0)
x_train -= x_train_mean
x_test -= x_train_mean

min_ = np.min(x_train)
max_ = np.max(x_train)[/mw_shl_code]
下面来在Test集上测试一下我们训练好的ResNet32网络:
[mw_shl_code=python,true]num_classes = 10
y_train_vector = keras.utils.to_categorical(y_train, num_classes)
y_test_vector = keras.utils.to_categorical(y_test, num_classes)

scores = my_model.evaluate(x_test, y_test_vector, verbose=1)

print('Test accuracy:', scores[1])[/mw_shl_code]
结果显示,这个网络在正常的测试集上可以达到91.96%的准确率。
[mw_shl_code=python,true]10000/10000 [==============================] - 4s 375us/step
Test accuracy: 0.9196[/mw_shl_code]
或者,你也可以使用下面的代码来测试,它的功能同之前的代码一致:
[mw_shl_code=python,true]len_index = x_test.shape[0]
sum_success = 0

for i in range(len_index):
    y_pred = my_model.predict(x_test.reshape(1,32,32,3))
    if (np.argmax(y_pred) == y_test):
        sum_success += 1

print('Test accuracy:', sum_success/10000.0)[/mw_shl_code]
同样,可以得到91.96%的准确率:
[mw_shl_code=python,true]Test accuracy: 0.9196
[/mw_shl_code]

做完上述这些必要的准备工作之后,就可以正式开启下面的AE生成实验了。再次提醒:尽管我们所使用的网络是ResNet32网络,但是你可以使用任何其他实现相同目的(即对CIFAR10中的图像进行分类)之网络来进行如下实验。下面的代码都是在Jupyter Notebook开发环境中完成的,其他环境可能会略有出入,请读者注意。


二、FGSM

FGSM是一种比较简单的AE生成算法,它由来自谷歌大脑的三位研究者在文献【4】中提出,其中一位作者就是大名鼎鼎的 Goodfellow。Ian Goodfellow因提出了生成对抗网络(GANs)而闻名,他被誉为“GANs之父”,甚至被认为是当前人工智能领域的顶级专家。他还是著名的花书《Deep Learning》的作者。文献【4】中的另外一个作者是Samy Bengio,他除了是深度学习领域的一位知名专家以外,还是新晋图灵奖得主Yoshua Bengio的兄弟。IBM ART工具箱中的FastGradientMethod函数实现了这个算法,下面我们就调用这个函数来对之前训练好的ResNet32网络发动AE攻击。
[mw_shl_code=python,true]x_test_1K, y_test_1K = x_test[:1000], y_test_vector[:1000]

classifier = KerasClassifier((min_, max_), model=my_model)

# Craft adversarial samples with FGSM
epsilon = 0.03  # Maximum perturbation
adv_fgsm_crafter = FastGradientMethod(classifier)

x_test_adv_fgsm = adv_fgsm_crafter.generate(x=x_test_1K, eps=epsilon)

scores_adv_test = my_model.evaluate(x_test_adv_fgsm, y_test_1K, verbose=1)
print('Accuracy on Test AEs based on FGSM:', scores_adv_test[1])[/mw_shl_code]

基于1000个测试AE给出的模型准确率如下,可见准确率已经被大大降低:
[mw_shl_code=python,true]1000/1000 [==============================] - 0s 309us/step
Accuracy on Test AEs based on FGSM: 0.187[/mw_shl_code]

下面的代码用于将原图及对应的AE绘制出来,以示对比:
[mw_shl_code=python,true]fig=plt.figure(figsize=(8, 2))
columns = 8
rows = 2
for i in range(1, 9):
    img = x_test[i+8].reshape(32,32,3) + x_train_mean
    fig.add_subplot(rows, columns, i)
    plt.imshow(img)
    plt.axis('off')
   
for i in range(1, 9):
    img_adv = x_test_adv_fgsm[i+8].reshape(32,32,3) + x_train_mean
    fig.add_subplot(rows, columns, i+8)
    plt.imshow(img_adv)
    plt.axis('off')[/mw_shl_code]
上述代码的执行效果如下,可见基于FGSM生成的AE图像在人眼看来仍然是可以辨识的。
2019-05-21_195914.jpg
但是将这些AE输入到神经网络后,则会发现神经网络均预测失败:
[mw_shl_code=python,true]for i in range(9, 17):
    y_pred = my_model.predict(x_test.reshape(1,32,32,3))
    print(np.argmax(y_pred), end = ' ')

print("")
for i in range(9, 17):
    y_pred = my_model.predict(x_test_adv_fgsm.reshape(1,32,32,3))
    print(np.argmax(y_pred), end = ' ')[/mw_shl_code]
如下所示,第一行给出的是正常图像的神经网络预测结果,第二行是相应AE之预测结果:
[mw_shl_code=python,true]1 0 9 5 7 9 8 5
9 3 1 4 6 1 6 3 [/mw_shl_code]

三、IGSM

同样在文献【4】中,Goodfellow等人还给出了一个多次迭代版本的AE生成算法——IGSM。IBM ART工具箱中的BasicIterativeMethod函数实现了这个算法,下面的代码就调用这个函数来对之前训练好的ResNet32网络发动AE攻击。
[mw_shl_code=python,true]epsilon=0.015  # Maximum perturbation
stepsize=0.005
adv_igsm_crafter = BasicIterativeMethod(classifier, eps=epsilon, eps_step=stepsize)

x_test_adv_igsm = adv_igsm_crafter.generate(x=x_test_1K)

scores_adv_test = my_model.evaluate(x_test_adv_igsm, y_test_1K, verbose=1)
print('Accuracy on Test AEs based on IGSM:', scores_adv_test[1])[/mw_shl_code]

基于1000个测试AE给出的模型准确率如下,可见准确率已经被大大降低:
[mw_shl_code=python,true]1000/1000 [==============================] - 0s 317us/step
Accuracy on Test AEs based on IGSM: 0.063[/mw_shl_code]
同样我们可以将原图及对应的AE绘制出来,以示对比。代码同前,这里略去。效果如下,可见基于IGSM生成的AE图像在人眼看来仍然是可以辨识的。
2019-05-21_200058.jpg
但是将这些AE输入到神经网络后,则会发现神经网络均预测失败:
[mw_shl_code=python,true]for i in range(9, 17):
    y_pred = my_model.predict(x_test.reshape(1,32,32,3))
    print(np.argmax(y_pred), end = ' ')

print("")
for i in range(9, 17):
    y_pred = my_model.predict(x_test_adv_igsm.reshape(1,32,32,3))
    print(np.argmax(y_pred), end = ' ')[/mw_shl_code]
如下所示,第一行给出的是正常图像的神经网络预测结果,第二行是相应AE之预测结果:
[mw_shl_code=python,true]1 0 9 5 7 9 8 5
9 4 1 4 1 1 6 3 [/mw_shl_code]

四、DeepFool

2016年,发表在CVPR上的文献【6】中提出了一种AE生成算法——DeepFool。IBM ART工具箱中的DeepFool函数实现了这个算法,其中需要注意的参数是max_iter 和epsilon,前者是生成算法的最大迭代次数,后者表示最大的扰动程度。
[mw_shl_code=python,true]# Craft adversarial samples with DeepFool
adv_df_crafter = DeepFool(classifier, max_iter=50, epsilon=0.01)

x_test_adv_df = adv_df_crafter.generate(x_test_1K)

scores_adv_test = my_model.evaluate(x_test_adv_df, y_test_1K, verbose=1)
print('Accuracy on Test AEs based on DeepFool:', scores_adv_test[1])[/mw_shl_code]
与之前的情况类似,下面给出的是基于1000个测试AE给出的模型准确率,可见准确率已经被大大降低:
[mw_shl_code=python,true]1000/1000 [==============================] - 0s 297us/step
Accuracy on Test AEs based on DeepFool: 0.325[/mw_shl_code]
同样我们可以将原图及对应的AE绘制出来,以示对比。代码同前,这里略去。效果如下,可见基于DeepFool生成的AE图像在人眼看来仍然是可以辨识的,而且效果比FGSM或IGSM的更贴近原图(也就是说引入的扰动更加细微)。
2019-05-21_200247.jpg
但是将这些AE输入到神经网络后,则会发现神经网络大概率地会预测失败:
[mw_shl_code=python,true]for i in range(9, 17):
    y_pred = my_model.predict(x_test.reshape(1,32,32,3))
    print(np.argmax(y_pred), end = ' ')

print("")
for i in range(9, 17):
    y_pred = my_model.predict(x_test_adv_df.reshape(1,32,32,3))
    print(np.argmax(y_pred), end = ' ')[/mw_shl_code]

如下所示,第一行给出的是正常图像的神经网络预测结果,第二行是相应AE之预测结果:
[mw_shl_code=python,true]1 0 9 5 7 9 8 5
9 4 1 4 7 8 6 7 [/mw_shl_code]

五、JSMA

JSMA是由Nicolas Papernot等在2016年的Euro S&P上提出的一种L_0类型的AE生成算法,参见文献【5】。与前面介绍的几种算法不同,JSMA是一种Targeted的攻击算法。也就是说,它不仅可以误导神经网络输出错误的分类结果,还可以预设一个目标,让神经网络输出指定的(错误)分类结果。因此,我们需要先给出预设的分类目标。这里采取的方法为,总是令神经网络输出原本的正确标签的下一个作为目标标签,例如正确的标签本应该是8,则AE会误导神经网络输出9,如果正确的标签本应该是9,则AE会误导神经网络输出0... ... 下面的代码用于生成预设之标签:
[mw_shl_code=python,true]test_len = y_test.shape[0]
y_test_t = np.zeros(y_test.shape)

for i in range(test_len):
    y_test_t[0] = (y_test[0] + 1)%num_classes

y_test_t_vector = keras.utils.to_categorical(y_test_t, num_classes)

y_test_target = y_test_t_vector[:1000][/mw_shl_code]

IBM ART工具箱中的SaliencyMapMethod函数实现了JSMA算法,下面的代码就调用这个函数来对之前训练好的ResNet32网络发动AE攻击。
[mw_shl_code=python,true]# Craft adversarial samples with JSMA
adv_jsma_crafter = SaliencyMapMethod(classifier, theta=0.1)

x_test_adv_jsma = adv_jsma_crafter.generate(x_test_1K, y = y_test_target)

scores_adv_test = my_model.evaluate(x_test_adv_jsma, y_test_1K, verbose=1)
print('Accuracy on Test AEs based on JSMA:', scores_adv_test[1])[/mw_shl_code]

同样可以将原图及对应的AE绘制出来,以示对比。代码同前,这里略去。效果如下,可见基于JSMA生成的AE图像在人眼看来仍然是可以辨识的。但作为一种L_0类型的AE生成算法,被引入的扰动往往是人眼可见的。
2019-05-21_200415.jpg
将这些AE输入到神经网络后,则会发现神经网络会被有方向地误导:
[mw_shl_code=python,true]for i in range(9, 17):
    y_pred = my_model.predict(x_test.reshape(1,32,32,3))
    print(np.argmax(y_pred), end = ' ')

print("")
for i in range(9, 17):
    y_pred = my_model.predict(x_test_adv_jsma.reshape(1,32,32,3))
    print(np.argmax(y_pred), end = ' ')[/mw_shl_code]
如下所示,第一行给出的是正常图像的神经网络预测结果,第二行是相应AE之预测结果。跟我们预想的一样,神经网络在面对AE时所给出的标签总是比相应的正常图像所给出的结果后移一位(当然这个误导的目标你也可以随意设定)。
[mw_shl_code=python,true]1 0 9 5 7 9 8 5
2 1 0 6 8 0 9 6 [/mw_shl_code]
最新经典文章,欢迎关注公众号

作者:白马负金羁
来源:https://blog.csdn.net/baimafujinji/article/details/89840023

已有(2)人评论

跳转到指定楼层
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条