基于优化的对抗样本生成算法

参考书籍:AI安全之对抗样本
入门

深度学习在训练过程中,通过计算样本的预测值与真实值之间的损失函数,之后在反向传递的过程中通过链式法则调整模型的参数,不断减小损失函数的值,迭代计算出模型的各层参数。

在这里插入图片描述

生成对抗样本的基本过程也可以参考这一过程,不同的是在迭代训练过程中,将网络参数固定下来,把对抗样本当做唯一需要训练的参数,通过反向传递过程调整对抗样本
在这里插入图片描述

import torch
import torchvision
from torchvision import datasets, transforms
from torch.autograd import Variable
import torch.utils.data.dataloader as Data
import torch.nn as nn
from torchvision import models
import numpy as np
import cv2

#对比展现原始图片和对抗样本图片
def show_images_diff(original_img,original_label,adversarial_img,adversarial_label):
    import matplotlib.pyplot as plt
    plt.figure()

    #归一化
    if original_img.any() > 1.0:
        original_img=original_img/255.0
    if adversarial_img.any() > 1.0:
        adversarial_img=adversarial_img/255.0

    plt.subplot(131)
    plt.title('Original')
    plt.imshow(original_img)
    plt.axis('off')

    plt.subplot(132)
    plt.title('Adversarial')
    plt.imshow(adversarial_img)
    plt.axis('off')

    plt.subplot(133)
    plt.title('Adversarial-Original')
    difference = adversarial_img - original_img
    #(-1,1)  -> (0,1)
    difference=difference / abs(difference).max()/2.0+0.5
    plt.imshow(difference,cmap=plt.cm.gray)
    plt.axis('off')
    plt.tight_layout()
    plt.show()
    
#获取计算设备 默认是CPU
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
#图像加载以及预处理
#从这里修改图片的路径
image_path="../picture/cropped_panda.jpg"
orig = cv2.imread(image_path)[..., ::-1]
orig = cv2.resize(orig, (224, 224))
img = orig.copy().astype(np.float32)

mean = [0.485, 0.456, 0.406]
std = [0.229, 0.224, 0.225]
img /= 255.0
img = (img - mean) / std
img = img.transpose(2, 0, 1)
img=np.expand_dims(img, axis=0)
img = Variable(torch.from_numpy(img).to(device).float())
print("shape=一张图片,三个通道,1代表一张图片,3,224,244,代表3*224*224")
print("0维一元,1维三元,二维224元,三维224元")
print(img.shape)
#使用预测模式 主要影响droupout和BN层的行为
print("——————————————")
print("使用Alexnet模型,进行预测,pretrained=True是预测模式,device是设备信息")
#使用model.eval()时,框架会自动把BN(BatchNorm)和DropOut固定住,不会取平均,而是用训练好的值
model = models.alexnet(pretrained=True).to(device).eval()
label=np.argmax(model(img).data.cpu().numpy())
print("label=+++{}".format(label))


#对抗样本生成核心代码
#图像数据梯度可以获取
img.requires_grad = True
#设置为不保存梯度值 自然也无法修改
for param in model.parameters():
    param.requires_grad = False
#torch.optim.Adam是toch的一个优化工具,通过优化器可以进行参数的优化
optimizer = torch.optim.Adam([img])
#采用交叉熵进行梯度计算
loss_func = torch.nn.CrossEntropyLoss()

epochs=100
#定向攻击的目标
target=288
target=Variable(torch.Tensor([float(target)]).to(device).long())

for epoch in range(epochs):
    # 梯度清零
    optimizer.zero_grad()

    # forward + backward
    output = model(img)
#计算交叉熵
    loss = loss_func(output, target)
    label=np.argmax(output.data.cpu().numpy())
    
    print("epoch={} loss={} label={}".format(epoch,loss,label))
    
    #如果定向攻击成功
    if label == target:
        break
#optimizer.zero_grad() 清空过往梯度;
#loss.backward() 反向传播,计算当前梯度;
#optimizer.step() 根据梯度更新网络参数
    loss.backward()
    optimizer.step()
    
adv=img.data.cpu().numpy()[0]
print(adv.shape)
adv = adv.transpose(1, 2, 0)
adv = (adv * std) + mean
adv = adv * 255.0
#adv = adv[..., ::-1]  # RGB to BGR
adv = np.clip(adv, 0, 255).astype(np.uint8)

show_images_diff(orig,388,adv,target.data.cpu().numpy()[0])
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值