【人工智能课程】计算机科学博士作业三

【人工智能课程】计算机科学博士作业三

来源:李宏毅2022课程第10课的作业

1 图片攻击概念

图片攻击是指故意对数字图像进行修改,以使机器学习模型产生错误的输出或者产生预期之外的结果。这种攻击是通过将微小的、通常对人类难以察觉的扰动应用于输入图像来实现的。图片攻击是对深度学习系统中的鲁棒性和安全性的一种测试,也可以用于欺骗、隐私侵犯、对抗性水印等。以下是一些常见的图片攻击的目的:

  1. 对抗样本研究:通过图片攻击,研究人员可以探索深度学习模型的鲁棒性和对抗样本的生成方法,以便改进模型的安全性和鲁棒性。
  2. 欺骗机器学习模型:攻击者可能希望通过修改图片使其被错误地分类,从而欺骗机器学习模型,例如将停车标志误识别为速限标志。
  3. 隐私攻击:通过修改图片,攻击者可以消除敏感信息,或者使图像模糊以保护隐私。
  4. 对抗性水印:攻击者可能希望通过添加微小的、难以察觉的扰动,来隐藏或改变水印,或者转移水印,以保护知识产权或者追踪盗版图片来源。

总之,图片攻击的目的可以是为了研究、测试模型的鲁棒性,也可以是出于恶意目的,比如欺骗或者损害隐私。在实际应用中,保护和提高模型的鲁棒性,并确保数据的安全与隐私是至关重要的。

2 算法

除了FGSM、IFGSM和MIFGSM之外,还有一些其他流行的图像攻击算法,包括:

  1. DeepFool:它是一种迭代的无目标攻击算法,通过找到沿着特征空间最不相关的方向来生成对抗样本。

  2. CW攻击(Carlini and Wagner攻击):这个算法试图最小化一种特定的损失函数,以欺骗分类器,并在L2和L∞规范下产生对抗样本。

  3. JSMA(Jacobian-based Saliency Map Attack):JSMA算法通过最大化目标函数的梯度,以找到最有效的像素扰动,使图像被错误分类。

  4. EOT(Expectation over Transformation):EOT算法通过对输入图像进行多个随机扰动,然后对这些扰动的预期值进行优化,生成对抗样本。

  5. One-pixel攻击:这种攻击算法仅修改图像中的几个像素,以欺骗分类器,同时尽可能减少对原始图像的影响。

3 Python实现

3.1 下载数据

# 设置环境
!pip install pytorchcv
!pip install imgaug# 下载数据
!wget https://github.com/DanielLin94144/ML-attack-dataset/files/8167812/data.zip# 解压
!unzip ./data.zip
!rm ./data.zip

3.2 参数设置

import torch
import torch.nn as nndevice = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
batch_size = 8# 平均值和标准差是根据cifar10数据集计算的统计数据
cifar_10_mean = (0.491, 0.482, 0.447) # cifar_10 图片数据三个通道的均值
cifar_10_std = (0.202, 0.199, 0.201) # cifar_10 图片数据三个通道的标准差# 将mean和std转换为三维张量,用于未来的运算
mean = torch.tensor(cifar_10_mean).to(device).view(3, 1, 1)
std = torch.tensor(cifar_10_std).to(device).view(3, 1, 1)epsilon = 8/255/stdroot = '/data' # 用于存储`benign images`的目录

3.3 导入数据

import os
import glob
import shutil
import numpy as np
from PIL import Image
from torchvision.transforms import transforms
from torch.utils.data import Dataset, DataLoadertransform = transforms.Compose([transforms.ToTensor(),transforms.Normalize(cifar_10_mean, cifar_10_std)
])class AdvDataset(Dataset):def __init__(self, data_dir, transform):self.images = []self.labels = []self.names = []'''data_dir├── class_dir│   ├── class1.png│   ├── ...│   ├── class20.png'''for i, class_dir in enumerate(sorted(glob.glob(f'{data_dir}/*'))):images = sorted(glob.glob(f'{class_dir}/*'))self.images += imagesself.labels += ([i] * len(images))self.names += [os.path.relpath(imgs, data_dir) for imgs in images]self.transform = transformdef __getitem__(self, idx):image = self.transform(Image.open(self.images[idx]))label = self.labels[idx]return image, labeldef __getname__(self):return self.namesdef __len__(self):return len(self.images)adv_set = AdvDataset(root, transform=transform)
adv_names = adv_set.__getname__()
adv_loader = DataLoader(adv_set, batch_size=batch_size, shuffle=False)print(f'number of images = {adv_set.__len__()}')

