9.5.2 在Cleverhans中使用FGSM算法
9.5.2在Cleverhans中使用FGSM算法
下面我們以MNIST為例介紹如何在Cleverhans中使用FGSM算法,代碼路徑為:
https://github.com/duoergun0729/adversarial_examples/blob/master/code/9-cleverhans-mnist-fgsm.ipynb
首先加載需要使用的Python庫,使用的深度學習框架為TensorFlow。Cleverhans中對攻擊算法的封裝在cleverhans.attacks中,識別MNIST的模型使用ModelBasicCNN。
importlogging
importnumpyasnp
importtensorflowastf
fromcleverhans.lossimportCrossEntropy
fromcleverhans.datasetimportMNIST
fromcleverhans.utils_tfimportmodel_eval
fromcleverhans.trainimporttrain
fromcleverhans.attacksimportFastGradientMethod
fromcleverhans.utilsimportAccuracyReport,set_log_level
fromcleverhans_tutorials.tutorial_modelsimportModelBasicCNN
定義全局變量,其中包括訓練的輪數、批處理的大小、學習速率和CNN模型的卷積核個數。
#定義全局變量
NB_EPOCHS=6
BATCH_SIZE=128
LEARNING_RATE=0.001
CLEAN_TRAIN=True
BACKPROP_THROUGH_ATTACK=False
NB_FILTERS=64
獲取MNIST數據集的訓練集和測試集,以及圖像數據的長寬及通道數據。
#獲取MNIST數據
mnist=MNIST(train_start=train_start,train_end=train_end,
test_start=test_start,test_end=test_end)
x_train,y_train=mnist.get_set('train')
x_test,y_test=mnist.get_set('test')
#使用圖像參數
img_rows,img_cols,nchannels=x_train.shape[1:4]
nb_classes=y_train.shape[1]
定義模型的輸入tensor以及訓練參數。
#定義輸入的TFplaceholder
x=tf.placeholder(tf.float32,shape=(None,img_rows,img_cols,
nchannels))
y=tf.placeholder(tf.float32,shape=(None,nb_classes))
#訓練一個MNIST模型
train_params={
'nb_epochs':nb_epochs,
'batch_size':batch_size,
'learning_rate':learning_rate
}
定義校驗函數,其中preds代表預測結果的tensor,y_set代表數據集x_set對應的真實標籤。在TensorFlow環境下,session加載了預先定義的計算圖,輸入x_set后,preds即為對應的預測結果。
defdo_eval(preds,x_set,y_set,report_key,is_adv=None):
acc=model_eval(sess,x,y,preds,x_set,y_set,args=eval_params)
setattr(report,report_key,acc)
ifis_advisNone:
report_text=None
elifis_adv:
report_text='adversarial'
else:
report_text='legitimate'
ifreport_text:
print('Testaccuracyon%sexamples:%0.4f'%(report_text,acc))
使用ModelBasicCNN在訓練集上進行訓練,損失函數使用交叉熵。訓練完畢后,在測試集上進行驗證。
model=ModelBasicCNN('model1',nb_classes,nb_filters)
preds=model.get_logits(x)
loss=CrossEntropy(model,smoothing=label_smoothing)
defevaluate():
do_eval(preds,x_test,y_test,'clean_train_clean_eval',False)
train(sess,loss,x_train,y_train,evaluate=evaluate,
args=train_params,rng=rng,var_list=model.get_params())
#計算訓練誤差
iftesting:
do_eval(preds,x_train,y_train,'train_clean_train_clean_eval')
經過6輪訓練后,在測試集上獲得了99.29%的準確率。
Testaccuracyonlegitimateexamples:0.9929
設置FGSM的攻擊參數,並初始化FastGradientMethod對象,使用測試集生成對抗樣本,並使用訓練好的ModelBasicCNN對生成的對抗樣本進行預測。
fgsm_params={
'eps':0.3,
'clip_min':0.,
'clip_max':1.
}
#初始化FastGradientMethod對象
fgsm=FastGradientMethod(model,sess=sess)
adv_x=fgsm.generate(x,**fgsm_params)
preds_adv=model.get_logits(adv_x)
#EvaluatetheaccuracyoftheMNISTmodelonadversarialexamples
do_eval(preds_adv,x_test,y_test,'clean_train_adv_eval',True)
預測結果表明,ModelBasicCNN僅能正確識別14.32%的對抗樣本。
Testaccuracyonadversarialexamples:0.1432