当前位置:   article > 正文

基于AlexNet的对抗样本攻击_cw算法

cw算法

目录

一、背景介绍

二、代码实现

1.代码的基本结构

第一部分:数据集的导入

第二部分:模型与优化器的选定,各类参数的设定

第三部分:cw攻击效果的训练

第四部分:攻击结果的可视化

2.cw攻击部分的代码呈现(注释很详细)

三、运行结果

        1.先让模型针对mnist数据集进行识别训练,以得到相应权值

        2.cw攻击效果展现

四、目前存在的问题


一、背景介绍

CW算法是一种基于优化的算法,它同时兼顾高攻击准确率和低对抗扰动的两个方面,达到真正意义上对抗样本的效果,即在模型分类出错的情况下,人眼不可查觉。

如果样本攻击成功就要满足两个条件:(1)对抗样本和对应的干净样本应该差距越小越好;(2)对抗样本应该使得模型分类错,且错的那一类的概率越高越好。由这两部分对应两个loss函数。

第一部分,rn对应着干净样本和对抗样本的差,把对抗样本映射到了tanh空间里面,使x可以在-inf到+inf做变换,有利于优化。也可以认为这种方法是一种平滑的梯度下降的方法,消除了在极端区域中陷入平缓而梯度消失的问题。

第二部分,公式中的Z(x)表示的是样本x通过模型未经过softmax的输出向量,对于干净的样本来说,这个向量的最大值对应的就是正确的类别(如果分类正确的话),现在我们将类别t(也就是我们最后想要攻击成的类别)所对应的逻辑值记为Z(An)t,将最大的值(对应类别不同于t)记为max{Z(An)i : i!=t },如果通过优化使得max{Z(An)i : i!=t } - Z(An)t变小,攻击就离成功更近了。k是置信度,可以理解为,k越大,那么模型分错,且错成的那一类的概率越大。最后就是常数c,这是一个超参数,用来权衡两个loss之间的关系,在这个代码中通过二分查找来确定c值。

 CW是一个基于优化的攻击,主要调节的参数是c和k。它的优点在于,可以调节置信度,生成的扰动小,可以破解很多的防御方法,缺点是很慢。

二、代码实现

1.代码的基本结构

第一部分:数据集的导入

1. 选定的mnist数据集,每次导入一种图片进行cw攻击

2. 图片大小 :28x28 标签 : 0~9

3. 初始图片信息为ndarry格式(28,28,3),经过各种操作(如转换为浮点型,resize高宽大小,transpose等),最终转换为可供模型读取的信息格式

第二部分:模型与优化器的选定,各类参数的设定

1. 我们使用的是alexnet模型和Adam优化器

2. 在进行攻击训练前,已经让alexnet模型针对mnist数据集进行识别的训练,得到了针对mnist数据集的权值

3. 各类参数的设定包括了最大迭代次数,学习率,二分查找最大迭代次数,c的初始值(c为超参数,可以简单理解为两个loss函数在最终loss值中所占比例),k值(置信度),均值,标准差等等

第三部分:cw攻击效果的训练

1. 最外层的循环为每次从数据集中导入一种图片,针对于每次导入的那张图片进行cw攻击

2. 紧接着的循环用于尝试不同的c值,通过二分法查找使得攻击效果最好的c值

3. 再内层的循环为针对一张图片的攻击效果的不断优化

        (1)将当前噪声与原始样本叠加,形成攻击样本

        (2)将攻击样本导入模型,得到梯度和结果

        (3)根据模型检测的结果,计算两个loss函数值

                loss1:用于挑选指定分类标签和剩下其他分类中概率最大者,计算两者之间的概率差

                loss2:用于计算对抗样本和原始数据之间的距离

                loss=c*loss1+loss2

        (4)进行backward,并调用优化器进行优化。(每次循环前进行梯度清零操作)

第四部分:攻击结果的可视化

1. 设定了show函数,在每张图片完成cw攻击后,同时展示其原始样本,生成的对抗样本,及对应噪声。结果图已在后文展现。

