Pytorch | 利用AI-FGTM针对CIFAR10上的ResNet分类器进行对抗攻击

Pytorch | 利用AI-FGTM针对CIFAR10上的ResNet分类器进行对抗攻击

之前已经针对CIFAR10训练了多种分类器:
Pytorch | 从零构建AlexNet对CIFAR10进行分类
Pytorch | 从零构建Vgg对CIFAR10进行分类
Pytorch | 从零构建GoogleNet对CIFAR10进行分类
Pytorch | 从零构建ResNet对CIFAR10进行分类
Pytorch | 从零构建MobileNet对CIFAR10进行分类
Pytorch | 从零构建EfficientNet对CIFAR10进行分类
Pytorch | 从零构建ParNet对CIFAR10进行分类

也实现了一些攻击算法:
Pytorch | 利用FGSM针对CIFAR10上的ResNet分类器进行对抗攻击
Pytorch | 利用BIM/I-FGSM针对CIFAR10上的ResNet分类器进行对抗攻击
Pytorch | 利用MI-FGSM针对CIFAR10上的ResNet分类器进行对抗攻击
Pytorch | 利用NI-FGSM针对CIFAR10上的ResNet分类器进行对抗攻击
Pytorch | 利用PI-FGSM针对CIFAR10上的ResNet分类器进行对抗攻击
Pytorch | 利用VMI-FGSM针对CIFAR10上的ResNet分类器进行对抗攻击
Pytorch | 利用VNI-FGSM针对CIFAR10上的ResNet分类器进行对抗攻击
Pytorch | 利用EMI-FGSM针对CIFAR10上的ResNet分类器进行对抗攻击

本篇文章我们使用Pytorch实现AI-FGTM对CIFAR10上的ResNet分类器进行攻击.

CIFAR数据集

CIFAR-10数据集是由加拿大高级研究所(CIFAR)收集整理的用于图像识别研究的常用数据集,基本信息如下:

  • 数据规模:该数据集包含60,000张彩色图像,分为10个不同的类别,每个类别有6,000张图像。通常将其中50,000张作为训练集,用于模型的训练;10,000张作为测试集,用于评估模型的性能。
  • 图像尺寸:所有图像的尺寸均为32×32像素,这相对较小的尺寸使得模型在处理该数据集时能够相对快速地进行训练和推理,但也增加了图像分类的难度。
  • 类别内容:涵盖了飞机(plane)、汽车(car)、鸟(bird)、猫(cat)、鹿(deer)、狗(dog)、青蛙(frog)、马(horse)、船(ship)、卡车(truck)这10个不同的类别,这些类别都是现实世界中常见的物体,具有一定的代表性。

下面是一些示例样本:

AI-FGTM介绍

AI - FGTM(Adam Iterative Fast Gradient Tanh Method)是一种用于生成对抗样本的算法,旨在提高对抗样本的转移性和不可区分性。

算法流程

初始化

  1. 给定原始干净样本 x x x,令 x 0 a d v = x x_{0}^{a d v}=x x0adv=x。
  2. 初始化第一时刻向量 m 0 = 0 m_{0}=0 m0=0,第二时刻向量 v 0 = 0 v_{0}=0 v0=0。