3.4 工具函数

(1)评估模型在良性图像上的性能

# 评估模型在良性图像上的性能
def epoch_benign(model, loader, loss_fn):model.eval()train_acc, train_loss = 0.0, 0.0for x, y in loader:x, y = x.to(device), y.to(device)yp = model(x)loss = loss_fn(yp, y)train_acc += (yp.argmax(dim=1) == y).sum().item()train_loss += loss.item() * x.shape[0]return train_acc / len(loader.dataset), train_loss / len(loader.dataset)

(2)

# 执行对抗性攻击 并生成对抗性示例
def gen_adv_examples(model, loader, attack, loss_fn):model.eval()adv_names = []train_acc, train_loss = 0.0, 0.0for i, (x, y) in enumerate(loader):x, y = x.to(device), y.to(device)x_adv = attack(model, x, y, loss_fn) # obtain adversarial examplesyp = model(x_adv)loss = loss_fn(yp, y)train_acc += (yp.argmax(dim=1) == y).sum().item()train_loss += loss.item() * x.shape[0]# store adversarial examplesadv_ex = ((x_adv) * std + mean).clamp(0, 1) # to 0-1 scaleadv_ex = (adv_ex * 255).clamp(0, 255) # 0-255 scaleadv_ex = adv_ex.detach().cpu().data.numpy().round() # round to remove decimal partadv_ex = adv_ex.transpose((0, 2, 3, 1)) # transpose (bs, C, H, W) back to (bs, H, W, C)adv_examples = adv_ex if i == 0 else np.r_[adv_examples, adv_ex]return adv_examples, train_acc / len(loader.dataset), train_loss / len(loader.dataset)# 创建存储对抗性示例的目录
def create_dir(data_dir, adv_dir, adv_examples, adv_names):if os.path.exists(adv_dir) is not True:_ = shutil.copytree(data_dir, adv_dir)for example, name in zip(adv_examples, adv_names):im = Image.fromarray(example.astype(np.uint8)) # 图片数据需要转成 uint8im.save(os.path.join(adv_dir, name))

3.5 攻击算法

(1)fgsm算法

def fgsm(model, x, y, loss_fn, epsilon=epsilon):x_adv = x.detach().clone() # 用良性图片初始化 x_advx_adv.requires_grad = True # 需要获取 x_adv 的梯度loss = loss_fn(model(x_adv), y) # 计算损失loss.backward()  # fgsm: 在x_adv上使用梯度上升来最大化损失grad = x_adv.grad.detach()x_adv = x_adv + epsilon * grad.sign()return x_adv

(2)ifgsm算法

# 在“全局设置”部分中将alpha设置为步长 
# alpha和num_iter可以自己决定设定成何值
alpha = 0.8 / 255 / std
def ifgsm(model, x, y, loss_fn, epsilon=epsilon, alpha=alpha, num_iter=20):x_adv = x# num_iter 次迭代for i in range(num_iter):x_adv = fgsm(model, x_adv, y, loss_fn, alpha) # 用(ε=α)调用fgsm以获得新的x_adv# x_adv = x_adv.detach().clone()# x_adv.requires_grad = True  # loss = loss_fn(model(x_adv), y)  # loss.backward()  # grad = x_adv.grad.detach()# x_adv = x_adv + alpha * grad.sign()x_adv = torch.max(torch.min(x_adv, x+epsilon), x-epsilon) # x_adv 裁剪到 [x-epsilon, x+epsilon]范围return x_adv

(3)mifgsm算法

