改正了利用Keras实现FGSM算法里的一些错误,并添加了一些注释
import numpy as np
from keras import backend, losses
def FGSM(model, image, y_true, eps=0.1):
# image 是 cv2 或者 plt 读取的图像
y_pred = model.output
# y_true: 目标真实值的张量。
# y_pred: 目标预测值的张量。
loss = losses.categorical_crossentropy(y_true, y_pred)
gradient = backend.gradients(loss, model.input)
gradient = gradient[0]
adv = image + backend.sign(gradient) * eps
# fgsm算法.整个程序最重要的其实就只有这一行
sess = backend.get_session()
adv = sess.run(adv, feed_dict={model.input: np.array([image])})
# 注意这里传递参数的情况
adv = np.clip(adv, 0, 1)
# np.clip(adv, 0, 255) #看自己情况选择 1 或者 255
# 有的像素点会超过255,需要处理
return adv
def FGSM_attack(model,img,img_number, eps=0.2):#epsilons=20):
print("如果帮助到了你,点个赞可以吗?")
# fgsm攻击 函数调用
# 下面部分代码(图像处理)需要根据自己的攻击图像的实际情况进行修改
# # 加载准备攻击的模型,对要攻击的图形进行转换
lpr_model = model
img_convert=img
ret_predict = lpr_model.predict_classes(np.array([img_convert])) # 进行预测
# 获取预测结果的one-hot编码,在攻击时需要用到
# 是为了求得上一个函数中的 y_true
# for example: if you use the keras to predict the MNIST,
# then the shape of label will be (N,)
# every label can be 0,...,9
# The shape of one-hot will be (N,10)
# one-hot[1]=[0., 1., 0., ..., 0., 0., 0.]
label = np.zeros([1, 10])
label[:,img_number]=1
# print("开始使用FGSM进行攻击")
# 计算eps的值,这里是N等分
# epsilons = np.linspace(0, 1, num=epsilons + 1)[1:]
# 使用循环来逐渐增加攻击的强度
img_attack = FGSM(lpr_model, img_convert, label, eps=eps)
attack_label = lpr_model.predict_classes(img_attack)
if attack_label[0] != ret_predict[0]:
print('攻击成功,前为:',ret_predict,', 后为:', attack_label)
else:
print('攻击失败')
return img_attack
# 返回对抗样本(图像)
使用时直接调用 FGSM_attack 函数就可以得到图像了
GOOD LUCK