当前位置:   article > 正文

对抗样本生成方法学习总结

对抗样本生成

title: 对抗样本生成方法
date: 2023-03-21 15:08:46
tags: pytorch 对抗样本
cover: https://s2.loli.net/2023/03/20/TkeiAjqp3Jdg9tI.png
categories: 深度学习

对抗样本生成方法

为什么会产生对抗样本?

2013年,Szegedy等人首次提出针对深度学习场景下的对抗样本生成算法–BFGS,作者认为,深度神经网络所具有的强大的非线性表达能力和模型的过拟合是可能产生对抗性样本原因之一。2014年,Goodfellow等人(包括Szegedy)对该问题进行了更深层次的研究,它们认为高维空间下深度神经网络的线性线性行为是导致该问题的根本原因。并提出FGSM算法。代码复现链接

image-20230320222100698

在实际问题当中由于我们分类器输出的特征精度有限,通常为8bits,16bits等。以8bits为例,当输入的信息小于 1 256 \frac{1}{256} 2561就会丢失掉该信息、例如 x ~ = x + η \tilde{x}=x+η x~=x+η,如果 η η η足够小的情况下( ∣ ∣ η ∣ ∣ ∞ < ϵ ||η||_{\infty}<\epsilon ∣∣η<ϵ),分类器无法将其区别开。

给定一个向量 η,如果它的无穷范数(即向量中绝对值最大的元素)小于某个值 ε,那么这个向量 η 就满足某个条件。具体来说,这个条件是根据上下文而定的,可能是某个算法中的收敛条件,也可能是某个优化问题中的约束条件等等。

当把无穷范数换成二范数(即欧几里得范数)或一范数时,公式的含义也会有所不同。

如果将无穷范数换成二范数,那么公式就变成了 ∣ ∣ η ∣ ∣ 2 < ϵ ||η||_{2}<\epsilon ∣∣η2<ϵ,表示向量 η 的二范数(即向量中各元素平方和的平方根)小于某个值 ε。这个条件通常用于最小化向量的误差或距离等问题。

如果将无穷范数换成一范数,那么公式就变成了 ∣ ∣ η ∣ ∣ 1 < ϵ ||η||_{1}<\epsilon ∣∣η1<ϵ,表示向量 η 的一范数(即向量中各元素绝对值之和)小于某个值 ε。这个条件通常用于最小化向量的稀疏性等问题。

img

假设我们有一个线性分类器 f ( x ) f(x) f(x),它的输出可以通过如下线性方程表示:
f ( x ) = w T x + b f(x) = w^T x + b f(x)=wTx+b
其中 x x x 是一个输入向量, w w w 是权重向量, b b b 是偏置项, T T T 表示矩阵转置。

现在,假设我们有一个样本 x x x,它的正确分类为 y y y。我们可以表示这个样本的损失函数为 L ( f ( x ) , y ) L(f(x), y) L(f(x),y),其中 L L L 是损失函数。我们的目标是找到 w w w b b b 的值,使得对于所有样本,损失函数 L L L 的值最小。

现在,考虑一个对抗样本 x ~ \tilde{x} x~,它通过向原始输入 x x x 添加一个微小的扰动而产生:

x ~ = x + η \tilde{x} = x + η x~=x+η
其中 η η η 是一个微小的扰动向量。我们希望找到一个合适的扰动 η η η,使得 f ( x ~ ) f(\tilde{x}) f(x~) 得到一个错误的分类。

x ~ \tilde{x} x~ 代入 f ( x ) f(x) f(x) 的公式中,我们有:

f ( x ~ ) = w T ( x + η ) + b = w T x + w T η + b f(\tilde{x}) = w^T (x + η) + b = w^T x + w^T η + b f(x~)=wT(x+η)+b=wTx+wTη+b
我们可以观察到,如果我们选择 η η η w w w 成正比,那么 w T η w^T η wTη 的值将会很大。这意味着,通过调整 η η η 的大小和方向,我们可以使 f ( x ~ ) f(\tilde{x}) f(x~) 的值足够大,从而导致错误的分类。

