【算法】Boundary Attack算法手稿

原文链接

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。