keras深度学习实战(19)——使用对抗攻击生成可欺骗神经网络的图像(代码片段)

盼小辉丶 盼小辉丶     2022-12-07     134

关键词:

Keras深度学习实战(19)——使用对抗攻击生成可欺骗神经网络的图像

0. 前言

近年来,深度学习在图像分类目标检测图像分割音频识别等诸多领域取得了突破性进展,深度学习模型已经能够以接近甚至超越人类水平的完成某些特定任务。
但最近的研究表明,深度学习模型容易受到输入数据中细微扰动的影响,从而导致模型输出错误的预测。在图像领域,此类扰动通常很小对于人眼而言甚至无法察觉,但它们却能够愚弄深度学习模型。针对深度学习模型的这种对抗攻击,限制了深度学习的成功在更广泛领域的应用。
本节中,我们将介绍对抗攻击 (Adversarial Attack) 的基本概念,并使用 Keras 实现对抗攻击生成可欺骗神经网络的图像。

1. 对抗攻击简介

深度学习在执行各种计算机视觉任务方面都有着优异的准确性,但尽管深度学习模型的精确度很高,现代深度网络却容易被微小扰动形式的对抗攻击所干扰,这些扰动对虽然对人类视觉系统而言几乎无法感知,但却可能导致神经网络分类器完全改变其对图像的预测。甚至,被攻击的模型对错误的预测结果具有很高的置信度。此外,相同的图像扰动可能使多个深度网络分类器得到错误输出,这引发了研究人员对对抗攻击的广泛兴趣。
包含恶意扰动的数据通常称为对抗样本 (Adversarial Example),而对抗攻击 (Adversarial Attack) 则是构建对抗样本的并对目标模型实施攻击的过程。例如,如下图所示,通过在图像中添加不明显的扰动,并不会影响人类对其内容的判断,但深度神经网络却对扰动后的图像输出了完全错误的分类结果。

2. 对抗攻击模型分析

为了了解如何对图像进行对抗攻击,我们首先回顾如何使用深度学习模型进行常规预测,然后我们将研究如何调整输入图像,以使深度学习模型对图像输出完全不同的类别,即使修改后的图像在人眼看来与原始图像并无差别。

2.1 模型识别图像流程

本小节,我们首先通过一个示例回顾深度学习模型识别图像流程,在该示例中我们尝试使用训练完成的深度学习模型预测红狐图片:

  • 对输入图像进行预处理,以便可以将其传递到 Inception 网络中
  • 导入预训练的 Inception v3 模型
  • 使用 Inception 模型预测图像类别
  • 图像将被预测为红狐

2.2 对抗攻击流程

接下来,我们的介绍如何通过在图中添加微小扰动修改图像,使其满足以下两个目标:

  • 使用同一网络对修改后的图像进行预测,令模型预测结果改变为山猫
  • 修改后的图像在人类看来没有区别

为了使生成的对抗样本完成以上目标,我们制定以下对抗攻击策略:

  • 定义损失函数:
    • 损失值是红狐图像属于山猫类别的概率
    • 损失值越大,表明我们越接近欺骗神经网络输出错误结果的目标
    • 因此,我们将最大化损失函数
  • 计算相对于输入变化的损失变化梯度:
    • 此步骤有助于了解将输出移向我们目标的输入像素
  • 根据计算出的梯度来更新输入图像:
    • 确保原始图像中的像素值与最终图像中的像素值相差不超过 3
    • 这样可以确保生成的图像与原始图像在人眼看来几乎没有差别
  • 重复以上步骤,直到模型以至少 0.8 的置信度将修改后的图像预测为山猫

3. 使用 Keras 实现对抗攻击

在本节中,我们使用 Keras 实现上述对抗攻击策略,以生成对抗样本。

(1) 导入所需库,读取红狐图片的图像,并查看图片:

import matplotlib.pyplot as plt
import cv2
import numpy as np
from keras import backend as K

img = cv2.imread('5.png')
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
plt.imshow(img)
plt.show()

(2) 预处理图像,以便可以将其传递到 Inception 网络:

img = cv2.resize(img, (299,299))
# 将图像像素值归一化至[-1,1]
original_image = img.astype('float')/255
original_image -= 0.5
original_image *= 2.
# 维度扩展
original_image = np.expand_dims(original_image, axis=0)

(3) 导入预训练的模型,并使用此模型预测图像中对象的类别:

from keras.preprocessing import image
from keras.applications import inception_v3
model = inception_v3.InceptionV3()
predictions = model.predict(original_image)
predicted_classes = inception_v3.decode_predictions(predictions, top=1)
imagnet_id, name, confidence = predicted_classes[0][0]
print("This is a  with :.4% confidence".format(name, confidence * 100))