FGSM类

FSGM算法

FGSM算法的核心思想是,利用输入数据的梯度信息来进行扰动,从而生成对抗样本。具体来说,FGSM算法会计算输入数据关于损失函数的梯度,然后将梯度的符号作为扰动的方向,添加一个很小的扰动,从而生成对抗样本。FGSM算法的公式如下:

  1. 给定输入样本* x x x*和真实标签 y t r u e y_{true} ytrue
  2. 计算输入样本 x x x关于损失函数 J J J的梯度,即 ∇ x J ( x , y t r u e ) \nabla_x J(x, y_{true}) xJ(x,ytrue)
  3. 计算梯度的符号,即 s i g n ( ∇ x J ( x , y t r u e ) ) 。 sign(\nabla_x J(x, y_{true}))。 sign(xJ(x,ytrue))
  4. 将符号作为扰动方向,添加一个很小的扰动 ϵ \epsilon ϵ,即 ϵ ∗ s i g n ( ∇ x J ( x , y t r u e ) ) \epsilon * sign(\nabla_x J(x, y_{true})) ϵsign(xJ(x,ytrue))
  5. 生成对抗样本:

x ~ = x + ϵ ∗ s i g n ( ∇ x J ( x , y t r u e ) ) 。 \tilde{x} = x + \epsilon * sign(\nabla_x J(x, y_{true}))。 x~=x+ϵsign(xJ(x,ytrue))

**伪代码示例:**用MNIST数据集来验证

import torch
import torch.nn as nn

def fgsm_attack(image, epsilon, data_grad): #输入图像,扰动因子,数据梯度
    sign_data_grad = data_grad.sign()  #用符号函数来取梯度方向
    perturbed_image = image + epsilon * sign_data_grad 	#核心公式
    perturbed_image = torch.clamp(perturbed_image, 0, 1) #输入张量大小限制
    return perturbed_image      #返回对抗样本

def generate_adversarial_example(model, device, image, label, epsilon):   #输入模型,设备型号,图片,真实标签,扰动因字
    image = image.to(device) #输入张量转移到指定设备上,避免重复运算
    label = label.to(device)

    image.requires_grad = True	 #启用梯度计算
    output = model(image)    #模型前向传播后所得结果
    loss = nn.CrossEntropyLoss()(output, label)  #调用交叉熵损失函数
    model.zero_grad()   #所有参数的梯度清零,避免累加
    loss.backward()     #损失函数反向传播

    data_grad = image.grad.data  #图形梯度的实际数据
    perturbed_image = fgsm_attack(image, epsilon, data_grad) 
    return perturbed_image

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
import torchvision
import torchvision.transforms as transforms

# 假设您已经有了一个训练好的模型 model
# model = ...

# 准备数据
transform = transforms.Compose([transforms.ToTensor()])#将图像转换为pytorch的张量
dataset = torchvision.datasets.MNIST(root='./data', train=False, download=True, transform=transform)  #这里只使用测试集,并将图像预处理应用到数据集上。
dataloader = torch.utils.data.DataLoader(dataset, batch_size=1, shuffle=True)    #创建数据加载器的对象,数据集,批次大小,是否打乱

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")    
model.to(device)
model.eval()     #将模式切换为评估模式,关闭模型在训练阶段启用的功能,如 dropout 和 batch normalization。

epsilon = 0.1  #扰动因子大小

for data, target in dataloader:
    # 生成对抗样本
    perturbed_data = generate_adversarial_example(model, device, data, target, epsilon)  #调用之前定义的函数

    # 使用模型进行预测
    output = model(perturbed_data) #前向传播
    _, pred = torch.max(output, 1) #找到模型输出(output)中的最大值,并获取其索引。这里,我们沿着第一个维度(dim=1)进行操作,即获取每个样本的最大概率对应的类别。pred 包含了模型的预测结果。

    # 检查模型的预测是否正确
    print("Original label:", target.item()) #打印原始标签
    print("Predicted label:", pred.item())  #打印预测的标签
    break   #对单张图片进行测试就不遍历了

  • 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

