9.7.2 运行测试代码
9.7.2运行测试代码
robust-ml提供了测试代码,下载路径为:
在测试代码中attack.py文件实现了PGD和FGSM攻击算法,攻击对象是InceptionV3模型。其中PGD算法是一个轻量级的攻击算法,基本思路是基于迭代优化,但是每次迭代更新时,会根据预先设置的阈值进行数据裁剪,我们结合代码详细介绍PGD算法的实现。首先继承robustml.attack.Attack类实现PGD算法。
classInceptionV3PGDAttack(robustml.attack.Attack):
在类的初始化函数中,输入的参数分别为:
#TensorFlow的会话
self._sess=sess
#被攻击的模型
self._model=model
#每个像素允许的最大扰动,超过的将直接截断
self._epsilon=epsilon
#最大迭代次数,默认为100
self._max_steps=max_steps
#学习速率,默认为0.001
self._learning_rate=learning_rate
#debug开关,默认为False
self._debug=debug
然后定义对应的标签_label并转换成独热编码格式,损失函数定义为预测值与_label的交叉熵,并根据损失函数计算对应的梯度self._grad。
self._label=tf.placeholder(tf.int32,())
one_hot=tf.expand_dims(tf.one_hot(self._label,1000),axis=0)
self._loss=tf.nn.softmax_cross_entropy_with_logits_v2(logits=model.logits,
labels=one_hot)
self._grad,=tf.gradients(self._loss,model.input)
在robust-ml中,攻击算法的主要实现集中在run函数中。如果进行定向攻击,设置定向目标为target,反之为None。
defrun(self,x,y,target):
mult=-1
iftargetisNone:
target=y
mult=1
计算图像扰动后的上限和下限,超过定义的最大扰动将被直接截断。迭代计算预测值、损失值和梯度值。
adv=np.copy(x)
lower=np.clip(x-self._epsilon,0,1)
upper=np.clip(x+self._epsilon,0,1)
foriinrange(self._max_steps):
p,l,g=self._sess.run(
[self._model.predictions,self._loss,self._grad],
{self._model.input:adv,self._label:target}
)
如果满足退出条件即完成迭代,反之则使用梯度值和学习速率更新对抗样本。定向攻击时,预测标签与定向攻击目标一致时退出;无定向攻击时,预测标签与原分类标签不相同时退出。
ifp!=y:
break
adv+=mult*self._learning_rate*np.sign(g)
adv=np.clip(adv,lower,upper)
攻击的模型为InceptionV3,需要下载TensorFlow对应的预训练版本,可直接运行setup.sh。
shsetup.sh
downloading
http://download.tensorflow.org/models/inception_v3_2016_08_28.tar.gz
downloadedinception_v3.ckpt
调用攻击代码在run.py中进行,其中需要指定的参数主要为ImageNet2012数据集的路径imagenet-path和攻击算法attack。默认情况下会攻击100张图片,如果希望修改攻击图片的范围,可以通过指定start和end来设置起始和结束的图片序号。
parser=argparse.ArgumentParser()
parser.add_argument('--imagenet-path',type=str,required=True,
help='directorycontaining`val.txt`and`val/`folder')
parser.add_argument('--start',type=int,default=0)
parser.add_argument('--end',type=int,default=100)
parser.add_argument('--attack',type=str,default='pgd',help='pgd|fgsm|
none')
args=parser.parse_args()
run.py会创建TensorFlow会话并初始化InceptionV3模型。
#创建TensorFlow会话
sess=tf.Session()
#初始化模型
model=InceptionV3(sess)
robust-ml通过provider.ImageNet封装了ImageNet2012。整个攻击过程在robustml.evaluate.evaluate函数中调用并评估攻击和防御效果。其中需要特别指出的是deterministic参数表示是否随机打乱图片顺序和定向攻击的目标标签,如果想提高随机性可以设置为True,如果想让每次运行的结果保持稳定可以设置为False。
#初始化ImageNet图像文件的数据发生器
provider=robustml.provider.ImageNet(args.imagenet_path,(299,299,3))
success_rate=robustml.evaluate.evaluate(model,attack,provider,
start=args.start,
end=args.end,
deterministic=True,
debug=True)
print('attacksuccessrate:%.2f%%(over%ddatapoints)'%(success_
rate*100,args.end-args.start))
运行FGSM攻击算法,攻击成功率为83%。
pythonrun.py--imagenet-path../data/--attackfgsm
attacksuccessrate:83.00%(over100datapoints)
运行PGD攻击算法,攻击成功率为100%。
pythonrun.py--imagenet-path../data/--attackpgd
attacksuccessrate:100.00%(over100datapoints)
robust-ml运行的算法是定向攻击还是无定向攻击,由模型的攻击模式决定。在evaluate函数的实现中可以发现。
https://github.com/robust-ml/robustml/blob/master/robustml/evaluate.py
evaluate函数会读取模型的攻击模式的targeted属性,默认都是无定向攻击。
threat_model=model.threat_model
targeted=threat_model.targeted
本例中使用的攻击模式为linf,为无定向攻击。
self._threat_model=robustml.threat_model.Linf(epsilon=0.01)