对抗样本学习01-基于优化的对抗样本生成算法

1. 生成对抗样本的原理

对抗样本学习01-基于优化的对抗样本生成算法_第1张图片

  • 深度学习网络训练,网络参数是被优化的参数,数据是固定的,发生变化的是网络

  • 生成对抗样本,对抗样本是被优化的参数,网络是固定的,发生变化的数据

    How to do?

    首先将图像读取为tensor类型的数据(梯度打开),然后再加载网络模型(模型参数梯度关闭),我们将读取的数据作为待优化的参数。往该数据送入网络,网络得到预测结果,计算预测结果与目标之间的误差,然后更新该数据,从而不断的让该数据接近攻击的目标。这个更新的数据,就是对抗样本,它可以让网络预测值发生偏差。

import torch
import torch.nn as nn
import torchvision
from torchvision import models
import matplotlib.pyplot as plt
from PIL import Image
import numpy as np

# transforms
ToTensor = torchvision.transforms.ToTensor()

# 图像数据获取
mean = [0.485, 0.456, 0.406]
std = [0.229, 0.224, 0.225]
image_path = "E:\Python_Demo\AI对抗样本入门\AI对抗学习\picture\cropped_panda.jpg"
orig_image = Image.open(image_path).convert("RGB")
orig_image = orig_image.resize(size=[224, 224])
orig_image = np.array(orig_image) / 255.0
orig_image = (orig_image - mean) / std
orig_image = orig_image.astype(np.float32)
tensor_orig_image = ToTensor(orig_image)
tensor_orig_image = tensor_orig_image[None, ...]  # torch.Size([1, 3, 224, 224])  cpu

# 模型、标签列表获取
model = models.alexnet(weights=models.AlexNet_Weights.IMAGENET1K_V1).eval()  # cuda
for param in model.parameters():
    param.requires_grad = False
labels_categories = models.AlexNet_Weights.IMAGENET1K_V1.value.meta[
    "categories"]  # labels_categories[388] = “giant panda”

src_pred_label_index = model(tensor_orig_image).argmax(dim=1).item()
print(src_pred_label_index, labels_categories[src_pred_label_index])  # 388 giant panda

# 基于优化的定向攻击
tensor_orig_image.requires_grad = True # 打开输入样本的梯度,
optimizer = torch.optim.Adam(params=[tensor_orig_image])# 将该输入样本作为优化器的优化参数,
target_label_index = torch.tensor([288]) # 指定攻击目标
loss_func = nn.CrossEntropyLoss()
epochs = 500
for epoch in range(epochs):
    optimizer.zero_grad()
    pred_label_nums = model(tensor_orig_image) # 前向传播
    loss = loss_func(pred_label_nums, target_label_index)  # CrossEntropyLoss的src是预测概率Tensor[1,1000],target是真实分类的索引。
    loss.backward() # 反向传播
    pred_label_num = torch.argmax(pred_label_nums, dim=1).item()
    pred_label_class = labels_categories[pred_label_num]
    print("epoch {} | label_num {} | lable_class {}".format(epoch + 1, pred_label_num, pred_label_class))
    if pred_label_num == target_label_index.item():
        break
    optimizer.step() # 更新参数,即更新输入样本

# 可视化
orig_image = ((orig_image * std + mean)*255).astype("uint8")
adv_image = tensor_orig_image.detach()[0].permute([1,2,0]).numpy()
adv_image = np.clip((adv_image*std + mean)*255,0,255).astype("uint8")

plt.subplot(131)
plt.imshow(orig_image)
plt.title(labels_categories[src_pred_label_index])
plt.subplot(132)
plt.imshow(adv_image)
plt.title(labels_categories[target_label_index])
plt.subplot(133)
plt.imshow(adv_image-orig_image)
plt.title("difference")
plt.show()

 对抗样本学习01-基于优化的对抗样本生成算法_第2张图片

 左图就是原始的结果,中间是对抗样本,对抗样本被网络识别为了leopard,右图是原始样本与对抗样本之间的差异。

你可能感兴趣的:(对抗样本,学习,人工智能,对抗样本)