原文链接
https://arxiv.org/abs/1712.04248
源码链接
该攻击的实现作为FoolBox的一部分提供:https://github.com/bethgelab/foolbox
但我没分析这个,我分析的是Opt-Attack源码里提供的Boundary Attack:https://github.com/LeMinhThong/blackbox-attack
Boundary Attack算法手稿
main函数
boundary_attack_mnist:找50张图片的对抗样本
第i+1张图片计算对抗样本(调用attack_untargeted)
attack_untargeted:
函数形参:model:mnist.pt ;train_dataset:60000张图片的集合;x0:原始图片;y0:正确标签
初始化一些数据:num_samples=1000,从60000张图片中抽样1000张图片
在1000个样本上搜索初始方向:
xi:随机抽样的1000张图片中的第i+1张;theta:xi-x0 {Tensor:(1,28,28)},原始图像和其他样本(肯定是对抗样本)之间的差值 ;
fine_grained_binary_search()细粒度二分查找法,找到一个最小的lbd(0~1),使得model.predict(x0 + lbd_mid*theta) != y0
distortion = torch.norm(lbd*theta)计算新的失真 2范式
如果新的distortion<best_distortion:
- 更新: best_distortion,g_theta
初始化一些数据: now_o是1000个抽样里面的最佳失真向量,
开始1000000次的迭代
初始化一个随机向量u
new_o = now_o + u*delta,new_o是初始化的最佳失真向量 + 一个随机向量
new_o = new_o *( torch.norm(now_o) / torch.norm(new_o)) ,使new_o的长度保持和now_o一致
new_o = new_o - epsilon/torch.norm(new_o)*(new_o),缩短new_o
若果 x0+new_o预测出来的标签不等于 y0,也就是仍然保持对抗性,则使 now_o = new_o
最终第i+1张图片的失真为now_o的2范式,返回对抗样本为x0+now_o,其中x0为当前第i+1张原始图片
综上:boundary attack首先通过细粒度二分查找法在随机抽样的1000张图片里找到best_theta和g_theta,然后迭代1000000次,每次生成一个随即向量u,now_o初始化为lbd*theta,这个就是失真向量。new_o = now_o+u*delta,让new_o保持和原来now_o一样的长度,再在现在这个方向上减短。如果model.predict(x0+new_o) != y0:则now_o = new_o,最终对抗样本为x0+now_o。