迭代更新( t = 0 t = 0 t=0 到 T − 1 T - 1 T−1)

  1. 计算当前梯度
    • 计算对抗样本 x t a d v x_{t}^{a d v} xtadv 关于真实标签 y t r u e y^{true} ytrue 的损失函数(J)的梯度 ∇ x t a d v J ( x t a d v , y t r u e ) \nabla_{x_{t}^{a d v}} J(x_{t}^{a d v}, y^{true}) ∇xtadvJ(xtadv,ytrue)。
  2. 更新一阶矩 m t + 1 m_{t + 1} mt+1
    • 根据公式 m t + 1 = m t + μ 1 ⋅ ∇ x t a d v J ( x t a d v , y t r u e ) m_{t + 1}=m_{t}+\mu_{1} \cdot \nabla_{x_{t}^{a d v}} J(x_{t}^{a d v}, y^{true}) mt+1=mt+μ1⋅∇xtadvJ(xtadv,ytrue) 计算 m t + 1 m_{t + 1} mt+1,其中 μ 1 \mu_{1} μ1 是一阶矩因子。
  3. 更新第二时刻向量 v t + 1 v_{t + 1} vt+1
    • 根据公式 v t + 1 = v t + μ 2 ⋅ ( ∇ x t a d v J ( x t a d v , y t r u e ) ) 2 v_{t + 1}=v_{t}+\mu_{2} \cdot (\nabla_{x_{t}^{a d v}} J(x_{t}^{a d v}, y^{true}))^{2} vt+1=vt+μ2⋅(∇xtadvJ(xtadv,ytrue))2 计算 v t + 1 v_{t + 1} vt+1,其中 μ 2 \mu_{2} μ2 是二阶矩因子。
  4. 计算步长 α t \alpha_{t} αt
    • 根据公式 α t = ε ∑ t = 0 T − 1 1 − β 1 t + 1 ( 1 − β 2 t + 1 ) 1 − β 1 t + 1 ( 1 − β 2 t + 1 ) \alpha_{t}=\frac{\varepsilon}{\sum_{t = 0}^{T - 1} \frac{1 - \beta_{1}^{t + 1}}{\sqrt{(1 - \beta_{2}^{t + 1})}}} \frac{1 - \beta_{1}^{t + 1}}{\sqrt{(1 - \beta_{2}^{t + 1})}} αt=∑t=0T−1(1−β2t+1) 1−β1t+1ε(1−β2t+1) 1−β1t+1 计算步长 α t \alpha_{t} αt,其中 ε \varepsilon ε 是扰动大小, β 1 \beta_{1} β1 和 β 2 \beta_{2} β2 是指数衰减率,且满足 ∑ t = 0 T − 1 α t = ε \sum_{t = 0}^{T - 1} \alpha_{t}=\varepsilon ∑t=0T−1αt=ε。
  5. 更新对抗样本 x t + 1 a d v x_{t + 1}^{a d v} xt+1adv
    • 根据公式 x t + 1 a d v = C l i p ε x { x t a d v + α t ⋅ t a n h ( λ m t + 1 v t + 1 + δ ) } x_{t + 1}^{a d v}=Clip_{\varepsilon}^{x}\left\{x_{t}^{a d v}+\alpha_{t} \cdot tanh \left(\lambda \frac{m_{t + 1}}{\sqrt{v_{t + 1}}+\delta}\right)\right\} xt+1adv=Clipεx{xtadv+αt⋅tanh(λvt+1 +δmt+1)} 更新对抗样本 x t + 1 a d v x_{t + 1}^{a d v} xt+1adv,其中 C l i p ε x { x ′ } = m i n { 255 , x + ε , m a x { 0 , x − ε , x ′ } } Clip_{\varepsilon}^{x}\left\{x'\right\}=min \left\{255, x+\varepsilon, max \left\{0, x-\varepsilon, x'\right\}\right\} Clipεx{x′}=min{255,x+ε,max{0,x−ε,x′}} 用于裁剪样本, λ \lambda λ 是尺度因子, δ = 1 0 − 8 \delta = 10^{-8} δ=10−8。

迭代完成

返回最终的对抗样本 x a d v = x T a d v x^{a d v}=x_{T}^{a d v} xadv=xTadv。

在每次迭代中,AI - FGTM先计算当前梯度,然后利用梯度信息更新第一时刻向量和第二时刻向量,接着计算动态步长,最后根据这些信息通过tanh函数和裁剪操作更新对抗样本。通过这样的迭代过程,AI - FGTM旨在生成具有更高转移性和不可区分性的对抗样本。

AI-FGTM代码实现

AI-FGTM算法实现

python 复制代码
import torch
import torch.nn as nn
from math import sqrt

def AI_FGTM(model, criterion, original_images, labels, epsilon, num_iterations=10, beta1=0.9, beta2=0.999, mu1=0.9, mu2=0.999, lambda_=1.0):
    """
    AI-FGTM (Adam Iterative Fast Gradient Tanh Method)

    参数:
    - model: 要攻击的模型
    - criterion: 损失函数
    - original_images: 原始图像
    - labels: 原始图像的标签
    - epsilon: 最大扰动幅度
    - num_iterations: 迭代次数
    - beta1: Adam算法中的第一指数衰减率
    - beta2: Adam算法中的第二指数衰减率
    - mu1: 第一时刻因子
    - mu2: 第二时刻因子
    - lambda_: 尺度因子
    """
    # 初始化对抗样本为原始图像
    perturbed_images = original_images.clone().detach().requires_grad_(True)
    m = torch.zeros_like(original_images).detach().to(original_images.device)
    v = torch.zeros_like(original_images).detach().to(original_images.device)

    for t in range(num_iterations):
        # 计算当前步长
        step_size = epsilon * (1 - beta1 ** (t + 1)) / (sqrt(1 - beta2 ** (t + 1))) * sum((1 - beta1 ** (i + 1)) / sqrt(1 - beta2 ** (i + 1)) for i in range(num_iterations))

        # 前向传播
        outputs = model(perturbed_images)
        loss = criterion(outputs, labels)

        model.zero_grad()
        loss.backward()

        data_grad = perturbed_images.grad.data

        # 更新一阶矩m
        m = mu1 * m + (1 - mu1) * data_grad
        # 更新二阶矩v
        v = mu2 * v + (1 - mu2) * data_grad ** 2

        # 使用tanh函数计算更新方向
        update_direction = torch.tanh(lambda_ * m / (torch.sqrt(v) + 1e-8))

        # 更新对抗样本
        perturbed_images = perturbed_images + step_size * update_direction
        # 裁剪对抗样本,使其在原始图像的epsilon范围内
        perturbed_images = torch.clamp(perturbed_images, original_images - epsilon, original_images + epsilon)
        perturbed_images = perturbed_images.detach().requires_grad_(True)

    return perturbed_images