I-FGSM

ADVERSARIAL EXAMPLES IN THE PHYSICAL WORLD:论文链接代码链接

image-20230321120600704

  1. 对抗样本的更新:

x ~ t + 1 = x ~ t + α ∗ s i g n ( ∇ x J ( x ~ t , y t r u e ) ) \tilde{x}_{t+1} = \tilde{x}_{t} + \alpha * sign(\nabla_x J(\tilde{x}_{t}, y_{true})) x~t+1=x~t+αsign(xJ(x~t,ytrue))

其中, x ~ t + 1 \tilde{x}_{t+1} x~t+1 表示第 t t t 次迭代生成的对抗样本, x ~ t + 1 \tilde{x}_{t+1} x~t+1 表示第 t + 1 t+1 t+1 次迭代生成的对抗样本,$\alpha $ 是每次迭代的扰动步长, y t r u e y_{true} ytrue是输入图像的真实标签, ∇ x J ( x ~ t , y t r u e ) \nabla_x J(\tilde{x}_{t}, y_{true}) xJ(x~t,ytrue) 是损失函数关于第 t t t 次迭代生成的对抗样本 x ~ t \tilde{x}_{t} x~t的梯度。

  1. 扰动投影:

c l i p ( x ~ t + 1 , x − ϵ , x + ϵ ) clip(\tilde{x}_{t+1}, x - \epsilon, x + \epsilon) clip(x~t+1,xϵ,x+ϵ)

其中, c l i p clip clip 函数用于将对抗样本 x ~ t + 1 \tilde{x}_{t+1} x~t+1限制在允许的扰动范围内(即 x − ϵ x - \epsilon xϵ x + ϵ x + \epsilon x+ϵ之间)。这样可以确保对抗样本的扰动不会超过预设的 ϵ ϵ ϵ

import torch

def i_fgsm_attack(image, epsilon, data_grad, num_iter, alpha):
    perturbed_image = image.clone()  # 初始化对抗样本为原始输入图像

    for _ in range(num_iter):  # 迭代 num_iter 次
        perturbed_image.requires_grad = True  # 设置对抗样本的 requires_grad 属性为 True,以计算梯度

        # 使用当前对抗样本计算损失函数的梯度
        output = model(perturbed_image)
        loss = criterion(output, label) #这个是以及实例化了交叉熵函数
        model.zero_grad()
        loss.backward()
        perturbed_grad = perturbed_image.grad.data

        # 根据梯度更新对抗样本
        perturbed_image = perturbed_image + alpha * perturbed_grad.sign()

        # 将对抗样本投影回定义的扰动范围内
        perturbation = torch.clamp(perturbed_image - image, min=-epsilon, max=epsilon)
        perturbed_image = torch.clamp(image + perturbation, min=0, max=1).detach()

    return perturbed_image

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

该论文还研究了扰动比例的概念:

为了研究任意变换对对抗图像的影响,我们引入了扰动率的概念。可以将其描述为对抗图像的比例,这些图像在转换后不再被错误分类。

A A A 表示原始的对抗样本集合,其中包含 n n n 个对抗样本,即 A = x ~ 1 , x ~ 2 , . . . , x ~ n A = {\tilde{x}_1, \tilde{x}_2, ..., \tilde{x}_n} A=x~1,x~2,...,x~n。每个对抗样本 x ~ i \tilde{x}_i x~i 都是通过攻击原始样本 x i x_i xi 获得的。

T ( x ~ ) T(\tilde{x}) T(x~) 表示对对抗样本 x ~ \tilde{x} x~ 施加的任意变换,例如旋转、缩放或平移等。

C ( x ~ ) C(\tilde{x}) C(x~) 表示对于对抗样本 x ~ \tilde{x} x~,模型的预测是否正确。如果预测正确,则 C ( x ~ ) = 1 C(\tilde{x}) = 1 C(x~)=1;如果预测错误,则 C ( x ~ ) = 0 C(\tilde{x}) = 0 C(x~)=0

