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