2.cw攻击部分的代码呈现(注释很详细)

  1. import cv2
  2. import torch
  3. import torchvision
  4. import numpy as np
  5. import matplotlib.pyplot as plt
  6. from torch.autograd import Variable
  7. from torchvision import models
  8. import os
  9. import PIL as Image
  10. # import Image
  11. os.environ["KMP_DUPLICATE_LIB_OK"]="TRUE"
  12. def show_images_diff(original_img,original_label,adversarial_img,adversarial_label):
  13. plt.figure()
  14. # 归一化
  15. if original_img.any()>1.0:
  16. original_img=original_img/255.0
  17. if adversarial_img.any()>1.0:
  18. adversarial_img=adversarial_img/255.0
  19. plt.subplot(131)
  20. plt.title('Original')
  21. plt.imshow(original_img)
  22. plt.axis('off')
  23. plt.subplot(132)
  24. plt.title(adversarial_img)
  25. plt.title('Adversarial')
  26. plt.imshow(adversarial_img)
  27. plt.axis('off')
  28. plt.subplot(133)
  29. plt.title('Adversarial-Original')
  30. difference=adversarial_img-original_img
  31. # (-1,1)->(1,0)
  32. difference=difference/abs(difference).max()/2.0 +0.5
  33. plt.imshow(difference,cmap=plt.cm.gray)
  34. plt.axis('off')
  35. plt.tight_layout()
  36. plt.show()
  37. def show_images(original_img):
  38. plt.figure()
  39. # 归一化
  40. if original_img.any()>1.0:
  41. original_img=original_img/255.0
  42. plt.subplot(131)
  43. plt.title('Original')
  44. plt.imshow(original_img)
  45. plt.axis('off')
  46. plt.tight_layout()
  47. plt.show()
  48. #数据集地址
  49. images = os.listdir('D:\pycharm\CWattack\pic\MNIST/test/')
  50. length = len(images)
  51. #选择模型
  52. device=torch.device('cuda' if torch.cuda.is_available() else 'cpu')
  53. model=models.alexnet(pretrained=True).to(device).eval()
  54. #设定最大迭代次数、学习率、二分查找最大迭代次数、c的初始值、k值等参数
  55. max_iterations=1000 # 1000次可以完成95%的优化工作
  56. learning_rate=0.01
  57. binary_search_steps=10
  58. initial_const=1e2
  59. confidence=initial_const
  60. k=40
  61. # 像素值区间
  62. boxmin = -3.0
  63. boxmax = 3.0
  64. num_labels=1000 # 类别数
  65. # 攻击目标标签,必须使用one hot编码
  66. target_label = 6
  67. tlab=Variable(torch.from_numpy(np.eye(num_labels)[target_label]).to(device).float())
  68. # np.eye 生成对角矩阵
  69. shape=(1,3,224,224)
  70. #均值和标准差
  71. mean = [0.485, 0.456, 0.406]
  72. std = [0.229, 0.224, 0.225]
  73. # 初始化c的边界
  74. lower_bound=0
  75. c=initial_const
  76. upper_bound=1e10
  77. # 保存最佳的l2值、预测概率值和对抗样本
  78. o_bestl2=1e10
  79. o_bestscore=-1
  80. o_bestattack=[np.zeros(shape)]
  81. # 根据像素值的边界计算标准差boxmul和均值boxplus,把对抗样本转换成新的输入newimg
  82. boxmul=(boxmax-boxmin)/2.0
  83. boxplus=(boxmin+boxmax)/2.0
  84. # 每次导入一张图片进行CW攻击
  85. for i in range(length):
  86. # 图片信息导入以及格式转换
  87. img = cv2.imread('D:\pycharm\CWattack\pic\MNIST/test/' + images[i]) #uint8(64,64,3)
  88. img2 = np.asarray(img, dtype='float32') #numpy (64,64,3)BGR
  89. img2 = img2[..., ::-1] #(64,64,3)RGB
  90. # img2 = np.asarray(img2,dtype='float32')
  91. img2 = cv2.resize(img2, (224, 224))
  92. img1 = img2.copy().astype(np.float32)
  93. img1 /= 255.0
  94. img1 = (img1 - mean) / std
  95. img1 = img1.transpose(2, 0, 1)
  96. img1 = np.expand_dims(img1, axis=0)
  97. # CW攻击过程
  98. for outer_step in range(binary_search_steps):
  99. print("o_bestl2={} confidence={}".format(o_bestl2,confidence))
  100. # 把原始图像转换成图像数据和扰动的形态
  101. timg=Variable(torch.from_numpy(np.arctanh((img1-boxplus)/boxmul*0.99999)).to(device).float())
  102. modifier=Variable(torch.zeros_like(timg).to(device).float())
  103. # 图像数据的扰动量梯度可以获取
  104. modifier.requires_grad = True
  105. optimizer=torch.optim.Adam([modifier],lr=learning_rate) # 优化器
  106. for iteration in range(1,max_iterations+1):
  107. optimizer.zero_grad()
  108. # 定义新输入
  109. newimg=torch.tanh(modifier+timg)*boxmul+boxplus
  110. output=model(newimg)
  111. # 定义cw中的损失函数 loss2:计算对抗样本和原始数据之间的距离
  112. loss2=torch.dist(newimg,(torch.tanh(timg)*boxmul+boxplus),p=2)
  113. # loss1:挑选指定分类标签和剩下其它分类中概率最大者,计算两者之间概率差
  114. real= torch.max(output*tlab)
  115. other=torch.max((1-tlab)*output)
  116. loss1=other-real+k
  117. loss1=torch.clamp(loss1,min=0) # 限制范围,截取功能
  118. loss1=confidence*loss1
  119. # 计算总的损失函数
  120. loss=loss1+loss2
  121. loss.backward(retain_graph=True)
  122. optimizer.step()
  123. l2=loss2
  124. sc=output.data.cpu().numpy()
  125. # 显示当前运行结果
  126. if(iteration%(max_iterations//10)==0):
  127. print("iteration={} loss={} loss1={} loss2={}".format(
  128. iteration,loss,loss1,loss2))
  129. if(l2<o_bestl2)and(np.argmax(sc)==target_label):
  130. print('attack success l2={} target_label={}'.format(l2,target_label))
  131. o_bestl2=l2
  132. o_bestscore=np.argmax(sc)
  133. o_bestattack=newimg.data.cpu().numpy()
  134. # 叠加噪声之后的攻击样本
  135. adv = o_bestattack[0]
  136. adv = adv.transpose(1, 2, 0)
  137. adv = (adv * std) + mean
  138. adv = adv * 255.0
  139. adv = np.clip(adv, 0, 255).astype(np.uint8)
  140. # 调用展示函数展示该图片的原始样本、攻击样本和噪声
  141. show_images_diff(img2, 0, adv, 0)
  142. # 每轮二分查找结束后,更新c值以及对应的边界
  143. confidence_old=-1
  144. if(o_bestscore==target_label)and o_bestscore!=-1:
  145. # 攻击成功,减小c的值
  146. upper_bound=min(upper_bound,confidence)
  147. if upper_bound<1e9:
  148. print()
  149. confidence_old=confidence
  150. confidence=(lower_bound+upper_bound)/2
  151. else:
  152. lower_bound=max(lower_bound,confidence)
  153. confidence_old=confidence
  154. if upper_bound<1e9:
  155. confidence=(lower_bound+upper_bound)/2
  156. else:
  157. confidence *=10
  158. print("outer_step={} confidence {}->{}".format(outer_step,
  159. confidence_old,confidence))

三、运行结果

1.先让模型针对mnist数据集进行识别训练,以得到相应权值

运行结果如下:

2.cw攻击效果展现

四、目前存在的问题

loss1在前10轮中取值很小,有很多时候是0,我们推断与训练过程中种类的设置有关,需要解决。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/296162
推荐阅读
相关标签
  

闽ICP备14008679号