所以要欺骗一个分类器,我们只需要知道从哪个方向来推动这个点,以便把它放在一边。如果我们改变的过于明显,我们会尽可能少点移动这个点,这样看起来像是无意间的错误。
在具有深度神经网络的图像分类中,我们分类的每个“点”都是由数千个像素组成的整个图像。这给了我们数千个可能合适的值,让我们可以调整和推动这个点越过分界线。如果我们确信我们以对人类不太明显的方式调整图像中的像素,我们就可以在图片看起来没被篡改的情况下欺骗分类器。
换句话说,我们可以取得一个真实物体的图片然后稍微调整一些像素,使得这个图像完全被神经网络视为别的东西 – 并且我们可以完全掌握它被检测成什么样的物体:
把一只猫变成烤面包机,来自的图像检测结果
如何欺骗神经网络我们已经讨论了训练神经网络以分类照片的基本过程:
插入一个训练图像。
检查神经网络的预测,看看距离正确结果有多远。
使用反向传播调整神经网络中每个层的权重,使最终预测更接近正确结果。
重复步骤1-3几千次并使用几千种不同的训练照片。
但是,如果不调整神经网络的层的权重,而是调整输入图像本身,直到我们得到我们想要的结果呢?
所以让我们拿先前训练的神经网络再次进行“训练”。不过这次让我们使用反向传播来调整输入图像而不是调整神经网络层:
这里是新的算法:
插入我们想要的破解的图像。
检查神经网络的预测,看看距离我们想要获得这张照片的结果有多远。
使用反向传播调整我们的照片,使最终的预测更接近我们想要的结果。
使用相同的照片重复步骤1-3几千次,直到网络给我们想要的结果。
最后,我们将获得一个欺骗神经网络并且不改变神经网络本身任何东西的图像。
唯一的问题是,不加限制地允许任何单个像素进行调整,图像的改动可能会非常剧烈,以至于肉眼可见。它们会出现变色的斑点区域或波浪区域:
没有限制调整像素的黑客图像。你能在墙上看到波浪形,在猫周围看到变色的斑点。
为了防止这些明显的失真,我们可以为我们的算法添加一个简单的约束。我们可以声明,黑客图像中没有一个像素可以从原始图像中变化超过一小部分 – 比如0.01%。这迫使我们的算法以一种既能欺骗神经网络又不会让图像看起来与原始图像不同的方式来调整图像。
以下是我们添加完约束后生成图像的样子:
限制了可以改变多少单个像素后生成的黑客图像。
即使这个图像看起来和我们看的一样,照样能够欺骗神经网络!
让我们看看如何编码实现它为了方便编写,我们首先需要一个预先训练的神经网络来进行欺骗。不进行从头开始的训练,而是使用Google创建已经好的。
Keras是一种流行的深度学习框架,它带有几个预先训练好的神经网络。我们将使用经过预先训练的Google Inception v3深层神经网络,检测1000种不同种类的对象。
这里是Keras的基本代码,使用这个神经网络识别图片中的内容。在运行之前,请确认你安装了Python 3和:
import numpy as np from keras.preprocessing import image from keras.applications import inception_v3 # Load pre-trained image recognition model model = inception_v3.InceptionV3() # Load the image file and convert it to a numpy array img = image.load_img("cat.png", target_size=(299, 299)) input_image = image.img_to_array(img) # Scale the image so all pixel intensities are between [-1, 1] as the model expects input_image /= 255. input_image -= 0.5 input_image *= 2. # Add a 4th dimension for batch size (as Keras expects) input_image = np.expand_dims(input_image, axis=0) # Run the image through the neural network predictions = model.predict(input_image) # Convert the predictions into text and print them predicted_classes = inception_v3.decode_predictions(predictions, top=1) imagenet_id, name, confidence = predicted_classes[0][0] print("This is a {} with {:.4}% confidence!".format(name, confidence * 100))运行后,它正确地检测了这个图像,将它归类为波斯猫:
$ python3 predict.py This is a Persian_cat with 85.7% confidence!现在让我们调整图像欺骗神经网络直到让它认为这只猫是烤面包机。
Keras内置没有训练输入图像的方法,只能训练神经网络层。所以我不得不手动编写训练步骤。