根据这些定义,我们可以计算变换 T T T 后被错误分类的对抗样本比例,即扰动率(Perturbation Rate, PR):
P R ( T ) = ∑ i = 1 n C ( T ( x ~ i ) ) n PR(T) = \frac{\sum_{i=1}^n C(T(\tilde{x}_i))}{n} PR(T)=ni=1nC(T(x~i))

这个公式计算了变换 T T T 后,错误分类的对抗样本占总对抗样本的比例。扰动率越高,表明变换 T T T 对对抗样本的效果影响越大。注意,这个公式依赖于您的任务和模型,因为 C ( x ~ ) C(\tilde{x}) C(x~) 是根据模型的预测来计算的。

MI-FGSM

论文链接:Boosting Adversarial Attacks with Momentum

开源代码:Non-Targeted-Adversarial-Attacks

Targeted-Adversarial-Attack

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DbCycemR-1679420060603)(null)]

深度神经网络容易受到对抗样本的攻击,由于潜在的严重后果,这些算法对安全性造成了担忧。对抗性攻击是评估深度学习模型部署之前的鲁棒性的重要替代方法。但是,大多数现有的对抗攻击攻击黑箱模型的成功率很低。

为了解决这个问题,我们提出了一类基于动量的迭代算法来增强对抗性攻击。通过将动量项整合到攻击的迭代过程中,我们的方法可以稳定更新方向,并在迭代过程中摆脱不良的局部最大值,从而产生更具可传递性的对抗样本。为了进一步提高黑盒攻击的成功率,我们将动量迭代算法应用于一组模型,并证明具有强大防御能力的经过对抗训练的模型也容易受到我们的黑盒攻击的攻击。

  1. 初始化:选定一个原始输入样本 x x x 和对应的正确标签 y t r u e y_{true} ytrue。设置最大扰动范围 ϵ \epsilon ϵ,迭代步长 α \alpha α,迭代次数 n u m i t e r num_{iter} numiter 以及动量系数 μ \mu μ。初始化对抗样本 x ~ 0 = x \tilde{x}_0 = x x~0=x 和动量 m 0 = 0 m_0 = 0 m0=0

  2. 对于每次迭代 t = 1 , 2 , . . . , n u m i t e r t = 1, 2, ..., num_{iter} t=1,2,...,numiter,执行以下操作:

​ a. 计算损失函数 J ( x ~ t − 1 , y t r u e ) J(\tilde{x}_{t-1}, y_{true}) J(x~t1,ytrue) 关于当前对抗样本 x ~ t − 1 \tilde{x}_{t-1} x~t1 的梯度:
∇ x J ( x ~ t − 1 , y t r u e ) \nabla_x J(\tilde{x}_{t-1}, y_{true}) xJ(x~t1,ytrue)
​ b. 更新动量: m t = μ ∗ m t − 1 + ∇ x J ( x ~ t − 1 , y t r u e ) ∣ ∇ x J ( x ~ t − 1 , y t r u e ) ∣ 1 m_t = \mu * m_{t-1} + \frac{\nabla_x J(\tilde{x}_{t-1}, y_{true})}{|\nabla_x J(\tilde{x}_{t-1}, y_{true})|_1} mt=μmt1+xJ(x~t1,ytrue)1xJ(x~t1,ytrue)。其中, μ \mu μ 是动量系数, ∣ ⋅ ∣ 1 |\cdot|_1 1 表示 L1 范数。

​ c. 更新对抗样本: x ~ t = x ~ t − 1 + α ∗ s i g n ( m t ) \tilde{x}_t = \tilde{x}_{t-1} + \alpha * sign(m_t) x~t=x~t1+αsign(mt)

​ d. 将对抗样本 x ~ t \tilde{x}_t x~t 限制在允许的扰动范围内: x ~ t = c l i p ( x ~ t , x − ϵ , x + ϵ ) \tilde{x}_t = clip(\tilde{x}_t, x - \epsilon, x + \epsilon) x~t=clip(x~t,xϵ,x+ϵ)

  1. 完成所有迭代后,输出最终的对抗样本 x ~ n u m i t e r \tilde{x}_{num_{iter}} x~numiter