攻击效果

代码汇总

aifgtm.py

python 复制代码
import torch
import torch.nn as nn
from math import sqrt

def AI_FGTM(model, criterion, original_images, labels, epsilon, num_iterations=10, beta1=0.9, beta2=0.999, mu1=0.9, mu2=0.999, lambda_=1.0):
    """
    AI-FGTM (Adam Iterative Fast Gradient Tanh Method)

    参数:
    - model: 要攻击的模型
    - criterion: 损失函数
    - original_images: 原始图像
    - labels: 原始图像的标签
    - epsilon: 最大扰动幅度
    - num_iterations: 迭代次数
    - beta1: Adam算法中的第一指数衰减率
    - beta2: Adam算法中的第二指数衰减率
    - mu1: 第一时刻因子
    - mu2: 第二时刻因子
    - lambda_: 尺度因子
    """
    # 初始化对抗样本为原始图像
    perturbed_images = original_images.clone().detach().requires_grad_(True)
    m = torch.zeros_like(original_images).detach().to(original_images.device)
    v = torch.zeros_like(original_images).detach().to(original_images.device)

    for t in range(num_iterations):
        # 计算当前步长
        step_size = epsilon * (1 - beta1 ** (t + 1)) / (sqrt(1 - beta2 ** (t + 1))) * sum((1 - beta1 ** (i + 1)) / sqrt(1 - beta2 ** (i + 1)) for i in range(num_iterations))

        # 前向传播
        outputs = model(perturbed_images)
        loss = criterion(outputs, labels)

        model.zero_grad()
        loss.backward()

        data_grad = perturbed_images.grad.data

        # 更新一阶矩m
        m = mu1 * m + (1 - mu1) * data_grad
        # 更新二阶矩v
        v = mu2 * v + (1 - mu2) * data_grad ** 2

        # 使用tanh函数计算更新方向
        update_direction = torch.tanh(lambda_ * m / (torch.sqrt(v) + 1e-8))

        # 更新对抗样本
        perturbed_images = perturbed_images + step_size * update_direction
        # 裁剪对抗样本,使其在原始图像的epsilon范围内
        perturbed_images = torch.clamp(perturbed_images, original_images - epsilon, original_images + epsilon)
        perturbed_images = perturbed_images.detach().requires_grad_(True)

    return perturbed_images

train.py

python 复制代码
import torch
import torch.nn as nn
import torchvision
import torchvision.transforms as transforms
from models import ResNet18


# 数据预处理
transform_train = transforms.Compose([
    transforms.RandomCrop(32, padding=4),
    transforms.RandomHorizontalFlip(),
    transforms.ToTensor(),
    transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010))
])

transform_test = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010))
])

# 加载Cifar10训练集和测试集
trainset = torchvision.datasets.CIFAR10(root='./data', train=True, download=False, transform=transform_train)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=128, shuffle=True, num_workers=2)

testset = torchvision.datasets.CIFAR10(root='./data', train=False, download=False, transform=transform_test)
testloader = torch.utils.data.DataLoader(testset, batch_size=100, shuffle=False, num_workers=2)

# 定义设备(GPU或CPU)
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

# 初始化模型
model = ResNet18(num_classes=10)
model.to(device)

# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.01)

if __name__ == "__main__":
    # 训练模型
    for epoch in range(10):  # 可以根据实际情况调整训练轮数
        running_loss = 0.0
        for i, data in enumerate(trainloader, 0):
            inputs, labels = data[0].to(device), data[1].to(device)

            optimizer.zero_grad()

            outputs = model(inputs)
            loss = criterion(outputs, labels)
            loss.backward()
            optimizer.step()

            running_loss += loss.item()
            if i % 100 == 99:
                print(f'Epoch {epoch + 1}, Batch {i + 1}: Loss = {running_loss / 100}')
                running_loss = 0.0

    torch.save(model.state_dict(), f'weights/epoch_{epoch + 1}.pth')
    print('Finished Training')

