Contents
如何使用通用对抗扰动(UAP)高效攻击批量模型并评估其迁移性
通用对抗扰动(Universal Adversarial Perturbation, UAP)是一种高度威胁AI部署的攻击手段。与针对单个输入定制的传统对抗样本不同,UAP寻找一个微小且固定的扰动向量 $\delta$,当它被叠加到绝大多数输入 $x$ 上时,都能导致模型 $f$ 的错误分类。对于AI基础设施而言,UAP的威胁在于其极高的效率:一旦生成,它可以被快速应用于整个数据集的批量推理,而无需为每个样本重新计算攻击。本文将深入探讨UAP的生成方法,并提供基于PyTorch的实操代码,用于批量攻击模型并评估其跨模型迁移性。
1. UAP的原理与威胁
UAP的目标是找到一个满足约束(如$|\delta|_\infty < \epsilon$)的扰动 $\delta$,使得:
$$P_{x \sim X} (f(x + \delta) \neq f(x)) \ge 1 – \xi$$
其中 $1 – \xi$ 是所需的“愚弄率”(Fooling Rate)。
UAP的强大之处在于模型决策边界的几何结构。在深度神经网络的高维空间中,决策边界通常被认为与数据流形平行,这使得一个固定的、通用的小扰动就能有效地将大量数据点推过边界。
2. 基于DeepFool的UAP生成实现
我们通常采用迭代优化的方法来生成UAP,该过程涉及在整个训练集或大型子集上,不断积累将样本推向决策边界的最小扰动方向。这里我们使用一个简化的基于梯度积累的方法。
2.1 环境准备
1 pip install torch torchvision numpy
2.2 UAP生成核心代码(PyTorch)
以下代码展示了如何在一个小数据集上迭代生成一个L-infinity范数约束的通用扰动 P。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74 import torch
import torch.nn as nn
import torchvision.models as models
from torch.utils.data import DataLoader, Dataset
import numpy as np
# 假设我们有一个简化的数据集类 (实际应加载CIFAR或ImageNet子集)
class DummyDataset(Dataset):
def __init__(self, size=1000):
self.data = torch.randn(size, 3, 224, 224)
self.labels = torch.randint(0, 10, (size,))
def __len__(self):
return len(self.data)
def __getitem__(self, idx):
return self.data[idx], self.labels[idx]
# 1. 初始化模型和数据
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = models.resnet18(pretrained=True).eval().to(device)
dataset = DummyDataset(size=500)
dataloader = DataLoader(dataset, batch_size=32)
# UAP 生成参数
EPSILON = 10 / 255.0 # L_inf 约束
MAX_ITER = 5 # 迭代次数
# 初始化通用扰动 P
P = torch.zeros(1, 3, 224, 224).to(device).requires_grad_(True)
print("--- 开始 UAP 生成 ---")
for epoch in range(MAX_ITER):
for images, labels in dataloader:
images, labels = images.to(device), labels.to(device)
# 步骤 1: 应用当前扰动并获取模型输出
perturbed_images = images + P
perturbed_images.requires_grad = True
outputs = model(perturbed_images)
# 获取模型预测的当前类别
_, pred_labels = torch.max(outputs, 1)
# 仅对模型分类正确的样本进行攻击
correct_mask = (pred_labels == labels).detach()
if not correct_mask.any():
continue
# 步骤 2: 计算损失 (这里我们尝试最大化模型分类到非原始类别的置信度)
# 实际更复杂的UAP使用最小距离导向(如DeepFool),这里简化为基于交叉熵的梯度上升
target_outputs = outputs[correct_mask]
target_labels = labels[correct_mask]
# 使用负交叉熵进行梯度上升,以推动模型远离正确分类
loss = -nn.CrossEntropyLoss()(target_outputs, target_labels)
model.zero_grad()
loss.backward()
# 步骤 3: 更新 P
# 积累梯度
grad_acc = P.grad.data.clone()
# 规范化并进行小步更新 (类似于迭代FGSM)
P.data += grad_acc.sign() * (EPSILON / MAX_ITER) # 粗略的步长控制
# 步骤 4: 投影 (Project P back to L_inf ball)
P.data.clamp_(-EPSILON, EPSILON)
P.grad.zero_()
del images, labels, outputs
print("UAP 生成完成。")
# 最终的通用扰动存储在 P 中
3. 批量攻击与愚弄率评估
生成 UAP 后,基础设施现在只需将其叠加到任何传入的批量数据上,即可进行攻击效率评估。这是 UAP 相较于传统攻击(如FGSM或PGD)在部署中的主要优势。
3.1 批量评估代码
我们将 P 应用到整个数据集,计算模型的准确率下降(即愚弄率)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 def evaluate_fooling_rate(model, dataloader, P, device):
correct_clean = 0
correct_perturbed = 0
total = 0
for images, labels in dataloader:
images, labels = images.to(device), labels.to(device)
perturbed_images = torch.clamp(images + P, 0, 1) # 保持像素值在[0, 1]内
# 清洁样本预测
with torch.no_grad():
outputs_clean = model(images)
_, predicted_clean = torch.max(outputs_clean.data, 1)
correct_clean += (predicted_clean == labels).sum().item()
# 扰动样本预测
outputs_perturbed = model(perturbed_images)
_, predicted_perturbed = torch.max(outputs_perturbed.data, 1)
correct_perturbed += (predicted_perturbed == labels).sum().item()
total += labels.size(0)
clean_acc = 100 * correct_clean / total
perturbed_acc = 100 * correct_perturbed / total
fooling_rate = clean_acc - perturbed_acc
print(f"清洁样本准确率: {clean_acc:.2f}%")
print(f"扰动样本准确率: {perturbed_acc:.2f}%")
print(f"UAP 愚弄率 (准确率下降): {fooling_rate:.2f}%")
return fooling_rate
# 评估在 Model A (ResNet18) 上的效果
_ = evaluate_fooling_rate(model, dataloader, P.detach(), device)
4. 迁移性评估
UAP的另一个关键指标是迁移性(Transferability)。如果一个UAP在模型A上生成,但能有效攻击模型B(甚至模型B拥有不同的架构),那么模型B也面临极大的安全风险。在部署环境中,这意味着攻击者无需知道目标模型的精确架构。
4.1 跨模型评估
我们将上面生成的扰动 P 应用到一个新的、未参与生成的模型(例如 VGG16)上。
1
2
3
4
5
6
7
8
9
10 # 导入 Model B (VGG16)
model_b = models.vgg16(pretrained=True).eval().to(device)
print("--- 评估 UAP 在 VGG16 (Model B) 上的迁移性 ---")
# 注意:我们直接使用在 ResNet18 上生成的 P
migration_fooling_rate = evaluate_fooling_rate(model_b, dataloader, P.detach(), device)
if migration_fooling_rate > 30:
print("!!! 警告:UAP具有高迁移性,不同架构的模型可能面临相同风险。")
4.2 评估意义
如果迁移性评估结果显示愚弄率较高(例如超过30%),则证明模型A和模型B在决策边界附近共享相似的线性特性。这种攻击的效率和鲁棒性使得它成为AI系统防御者必须重点关注的威胁。在AI部署管道中,必须考虑通过对抗训练或集成防御机制来缓解 UAP 攻击。
汤不热吧