MI-FGSM 算法在每次迭代中,都会根据损失函数的梯度和动量来更新对抗样本。动量的引入有助于沿着梯度的主要方向累积更新,从而提高收敛速度。同时,动量可以平滑梯度,避免陷入局部最小值。

import torch
import torch.nn as nn

def mi_fgsm_attack(model, image, label, epsilon, alpha, num_iter, mu):
    # 确保模型处于评估(推理)模式
    model.eval()

    # 将输入图像和标签转移到相同的设备(例如 GPU)上
    image = image.to(device)
    label = label.to(device)

    # 初始化对抗样本和动量,这个函数复制出来的张量没有梯度信息
    adv_image = image.clone().detach()
    momentum = torch.zeros_like(adv_image)

    # 创建损失函数(交叉熵损失)
    criterion = nn.CrossEntropyLoss()

    for i in range(num_iter):
        # 计算对抗样本的梯度
        adv_image.requires_grad = True
        output = model(adv_image)
        loss = criterion(output, label)
        model.zero_grad()
        loss.backward()
        grad = adv_image.grad.data

        # 更新动量
        momentum = mu * momentum + grad / grad.norm(p=1)

        # 使用动量更新对抗样本
        adv_image = adv_image.detach() + alpha * torch.sign(momentum)

        # 限制对抗样本在允许的扰动范围内
        adv_image = torch.max(torch.min(adv_image, image + epsilon), image - epsilon)
        adv_image = torch.clamp(adv_image, 0, 1)  # 限制像素值在 [0, 1] 范围内

    return adv_image

  • 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

PGD

论文地址

代码链接

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WOcfV81Y-1679420059468)(null)]

主要贡献

  1. 我们对与该鞍点公式相对应的优化环境进行了仔细的实验研究。尽管其组成部分具有非凸性和非凹性,但我们发现根本的优化问题毕竟是可解决的。特别是,我们提供了有力的证据,证明一阶方法可以可靠地解决此问题。我们用来自真实分析的思想补充这些见解,以进一步激发投影梯度下降(PGD)作为通用的“一阶攻击”,即,利用有关网络的本地一阶信息的最强攻击。
  2. 我们探索了网络架构对对抗鲁棒性的影响,并发现模型能力在这里起着重要的作用。为了可靠地抵抗强大的对抗攻击,网络需要的容量要比仅正确分类良性样本的容量更大。这表明,鞍点问题的鲁棒决策边界比仅将良性数据点分开的决策边界要复杂得多。
  3. 基于以上见解,我们在MNIST和CIFAR10上训练了网络,这些网络可抵抗各种对抗性攻击。
import torch
import torch.nn as nn

class PGD():
    def __init__(self, model):
        self.model = model
        self.emb_backup = {}
        
    def attack(self, epsilon=1., alpha=0.3, emb_name='emb.', is_first_attack=False):
        for name, param in self.model.named_parameters():
            if param.requires_grad and emb_name in name:
                if is_first_attack:
                    self.emb_backup[name] = param.data.clone()
                norm = torch.norm(param.grad)
                if norm != 0 and not torch.isnan(norm):  #我也不知道为毛typora不渲染成!=
                    r_at = alpha * param.grad / norm
                    param.data.add_(r_at)
                    param.data
                    param.data = self.project(name, param.data, epsilon)

    def project(self, param_name, param_data, epsilon):
        r = param_data - self.emb_backup[param_name]
        if torch.norm(r) > epsilon:
            r = epsilon * r / torch.norm(r)
        return self.emb_backup[param_name] + r

# 假设你有一个简单的模型,如下所示:
class SimpleModel(nn.Module):
    def __init__(self):
        super(SimpleModel, self).__init__()
        self.emb = nn.Embedding(10, 3)
        self.linear = nn.Linear(3, 1)

    def forward(self, x):
        x = self.emb(x)
        x = self.linear(x)
        return x