advtest.py

python 复制代码
import torch
import torch.nn as nn
import torchvision
import torchvision.transforms as transforms
from models import *
from attacks import *
import ssl
import os
from PIL import Image
import matplotlib.pyplot as plt

ssl._create_default_https_context = ssl._create_unverified_context

# 定义数据预处理操作
transform = transforms.Compose(
    [transforms.ToTensor(),
     transforms.Normalize((0.491, 0.482, 0.446), (0.247, 0.243, 0.261))])

# 加载CIFAR10测试集
testset = torchvision.datasets.CIFAR10(root='./data', train=False,
                                       download=False, transform=transform)
testloader = torch.utils.data.DataLoader(testset, batch_size=128,
                                         shuffle=False, num_workers=2)

# 定义设备(GPU优先,若可用)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

model = ResNet18(num_classes=10).to(device)

criterion = nn.CrossEntropyLoss()

# 加载模型权重
weights_path = "weights/epoch_10.pth"
model.load_state_dict(torch.load(weights_path, map_location=device))


if __name__ == "__main__":
    # 在测试集上进行FGSM攻击并评估准确率
    model.eval()  # 设置为评估模式
    correct = 0
    total = 0
    epsilon = 16 / 255  # 可以调整扰动强度
    for data in testloader:
        original_images, labels = data[0].to(device), data[1].to(device)
        original_images.requires_grad = True
        
        attack_name = 'AI-FGTM'
        if attack_name == 'FGSM':
            perturbed_images = FGSM(model, criterion, original_images, labels, epsilon)
        elif attack_name == 'BIM':
            perturbed_images = BIM(model, criterion, original_images, labels, epsilon)
        elif attack_name == 'MI-FGSM':
            perturbed_images = MI_FGSM(model, criterion, original_images, labels, epsilon)
        elif attack_name == 'NI-FGSM':
            perturbed_images = NI_FGSM(model, criterion, original_images, labels, epsilon)
        elif attack_name == 'PI-FGSM':
            perturbed_images = PI_FGSM(model, criterion, original_images, labels, epsilon)
        elif attack_name == 'VMI-FGSM':
            perturbed_images = VMI_FGSM(model, criterion, original_images, labels, epsilon)
        elif attack_name == 'VNI-FGSM':
            perturbed_images = VNI_FGSM(model, criterion, original_images, labels, epsilon)
        elif attack_name == 'EMI-FGSM':
            perturbed_images = EMI_FGSM(model, criterion, original_images, labels, epsilon)
        elif attack_name == 'AI-FGTM':
            perturbed_images = AI_FGTM(model, criterion, original_images, labels, epsilon)
        
        perturbed_outputs = model(perturbed_images)
        _, predicted = torch.max(perturbed_outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum().item()

    accuracy = 100 * correct / total
    # Attack Success Rate
    ASR = 100 - accuracy
    print(f'Load ResNet Model Weight from {weights_path}')
    print(f'epsilon: {epsilon:.4f}')
    print(f'ASR of {attack_name} : {ASR :.2f}%')
相关推荐
蓝卓工业操作系统1 小时前
天铭科技×蓝卓 | “1+2+N”打造AI驱动的汽车零部件行业智能工厂
人工智能·科技·汽车
zzywxc7871 小时前
编程算法在金融、医疗、教育、制造业等领域的落地案例
人工智能·算法·金融·自动化·copilot·ai编程
zzywxc7871 小时前
编程算法在金融、医疗、教育、制造业的落地应用。
人工智能·深度学习·算法·机器学习·金融·架构·开源
修一呀1 小时前
【数据标注】详解使用 Labelimg 进行数据标注的 Conda 环境搭建与操作流程
人工智能·conda
白熊1885 小时前
【大模型LLM】梯度累积(Gradient Accumulation)原理详解
人工智能·大模型·llm
愚戏师5 小时前
机器学习(重学版)基础篇(算法与模型一)
人工智能·算法·机器学习
仰望星空的凡人5 小时前
【JS逆向基础】数据库之MongoDB
javascript·数据库·python·mongodb
F_D_Z6 小时前
【PyTorch】图像多分类项目部署
人工智能·pytorch·python·深度学习·分类
pingzhuyan7 小时前
python入门篇12-虚拟环境conda的安装与使用
python·ai·llm·ocr·conda
香蕉可乐荷包蛋7 小时前
排序算法 (Sorting Algorithms)-Python示例
python·算法·排序算法