模型对于输入的图像,输出的预测结果如下,看以看到模型可以以很高的置信度得到正确的结果:

This is a red_fox with 92.09% confidence

(4) 接下来,为对抗攻击模型定义输入和输出:

model_input_layer = model.layers[0].input
model_output_layer = model.layers[-1].output

model_input_layer 是模型的输入,而 model_output_layer (具有 softmax 激活函数的最后一层)是输入图像属于各种类别的概率。

(5) 设置原始图像的修改限制(即图片最大变化阈值),指定了修改原始图像应遵照的限制:

max_change_above = np.copy(original_image) + 0.01
max_change_below = np.copy(original_image) - 0.01
adversarial_sample = np.copy(original_image)

(6) 初始化损失函数,以便模型将修改后图像预测为山猫(模型输出预测向量中的第 283 个索引值):

learning_rate = 0.1
prob_cat = []
# 山猫
object_type_to_fake = 283
cost_function = model_output_layer[0, object_type_to_fake]

model_output_layer 的输出是图像的各种类别的概率,我们指定损失函数由我们要伪造对象类别的索引位置决定。

(7) 初始化损失相对于输入的梯度函数:

gradient_function = K.gradients(cost_function, model_input_layer)[0]

此代码计算 cost_function 相对于 model_input_layer (输入图像)的梯度变化。需要注意的是,如果使用 TensorFlow2 作为 Keras 的后端,会报如下错误:

Traceback (most recent call last):
  File "adversarial_attack.py", line 45, in <module>
    gradient_function = K.gradients(cost_function, model_input_layer)[0]
  File "/python3.7/lib/python3.7/site-packages/tensorflow/python/keras/backend.py", line 3969, in gradients
    loss, variables, colocate_gradients_with_ops=True)
  File "/python3.7/lib/python3.7/site-packages/tensorflow/python/ops/gradients_impl.py", line 172, in gradients
    unconnected_gradients)
  File "/python3.7/lib/python3.7/site-packages/tensorflow/python/ops/gradients_util.py", line 491, in _GradientsHelper
    raise RuntimeError("tf.gradients is not supported when eager execution "
RuntimeError: tf.gradients is not supported when eager execution is enabled. Use tf.GradientTape instead.

为了解决上述问题,需要在代码开头加上以下代码,切换梯度求解的执行模型:

import tensorflow as tf
tf.compat.v1.disable_eager_execution()

(8) 定义输入与损失和梯度变化的映射函数,计算 cost_function 值(即该图像属于山猫类别的概率)和相对于输入图像的梯度信息:

grab_cost_and_gradients_from_model = K.function([model_input_layer], [cost_function, gradient_function])

(9) 使用梯度信息不断更新输入图像,直到模型以至少 0.8 的置信度将修改后的图像预测为山猫:

cost = 0.0

while cost < 0.80:
    cost, gradients = grab_cost_and_gradients_from_model([adversarial_sample, 0])
    adversarial_sample += gradients * learning_rate
    adversarial_sample = np.clip(adversarial_sample, max_change_below, max_change_above)
    prob_cat.append(cost)
    print("Model's predicted likelihood that the image is an tiger cat: :.8%".format(cost * 100))

在以上代码中,我们获得了与输入图像 (adversarial_sample) 相对应的损失和梯度信息。另外,我们利用梯度(乘以学习率)更新输入图像。最后,如果被修改的图片超过了预定义的图片最大变化阈值,我们会对其进行裁剪,以确保图像修改前后的变化并不明显。不断循环执行这些步骤,直到获得输入图像至少有 0.8 的概率被预测为山猫为止。

Model's predicted likelihood that the image is an tiger cat: 0.0043381504%
Model's predicted likelihood that the image is an tiger cat: 0.0043390162%
...
Model's predicted likelihood that the image is an tiger cat: 74.044788%
Model's predicted likelihood that the image is an tiger cat: 89.34136%

(10) 绘制随着 epoch 的改变,红狐图像被检测为山猫图像的概率的变化:

epochs = range(1, len(prob_cat) + 1)
plt.plot(epochs, prob_cat, 'b')
plt.title('Probability of African elephant class')
plt.xlabel('Epochs')
plt.ylabel('Probability')
plt.show()

得到的图像被预测为山猫的概率变化如下:

(11) 预测被修改后的图像类别概率:

output = model.predict(adversarial_sample)[0]
print('class: ', np.argmax(output), 'confidence: ', output[np.argmax(output)])

预测输出已经被修改为 283,即山猫,且概率为 0.9487

class:  283 confidence:  0.94870704

(12) 由于在输入图像时对其进行了预处理,为了将其可视化,需要对修改后的输入图像进行逆预处理过程。原始图像、对抗样本(即被修改后图像)以及两个图像之间的差异(即添加的对抗性扰动)可视化如下:

adversarial_sample = adversarial_sample / 2
adversarial_sample = adversarial_sample + 0.5
adversarial_sample = adversarial_sample * 255
adversarial_sample = np.clip(adversarial_sample, 0, 255).astype('uint8')

plt.subplot(131)
plt.imshow(img)
plt.title('Original image')
plt.subplot(132)
plt.imshow(adversarial_sample[0,:,:,:])
plt.title('Adversarial sample')
plt.subplot(133)
plt.imshow(img - adversarial_sample[0,:,:,:])
plt.title('Difference')
plt.show()

小结

尽管深度神经网络在各种计算机视觉任务上具有很高的准确性,但研究表明它们容易受到微小扰动的影响,从而导致它们输出完全错误的预测结果。由于深度学习是当前机器学习和人工智能的核心技术,这一缺陷引起了研究人员广泛的兴趣。本文首先介绍了对抗攻击的基本概念,然后利用 Keras 实现了一种经典的对抗攻击算法,通过在图中添加微小扰动令红狐图像被错误的预测为山猫图像,我们也可以通过改变攻击的目标索引,来使图像被错误分类为其它类别。

系列链接

Keras深度学习实战(1)——神经网络基础与模型训练过程详解
Keras深度学习实战(2)——使用Keras构建神经网络
Keras深度学习实战(3)——神经网络性能优化技术
Keras深度学习实战(4)——深度学习中常用激活函数和损失函数详解
Keras深度学习实战(5)——批归一化详解
Keras深度学习实战(6)——深度学习过拟合问题及解决方法
Keras深度学习实战(7)——卷积神经网络详解与实现
Keras深度学习实战(8)——使用数据增强提高神经网络性能
Keras深度学习实战(9)——卷积神经网络的局限性
Keras深度学习实战(10)——迁移学习详解
Keras深度学习实战(11)——可视化神经网络中间层输出
Keras深度学习实战(12)——面部特征点检测
Keras深度学习实战(13)——目标检测基础详解
Keras深度学习实战(14)——从零开始实现R-CNN目标检测
Keras深度学习实战(15)——从零开始实现YOLO目标检测
Keras深度学习实战(16)——自编码器详解
Keras深度学习实战(17)——使用U-Net架构进行图像分割
Keras深度学习实战(18)——语义分割详解

keras深度学习实战(22)——生成对抗网络详解与实现(代码片段)

Keras深度学习实战(22)——生成对抗网络详解与实现0.前言1.生成对抗网络原理2.模型分析3.利用生成对抗网络生成手写数字图像小结系列链接0.前言生成对抗网络(GenerativeAdversarialNetworks,GAN)使用神经网络生成与原始图像集非常相... 查看详情

keras深度学习实战(23)——dcgan详解与实现(代码片段)

Keras深度学习实战(23)——DCGAN详解与实现0.前言1.使用DCGAN生成手写数字图像2.使用DCGAN生成面部图像2.1模型分析2.2从零开始实现DCGAN生成面部图像小结系列链接0.前言在生成对抗网络(GenerativeAdversarialNetworks,GAN)一节中,我们使用... 查看详情

keras深度学习实战(23)——dcgan详解与实现(代码片段)

Keras深度学习实战(23)——DCGAN详解与实现0.前言1.使用DCGAN生成手写数字图像2.使用DCGAN生成面部图像2.1模型分析2.2从零开始实现DCGAN生成面部图像小结系列链接0.前言在生成对抗网络(GenerativeAdversarialNetworks,GAN)一节中,... 查看详情

keras深度学习实战(20)——deepdream模型详解(代码片段)

Keras深度学习实战(20)——DeepDream模型详解0.前言1.DeepDream的技术原理2.DeepDream模型分析3.DeepDream算法实现3.1数据加载与预处理3.2DeepDream生成模型小结系列链接0.前言在《对抗样本生成》一节中,我们通过略微修改输入... 查看详情

keras深度学习实战——基于vgg19模型实现性别分类(代码片段)

Keras深度学习实战——基于VGG19模型实现性别分类0.前言1.VGG19架构简介2.使用预训练VGG19模型进行性别分类2.1构建输入与输出数据2.2模型构建与训练2.3模型错误分类示例相关链接0.前言在《迁移学习》中,我们了解了利用迁移学... 查看详情

keras深度学习实战(30)——使用文本生成模型进行文学创作(代码片段)

Keras深度学习实战(30)——使用文本生成模型进行文学创作0.前言1.文本生成模型与数据集分析1.1数据集分析1.2模型分析2.构建文本生成模型2.1数据预处理2.2模型构建与训练小结系列链接0.前言在情感分类任务中,神经... 查看详情

keras深度学习实战——使用fasttext模型构建单词向量(代码片段)

Keras深度学习实战——使用fastText模型构建单词向量0.前言1.fastText算法模型2.模型与数据集分析2.1fastText模型分析2.2数据集分析3.使用Keras实现fastText生成单词向量相关链接0.前言fastText是另一种用于生成单词向量的神经网络模型,其... 查看详情

keras深度学习实战(38)——图像字幕生成(代码片段)

Keras深度学习实战(38)——图像字幕生成0.前言1.模型与数据集分析1.1数据集分析1.2模型分析2.实现图像字幕生成模型2.1数据集加载与预处理2.2模型构建与训练3.使用束搜索生成字幕3.1束搜索原理3.2利用束搜索改进预测结... 查看详情

深度学习攻防对抗(jcai-19阿里巴巴人工智能对抗算法竞赛)

...简单科普一下人工智能与信息安全的交叉前沿研究领域:深度学习攻防对抗。然后简单介绍一下IJCAI-19阿里巴巴人工智能对抗算法竞 查看详情

keras深度学习实战——使用fasttext模型构建单词向量(代码片段)

Keras深度学习实战——使用fastText模型构建单词向量0.前言1.fastText算法模型2.模型与数据集分析2.1fastText模型分析2.2数据集分析3.使用Keras实现fastText生成单词向量相关链接0.前言fastText是另一种用于生成单词向量的神经网络模型࿰... 查看详情

keras深度学习实战(13)——目标检测基础详解(代码片段)

Keras深度学习实战(13)——目标检测基础详解0.前言1.目标检测概念2.创建自定义目标检测数据集2.1windows2.2Ubuntu2.3MacOS3.使用选择性搜索在图像内生成候选区域3.1候选区域3.2选择性搜索3.3使用选择性搜索生成候选区域4.交并... 查看详情

keras深度学习实战(26)——文档向量详解(代码片段)

Keras深度学习实战(26)——文档向量详解0.前言1.文档向量基本概念2.神经网络模型与数据集分析2.1模型分析2.2数据集介绍3.利用Keras构建神经网络模型生成文档向量小结系列链接0.前言在《从零开始构建单词向量》一节中,我们... 查看详情

keras深度学习实战——使用glove模型构建单词向量(代码片段)

Keras深度学习实战——使用GloVe模型构建单词向量0.前言1.GloVe算法模型1.1模型目标1.2GloVe算法计算细节3.实现GloVe模型构建单词向量3.1数据集3.2模型实现相关链接0.前言在《使用fastText模型构建单词向量》一节中,我们学习了如何构... 查看详情

keras深度学习实战——使用glove模型构建单词向量(代码片段)

Keras深度学习实战——使用GloVe模型构建单词向量0.前言1.GloVe算法模型1.1模型目标1.2GloVe算法计算细节3.实现GloVe模型构建单词向量3.1数据集3.2模型实现相关链接0.前言在《使用fastText模型构建单词向量》一节中,我们学习了如... 查看详情

keras深度学习实战(20)——神经风格迁移详解(代码片段)

Keras深度学习实战(20)——神经风格迁移详解0.前言1.神经风格迁移原理2.模型分析3.使用Keras实现神经风格迁移小结系列链接0.前言在DeepDream图像生成算法的学习中,我们通过修改像素值试图使神经网络中卷积核的激... 查看详情

深度学习100例-生成对抗网络(dcgan)手写数字生成|第19天(代码片段)

文章目录深度卷积生成对抗网络(DCGAN)一、前言二、什么是生成对抗网络?1.设置GPU2.加载和准备数据集三、创建模型1.生成器2.判别器四、定义损失函数和优化器1.判别器损失2.生成器损失五、定义训练循环六、训练... 查看详情

深度学习100例-生成对抗网络(dcgan)手写数字生成|第19天(代码片段)

文章目录深度卷积生成对抗网络(DCGAN)一、前言二、什么是生成对抗网络?1.设置GPU2.加载和准备数据集三、创建模型1.生成器2.判别器四、定义损失函数和优化器1.判别器损失2.生成器损失五、定义训练循环六、训练... 查看详情

keras深度学习实战(40)——音频生成(代码片段)

Keras深度学习实战(40)——音频生成0.前言1.模型与数据集分析1.1数据集分析1.2模型分析2.音频生成模型2.1数据集加载与预处理2.2模型构建与训练小结系列链接0.前言我们已经在《文本生成模型》一节中学习了如何利用深... 查看详情