# 创建一个简单模型实例
model = SimpleModel()

# 创建 PGD 攻击实例
pgd = PGD(model)

# 假设你已经计算了模型的损失,并对损失进行了反向传播
# ...
# 在更新参数之前,执行 PGD 攻击
pgd.attack(epsilon=1., alpha=0.3, emb_name='emb.', is_first_attack=True)

# 然后,你可以像往常一样更新模型的参数
# ...

  • 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

关于改进PGD的论文(还没来得及看)

  1. Zhang, D., Zhang, T., Lu, Y., Zhu, Z. & Dong, B. You Only Propagate Once: Accelerating Adversarial Training via Maximal Principle.
  2. Madry, A., Makelov, A., Schmidt, L., Tsipras, D. & Vladu, A. Towards Deep Learning Models Resistant to Adversarial Attacks. arXiv:1706.06083 [cs, stat] (2019).
  3. Zhu, C. et al. FreeLB: Enhanced Adversarial Training for Language Understanding. arXiv:1909.11764 [cs] (2019).
  4. Shafahi, A. et al. Adversarial Training for Free! arXiv:1904.12843 [cs, stat] (2019).

C&W

论文地址

代码地址

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SiGO6R7W-1679420060649)(null)]

C&W攻击(Carlini & Wagner攻击)是一种基于优化的对抗样本生成方法。该方法的目标是找到一个最小的扰动,使得机器学习模型产生错误的预测。C&W攻击通过优化一个特定的目标函数来生成对抗样本。以下是算法的主要步骤和相关公式。

1.定义一个目标函数: C&W攻击的核心是定义一个目标函数 f f f,以找到一个最小的扰动 δ \delta δ。目标函数如下所示:
f ( x + δ ) = max ⁡ ( max ⁡ i ≠ t Z ( x + δ ) i − Z ( x + δ ) t , − κ ) f(x + \delta) = \max\left(\max_{i \neq t}{Z(x + \delta)_i} - Z(x + \delta)_t, -\kappa\right) f(x+δ)=max(i=tmaxZ(x+δ)iZ(x+δ)t,κ)
其中, x x x是原始输入, δ \delta δ是添加到输入的扰动, t t t x x x的真实类别, Z ( x + δ ) Z(x+\delta) Z(x+δ)是模型在输入 x + δ x+\delta x+δ上的预测得分(通常为logits), κ \kappa κ是一个用于控制目标函数置信度的参数。

2.将问题转换为优化问题: 我们希望找到一个最小的扰动 δ \delta δ,使得 f ( x + δ ) ≤ 0 f(x+\delta) \leq 0 f(x+δ)0。这可以通过将其表示为以下优化问题来实现:
min ⁡ δ      ∥ δ ∥ 2 s.t.      f ( x + δ ) ≤ 0 \min_\delta \;\; \|\delta\|_2 \\ \text{s.t.} \;\; f(x + \delta) \le 0 δminδ2s.t.f(x+δ)0
3.变量变换:

为了使问题更容易解决,我们可以对输入应用变量变换。我们可以定义一个新的变量 w w w,使得 x ′ = 1 2 ( tanh ⁡ ( w ) + 1 ) x' = \frac{1}{2}(\tanh(w) + 1) x=21(tanh(w)+1)。现在,我们的优化问题变为:

min ⁡ w      ∥ 1 2 ( tanh ⁡ ( w ) + 1 ) − x ∥ 2 2 s.t.      f ( 1 2 ( tanh ⁡ ( w ) + 1 ) ) ≤ 0 \min_w \;\; \left\| \frac{1}{2}(\tanh(w) + 1) - x \right\|_2^2 \\ \text{s.t.} \;\; f\left(\frac{1}{2}(\tanh(w) + 1)\right) \le 0 wmin 21(tanh(w)+1)x 22s.t.f(21(tanh(w)+1))0

  1. 使用优化算法求解: 在获得优化问题后,我们可以使用梯度下降类的优化算法(例如:L-BFGS、Adam等)来求解。
  2. 生成对抗样本: 通过求解优化问题,我们可以找到最优的 w ∗ w^* w,从而生成对抗样本。
    x a d v = 1 2 ( tanh ⁡ ( w ∗ ) + 1 ) x_{adv} = \frac{1}{2}(\tanh(w^*) + 1) xadv=21(tanh(w)+1)