def mifgsm(model, x, y, loss_fn, epsilon=epsilon, alpha=alpha, num_iter=20, decay=1.0):x_adv = x# 初始化 momentum tensormomentum = torch.zeros_like(x).detach().to(device)# num_iter 次迭代for i in range(num_iter):x_adv = x_adv.detach().clone()x_adv.requires_grad = True  loss = loss_fn(model(x_adv), y)  loss.backward()  # TODO: Momentum calculationgrad = x_adv.grad.detach() + (1 - decay) * momentummomentum = gradx_adv = x_adv + alpha * grad.sign()x_adv = torch.max(torch.min(x_adv, x+epsilon), x-epsilon) # x_adv 裁剪到 [x-epsilon, x+epsilon]范围return x_adv

(4)EOT算法

def eot_attack(model, x, y, loss_fn, epsilon= 0.03, num_samples= 10, sigma= 0.1):best_adv_example = Nonebest_adv_loss = float('inf')for _ in range(num_samples):perturbation = torch.randn_like(x) * sigmax_adv = x + perturbationx_adv = torch.clamp(x_adv, 0, 1)  # 将像素值限制在合理范围内# 使用 fgsm 得到对抗样本x_adv = fgsm(model, x_adv, y, loss_fn, epsilon)# 计算对抗样本的损失adv_loss = loss_fn(model(x_adv), y).item()# 保留损失最小的对抗样本if adv_loss < best_adv_loss:best_adv_example = x_adv.detach()best_adv_loss = adv_lossreturn best_adv_example

3.6 算法评估

准确率越低越好,损失越大越好

(1)基准模型

from pytorchcv.model_provider import get_model as ptcv_get_modelmodel = ptcv_get_model('resnet110_cifar10', pretrained=True).to(device)
loss_fn = nn.CrossEntropyLoss()benign_acc, benign_loss = epoch_benign(model, adv_loader, loss_fn)
print(f'[ Base(未Attack图片评估) ] benign_acc = {benign_acc:.5f}, benign_loss = {benign_loss:.5f}')

[ Base(未Attack图片评估) ] benign_acc = 0.95000, benign_loss = 0.22678

(2)FGSM算法

adv_examples, fgsm_acc, fgsm_loss = gen_adv_examples(model, adv_loader, fgsm, loss_fn)
print(f'[ Attack(FGSM Attack图片评估) ] fgsm_acc = {fgsm_acc:.5f}, fgsm_loss = {fgsm_loss:.5f}')# create_dir(root, 'fgsm', adv_examples, adv_names)

[ Attack(FGSM Attack图片评估) ] fgsm_acc = 0.59000, fgsm_loss = 2.49272

(3)I-FGSM算法

adv_examples, ifgsm_acc, ifgsm_loss = gen_adv_examples(model, adv_loader, ifgsm, loss_fn)
print(f'[ Attack(I-FGSM Attack图片评估) ] ifgsm_acc = {ifgsm_acc:.5f}, ifgsm_loss = {ifgsm_loss:.5f}')create_dir(root, 'ifgsm', adv_examples, adv_names)

[ Attack(I-FGSM Attack图片评估) ] ifgsm_acc = 0.01000, ifgsm_loss = 17.30204

(4)EOT算法

adv_examples, ifgsm_acc, ifgsm_loss = gen_adv_examples(model, adv_loader, eot_attack, loss_fn)
print(f'[ Attack(I-FGSM Attack图片评估) ] ifgsm_acc = {ifgsm_acc:.5f}, ifgsm_loss = {ifgsm_loss:.5f}')create_dir(root, 'eot', adv_examples, adv_names)

[ Attack(I-FGSM Attack图片评估) ] ifgsm_acc = 0.21000, ifgsm_loss = 5.35198

(5)基于Ensemble 模型的IFGSM算法

