改正了利用Keras實(shí)現(xiàn)FGSM算法里的一些錯(cuò)誤,并添加了一些注釋
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: 目標(biāo)真實(shí)值的張量。
# y_pred: 目標(biāo)預(yù)測值的張量。
loss = losses.categorical_crossentropy(y_true, y_pred)
gradient = backend.gradients(loss, model.input)
gradient = gradient[0]
adv = image + backend.sign(gradient) * eps
# fgsm算法.整個(gè)程序最重要的其實(shí)就只有這一行
sess = backend.get_session()
adv = sess.run(adv, feed_dict={model.input: np.array([image])})
# 注意這里傳遞參數(shù)的情況
adv = np.clip(adv, 0, 1)
# np.clip(adv, 0, 255) #看自己情況選擇 1 或者 255
# 有的像素點(diǎn)會(huì)超過255卖局,需要處理
return adv
def FGSM_attack(model,img,img_number, eps=0.2):#epsilons=20):
print("如果幫助到了你,點(diǎn)個(gè)贊可以嗎辈灼?")
# fgsm攻擊 函數(shù)調(diào)用
# 下面部分代碼(圖像處理)需要根據(jù)自己的攻擊圖像的實(shí)際情況進(jìn)行修改
# # 加載準(zhǔn)備攻擊的模型甫匹,對要攻擊的圖形進(jìn)行轉(zhuǎn)換
lpr_model = model
img_convert=img
ret_predict = lpr_model.predict_classes(np.array([img_convert])) # 進(jìn)行預(yù)測
# 獲取預(yù)測結(jié)果的one-hot編碼,在攻擊時(shí)需要用到
# 是為了求得上一個(gè)函數(shù)中的 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進(jìn)行攻擊")
# 計(jì)算eps的值蓝牲,這里是N等分
# epsilons = np.linspace(0, 1, num=epsilons + 1)[1:]
# 使用循環(huán)來逐漸增加攻擊的強(qiáng)度
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
# 返回對抗樣本(圖像)
使用時(shí)直接調(diào)用 FGSM_attack
函數(shù)就可以得到圖像了
GOOD LUCK