对抗样本攻击
前言
对抗样本攻击就是对图像加以扰动从而干扰图像分类器产生错误的判断。
主要包括包括错误分类和源/目标错误分类。
- 错误分类的目标意味着对手只希望输出分类是错误的,但并不关心新分类是什么。
- 源/目标错误分类意味着对手想要更改原始属于特定源类的图像,以便将其分类为特定目标类。
FGSM和PGD都是错误分类下面是二者的区别:
PGSM和PGD对比
1. 攻击的基本原理
-
FGSM:
- FGSM 是一种 一次性 攻击方法,只计算 一次 梯度,并基于这个梯度生成对抗样本。
- 它通过以下公式生成对抗样本:
x adv = x + ϵ ⋅ sign ( ∇ x J ( θ , x , y ) ) x_{\text{adv}} = x + \epsilon \cdot \text{sign}(\nabla_x J(\theta, x, y)) xadv=x+ϵ⋅sign(∇xJ(θ,x,y)) - 这里 ϵ \epsilon ϵ 是扰动幅度, sign ( ⋅ ) \ \text{sign}(\cdot) sign(⋅) 表示梯度的符号函数。该方法仅对输入图像的像素添加一个很小的固定方向扰动(符号方向),以最大化损失,从而欺骗分类器。
- 代码实现:
# FGSM 攻击函数 def fgsm_attack(data, epsilon, data_grad): # 获取扰动方向 sign_data_grad = data_grad.sign() # 添加扰动,生成对抗样本 perturbed_data = data + epsilon * sign_data_grad # 将对抗样本的值限制在 [0, 1] 范围内 perturbed_data = torch.clamp(perturbed_data, -1, 1) return perturbed_data
-
PGD:
- PGD 是一种 迭代 攻击方法,它多次计算梯度,并在每一步生成中间对抗样本,然后将结果投影回合法的扰动范围(通常是 ϵ \epsilon ϵ领域内的范围)。
- 公式如下:
x adv t + 1 = clip x , ϵ ( x adv t + α ⋅ sign ( ∇ x J ( θ , x adv t , y ) ) ) x_{\text{adv}}^{t+1} = \text{clip}_{x, \epsilon} \left( x_{\text{adv}}^{t} + \alpha \cdot \text{sign}(\nabla_x J(\theta, x_{\text{adv}}^{t}, y)) \right) xadvt+1=clipx,ϵ(xadvt+α⋅sign(∇xJ(θ,xadvt,y))) - 其中 α \alpha α 是每次更新的步长, clip x , ϵ \text{clip}_{x, \epsilon} clipx,ϵ表示将结果限制在 ϵ \epsilon ϵ领域的范围内(使对抗样本不会离原始样本太远)。这就意味着 PGD 会在小范围内多次调整对抗样本,以增加攻击的成功率。
- 代码实现:
pip install git+https://github.com/fra31/auto-attack #导入模型以及初始化 from autoattack import AutoAttack adversary = AutoAttack(forward_pass, norm='Linf', eps=epsilon, version='standard') #加入PGD x_adv = adversary.run_standard_evaluation(images, labels, bs=batch_size)
2. 攻击的强度
- FGSM:
- FGSM 是一种 快速且简单 的攻击方法,但由于只进行一次扰动,攻击强度相对较低。
- 因为它只使用了单步的梯度信息,对模型的扰动效果较为有限,在一些鲁棒模型(经过防御训练的模型)上攻击效果较差。
- PGD:
- PGD 由于多次迭代、逐步优化对抗样本,因此通常被认为是 更强大、更难防御的攻击。
- 多次梯度迭代可以让对抗样本逐渐朝最优攻击方向前进,因此 PGD 在许多对抗性防御下仍然能够成功攻击模型,被认为是比 FGSM 更强的攻击方法。
3. 计算效率
- FGSM:
- 由于只计算一次梯度,FGSM 的计算开销非常小,生成对抗样本非常快。因此,它适合在计算资源受限或实时性要求较高的场景中使用。
- PGD:
- PGD 需要多次迭代,每次都要计算梯度,因此 计算成本较高。生成一个对抗样本可能需要数倍于 FGSM 的计算时间。
- PGD 的攻击效果比 FGSM 好,但在实时性要求较高的应用中可能不太适合。
4. 使用的场景和效果
- FGSM:
- 适合用于快速测试模型的脆弱性,尤其是在防御性较弱的模型上,FGSM 通常可以快速发现漏洞。
- 由于其简单性,FGSM 通常用于较简单的对抗样本生成任务中,例如验证模型是否存在对抗性脆弱性。
- PGD:
- 适合用于评估模型在 强对抗性攻击 下的鲁棒性,尤其是经过对抗训练的模型(即模型已经对对抗样本进行过训练)。
- 在对抗性防御研究中,PGD 被广泛用作评估标准,作为一种“最强的白盒攻击”来测试模型的抗攻击能力。
实战
对CIFAR10数据集加入FGSM和PGD进行精度测试
FGSM:
epsilon = 0.1
if epoch == epochs - 1:
for x, y in test_iter:
x, y = x.to(device), y.to(device) # 数据转移到GPU设备
n_test += y.shape[0] # 样本数量
# FGSM 对抗攻击测试
x.requires_grad = True
output = model(x)
loss = criterion(output, y)
model.zero_grad()
loss.backward()
data_grad = x.grad.data
# 生成对抗样本并测试
perturbed_data = fgsm_attack(x, epsilon, data_grad)
output_adv = model(perturbed_data)
correct_adv += (output_adv.argmax(dim=1) == y).sum().item() # 计算对抗样本的正确数
print(f'epoch {epoch + 1}/{epochs}, 对抗测试准确率 (FGSM, epsilon={epsilon}): {correct_adv / n_test:.4f}')
PGD:
if epoch == epochs - 1: # 只在最后一个 epoch 进行对抗性攻击评估
# 定义 AutoAttack 使用的前向函数
def forward_pass(x):
return model(x)
# 初始化 AutoAttack
adversary = AutoAttack(forward_pass, norm='Linf', eps=8/255, version='standard')
# 在测试集上生成对抗样本
x_adv = []
y_true = []
for x, y in testloader:
x, y = x.to(device), y.to(device)
x_adv.append(adversary.run_standard_evaluation(x, y))
y_true.append(y)
# 计算模型在对抗样本上的准确率
correct_adv = 0
total_adv = 0
with torch.no_grad():
for x_adv_batch, y_batch in zip(x_adv, y_true):
output_adv = model(x_adv_batch)
correct_adv += (output_adv.argmax(dim=1) == y_batch).sum().item()
total_adv += y_batch.size(0)
adv_accuracy = correct_adv / total_adv
print(f"对抗样本上的准确率 (AutoAttack): {adv_accuracy:.4f}")
总结
特性 | FGSM | PGD |
---|---|---|
迭代次数 | 单步 | 多步 |
计算开销 | 低 | 高 |
攻击强度 | 相对较弱 | 相对较强 |
使用场景 | 快速测试、实时应用 | 强对抗性攻击、防御评估 |
对抗样本生成公式 | x adv = x + ϵ ⋅ sign ( ∇ x J ) x_{\text{adv}} = x + \epsilon \cdot \text{sign}(\nabla_x J) xadv=x+ϵ⋅sign(∇xJ) | x adv t + 1 = clip x , ϵ ( x adv t + α ⋅ sign ( ∇ x J ) ) x_{\text{adv}}^{t+1} = \text{clip}_{x, \epsilon}(x_{\text{adv}}^t + \alpha \cdot \text{sign}(\nabla_x J)) xadvt+1=clipx,ϵ(xadvt+α⋅sign(∇xJ)) |
- FGSM 是一种快速攻击,适合用于发现模型的初步脆弱性,但对于防御性的模型,攻击成功率可能不高。
- PGD 是一种更强的攻击方法,通过多步优化,可以在限定范围内找到更有效的对抗样本,对抗性更强,因此通常用于评估模型的最坏情况表现。