class ensembleNet(nn.Module):def __init__(self, model_names):super().__init__()self.models = nn.ModuleList([ptcv_get_model(name, pretrained=True) for name in model_names])self.softmax = nn.Softmax(dim=1)def forward(self, x):ensemble_logits = 0for i, m in enumerate(self.models):ensemble_logits += m(x)return ensemble_logits/len(self.models)
model_names = ['nin_cifar10','resnet20_cifar10','preresnet20_cifar10'
]
ensemble_model = ensembleNet(model_names).to(device)
loss_fn = nn.CrossEntropyLoss()adv_examples, ifgsm_acc, ifgsm_loss = gen_adv_examples(ensemble_model, adv_loader, ifgsm, loss_fn)
print(f'[ Attack(I-FGSM Attack图片评估) ] ifgsm_acc = {ifgsm_acc:.5f}, ifgsm_loss = {ifgsm_loss:.5f}')# create_dir(root, 'ensemble_model_ifgsm', adv_examples, adv_names)

[ Attack(I-FGSM Attack图片评估) ] ifgsm_acc = 0.00000, ifgsm_loss = 13.37727

(6)基于Ensemble 模型的EOT算法

class ensembleNet(nn.Module):def __init__(self, model_names):super().__init__()self.models = nn.ModuleList([ptcv_get_model(name, pretrained=True) for name in model_names])self.softmax = nn.Softmax(dim=1)def forward(self, x):ensemble_logits = 0for i, m in enumerate(self.models):ensemble_logits += m(x)return ensemble_logits/len(self.models)
model_names = ['nin_cifar10','resnet20_cifar10','preresnet20_cifar10'
]
ensemble_model = ensembleNet(model_names).to(device)
loss_fn = nn.CrossEntropyLoss()adv_examples, ifgsm_acc, ifgsm_loss = gen_adv_examples(ensemble_model, adv_loader, eot_attack, loss_fn)
print(f'[ Attack(I-FGSM Attack图片评估) ] ifgsm_acc = {ifgsm_acc:.5f}, ifgsm_loss = {ifgsm_loss:.5f}')create_dir(root, 'ensemble_model_eot', adv_examples, adv_names)

[ Attack(I-FGSM Attack图片评估) ] ifgsm_acc = 0.08000, ifgsm_loss = 3.68992

3.7 可视化

import matplotlib.pyplot as pltclasses = ['airplane', 'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck']plt.figure(figsize=(10, 20))
cnt = 0
for i, cls_name in enumerate(classes):path = f'{cls_name}/{cls_name}1.png'# 未Attack图片(benign image)cnt += 1plt.subplot(len(classes), 4, cnt)im = Image.open(f'./data/{path}')logit = model(transform(im).unsqueeze(0).to(device))[0]predict = logit.argmax(-1).item()prob = logit.softmax(-1)[predict].item()plt.title(f'benign: {cls_name}1.png\n{classes[predict]}: {prob:.2%}')plt.axis('off')plt.imshow(np.array(im))# Attack后图片(adversarial image)cnt += 1plt.subplot(len(classes), 4, cnt)im = Image.open(f'./ensemble_model_ifgsm/{path}')logit = model(transform(im).unsqueeze(0).to(device))[0]predict = logit.argmax(-1).item()prob = logit.softmax(-1)[predict].item()plt.title(f'adversarial: {cls_name}1.png\n{classes[predict]}: {prob:.2%}')plt.axis('off')plt.imshow(np.array(im))
plt.tight_layout()
plt.show()

可以从图中可以看到,图片的识别出现了错误,说明图片攻击成功。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/522192.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

为什么说鸿蒙开发就业面广?人才遭“爆抢”的背后说明什么?

鸿蒙开发&#xff0c;作为华为推出的全新操作系统&#xff0c;自其诞生以来就备受关注。而鸿蒙开发就业面广&#xff0c;人才遭“爆抢”的现象&#xff0c;更是引发了业界的广泛讨论。那么&#xff0c;这一现象背后究竟隐藏着怎样的原因和深意呢&#xff1f; 首先&#xff0c;鸿…

【infiniband监控】grafana变量使用细化优化监控指标

本站以分享各种运维经验和运维所需要的技能为主 《python零基础入门》&#xff1a;python零基础入门学习 《python运维脚本》&#xff1a; python运维脚本实践 《shell》&#xff1a;shell学习 《terraform》持续更新中&#xff1a;terraform_Aws学习零基础入门到最佳实战 《k8…

9道软件测试面试题,刷掉90%的测试程序员

