我正在使用mnist数据集上的deepfool和sparsefool测试对抗性样本攻击。它对预处理后的图像数据造成了攻击。但是,当我将其保存到图像中然后重新加载时,它无法进行攻击。
我已经使用sparsefool和deepfool测试了它,我认为将其保存到图像中时存在一些精度问题。但是我无法弄清楚如何正确实施它。
if __name__ == "__main__":
# pic_path = 'testSample/img_13.jpg'
pic_path = "./hacked.jpg"
model_file = './trained/'
image = Image.open(pic_path)
image_array = np.array(image)
# print(np.shape(image_array)) # 28*28
shape = (28, 28, 1)
projection = (0, 1)
image_norm = tf.cast(image_array / 255.0 - 0.5, tf.float32)
image_norm = np.reshape(image_norm, shape) # 28*28*1
image_norm = image_norm[tf.newaxis, ...] # 1*28*28*1
model = tf.saved_model.load(model_file)
print(np.argmax(model(image_norm)), "nnn")
# fool_img, r, pred_label, fool_label, loops = SparseFool(
# image_norm, projection, model)
print("pred_label", pred_label)
print("fool_label", np.argmax(model(fool_img)))
pert_image = np.reshape(fool_img, (28, 28))
# print(pert_image)
pert_image = np.copy(pert_image)
# np.savetxt("pert_image.txt", (pert_image + 0.5) * 255)
pert_image += 0.5
pert_image *= 255.
# shape = (28, 28, 1)
# projection = (0, 1)
# pert_image = tf.cast(((pert_image - 0.5) / 255.), tf.float32)
# image_norm = np.reshape(pert_image, shape) # 28*28*1
# image_norm = image_norm[tf.newaxis, ...] # 1*28*28*1
# print(np.argmax(model(image_norm)), "ffffnnn")
png = Image.fromarray(pert_image.astype(np.uint8))
png.save("./hacked.jpg")
它应该攻击4到9,但是保存的图像仍被预测为4。
完整代码项目在上共享 https://drive.google.com/open?id=132_SosfQAET3c4FQ2I1RS3wXsT_4W5Mw
答案 0 :(得分:1)
根据我的研究以及本文作为参考https://arxiv.org/abs/1607.02533 在转换为图像时,您可以在现实生活中看到,攻击产生的所有对抗性攻击样本在现实世界中均无法使用。它可以解释如下:“这可以由以下事实来解释:迭代方法利用了更细微的 摄动,这些微妙的摄动更有可能被照片变换破坏”。
例如,您的干净图像有127,200,55,....您被划分为255(因为它是8bit png),并以(0.4980,0.78431,0.2156,...)发送给您ML。 Deepfool是高级攻击方法,它添加了较小的扰动并将其更改为(0.498 1 ,0.784 1 ,0.215 5 ...)。现在,这是一个对抗性示例,可能会使您的ML蒙混。但是如果您尝试将其保存为8bit png,则会再次得到127,200,55 ..,因为您将其乘以255。因此,对抗性信息会丢失。
简单地说,您使用深傻瓜方法添加了一些很小的扰动,这在现实世界中8bit png中是不可能的。