Deepfool

论文链接

代码链接

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UxPJoO8u-1679420059504)(null)]

先进的深度神经网络在许多图像分类任务上均取得了令人印象深刻的结果。但是,这些相同的体系结构已显示出对图像的细微的扰动是不稳定的。尽管此现象很重要,但尚未提出有效的方法来准确计算针对此类大规模数据集扰动的、最新分类器的鲁棒性。

在本文中,我们填补了这一空白,并提出了DeepFool算法,以有效地计算出欺骗深层网络的扰动,从而可靠地量化这些分类器的鲁棒性。大量的实验结果表明,在计算对抗性扰动和使分类器更健壮的任务上,我们的方法优于最新方法。

  1. 对于输入样本x,计算模型的预测: f ( x ) f(x) f(x)

  2. 初始化扰动 δ \delta δ为零: δ = 0 \delta = 0 δ=0

  3. 对于每次迭代,在当前输入样本 x + δ x + \delta x+δ上线性化模型,然后求解最优扰动方向。在本轮迭代中,找到使得类别发生改变的最小扰动 δ ( i ) \delta^{(i)} δ(i)。具体来说,对于二分类问题,寻找最优扰动方向 δ ( i ) \delta^{(i)} δ(i)可以通过解决以下优化问题实现:

    min ⁡ δ ( i )    ∣ f ^ ( x + δ ) − f ^ ( x ) ∣ ∥ ∇ f ^ ( x ) ∥ 2 s.t.      f ^ ( x + δ ) = 0 \min_{\delta^{(i)}} \; \frac{|\hat{f}(x + \delta) - \hat{f}(x)|}{\|\nabla \hat{f}(x)\|_2} \\ \text{s.t.} \;\; \hat{f}(x + \delta) = 0 δ(i)min∥∇f^(x)2f^(x+δ)f^(x)s.t.f^(x+δ)=0

其中 f ^ ( x ) = f ( x ) − y \hat{f}(x) = f(x) - y f^(x)=f(x)y, y y y是正确的类别。对于多分类问题,优化问题稍有不同,我们需要在所有的分类边界中找到最接近当前点的边界:
min ⁡ δ ( i )    ∣ f ^ k ( x + δ ) − f ^ j ( x ) ∣ ∥ ∇ ( f ^ k ( x ) − f ^ j ( x ) ) ∥ 2 s.t.      f ^ k ( x + δ ) = f ^ j ( x ) \min_{\delta^{(i)}} \; \frac{|\hat{f}_k(x + \delta) - \hat{f}_j(x)|}{\|\nabla (\hat{f}_k(x) - \hat{f}_j(x))\|_2} \\ \text{s.t.} \;\; \hat{f}_k(x + \delta) = \hat{f}_j(x) δ(i)min∥∇(f^k(x)f^j(x))2f^k(x+δ)f^j(x)s.t.f^k(x+δ)=f^j(x)
其中 k k k j j j分别是当前类别和其他类别的索引。

  1. 更新扰动 δ = δ + δ ( i ) \delta = \delta + \delta^{(i)} δ=δ+δ(i)
  2. 重复步骤3和4,直到达到预定的迭代次数,或者找到的扰动 δ \delta δ已经导致了类别改变。
  3. 返回对抗样本: x a d v = x + δ x_{adv} = x + \delta xadv=x+δ

DeepFool算法的主要优点是生成的扰动较小,而且相对于其他方法,它更接近计算最优的对抗扰动。然而,它的缺点是算法相对复杂,计算成本较高。

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/296212
推荐阅读
相关标签
  

闽ICP备14008679号