没点真本事真技术&#xff0c;没点面试经验&#xff0c;不了解点职场套路&#xff0c;如何过五关斩六将&#xff1f;如何打败面试官&#xff1f;如何拿下那梦寐以求的offer&#xff1f; 如果你的跳槽意向已经很确定&#xff0c;那么请往下看&#xff01; 跳槽最重要的一步自然…

C/C++内存管理【C++】

目录 一、 C/C内存分布1. C内存管理方式(1) new和delete操作内置类型(2) new和delete操作自定义类型 二、 operator new与operator delete函数三、 malloc/free和new/delete的区别四、内存泄漏 一、 C/C内存分布 C/C程序的内存布局会因编译器和操作系统而有所不同&#xff0c;但…

SoapUI、Jmeter、Postman三种接口测试工具的比较分析

前段时间忙于接口测试&#xff0c;也看了几款接口测试工具&#xff0c;简单从几个角度做了个比较&#xff0c;拿出来与诸位分享一下。本文从多个方面对接口测试的三款常用工具进行比较分析&#xff0c;以便于在特定的情况下选择最合适的工具&#xff0c;或者使用自己编写的工具…

【QT6】打开项目 .pro 一堆报错 但是程序可以运行 打开别人的QT项目后,全是报错

报错环境 我通过在网上拷贝的项目&#xff0c; 然后打开pro文件 build项目 你会发现各种报错 无缘无故的报错 明明环境已经没问题了 解决方案 首先是提示no valid settings file could be found&#xff0c;这个错误很好解决&#xff0c;删除项目目录下的.user文件&#xff…

移掉 K 位数字(LeetCode 402)

文章目录 1.问题描述2.难度等级3.热门指数4.解题思路4.1 暴力法4.2 贪心 单调栈 参考文献 1.问题描述 给你一个以字符串表示的非负整数 num 和一个整数 k&#xff0c;移除这个数中的 k 位数字&#xff0c;使得剩下的整数最小。请你以字符串形式返回这个最小的整数。 示例 1 …

#微信小程序(布局、渲染层基础知识)

1.IDE&#xff1a;微信开发者工具 2.实验&#xff1a; 3.记录: &#xff08;1&#xff09;view&#xff08;类似于div&#xff09; &#xff08;2&#xff09;块级元素不占满一行且水平均分布局flex,justify(space-around) &#xff08;3&#xff09;滚动<scroll view sc…

go语言-k8s宿主信息采集运维脚本

背景 由于工作需要&#xff0c;需要采集k8s集群中的宿主相关信息&#xff0c;包括cpu,memory,lvm,标签等信息。通常作为SRE会主选shell或python脚本来实现。但最近我们团队主流开发语言已经切换到golang.所以本次尝试用go语言来写写运维脚本。 实现流程图 代码实现 package m…

每日OJ题_牛客CM24 最近公共祖先

目录 牛客CM24 最近公共祖先 解析代码 牛客CM24 最近公共祖先 最近公共祖先_牛客题霸_牛客网 解析代码 class LCA { public:int getLCA(int a, int b) {// 左孩 父 * 2 1&#xff0c;右孩 父 * 2 2&#xff1b;// 父 &#xff08;孩 - 1&#xff09; / 2&#xff1b;/…

妇女节特刊 | 上海交大吴梦玥:用言语智能技术,为精神疾病开出第一张诊疗单

从孩童的咿呀学语&#xff0c;到青年时期聊不完的少年心事&#xff0c;进而人到中年&#xff0c;耳边既有父母长辈的叮咛关切&#xff0c;也有生活压力一刻不停的催促……细细回想&#xff0c;人生每个阶段的经历与回忆都萦绕着不同的声音&#xff0c;夏日的蝉鸣与篮球场上的聒…

探索数据可视化:Matplotlib 基础指南

图形绘制 import numpy as np import pandas as pd import matplotlib.pyplot as pltx np.linspace(0,2 * np.pi,100)# 说明&#xff1a;正弦波。x&#xff1a;NumPy数组 # 所有的数据&#xff0c;进行正弦计算 y np.sin(x)plt.plot(x,y)# 指定x轴范围 plt.xlim(-1,10) # 指…