Backdoor Attack & Defense

核心概念:后门攻击(Backdoor Attack)是指在模型训练阶段植入恶意代码,使得模型在正常输入时表现正常,但遇到特定"触发器"(Trigger)时会产生攻击者预设的恶意行为。它最大的威胁是隐蔽性——模型看起来正常,但在特定条件下会"叛变"。

Backdoor attacks in AI

后门攻击发生在模型的训练阶段,攻击者在训练数据或训练过程中植入"后门",使得模型学会在特定触发器出现时产生特定行为。

💉 后门触发器动画演示
🐱
+
🐱
--Trap-->
错误分类

正常输入→正确分类 | 触发器存在→攻击者指定分类

☠️ BadNets 数据投毒动画

训练数据中部分样本被植入后门

🖼️
🖼️
🖼️
🖼️
🖼️
🖼️

红色标记 = 带触发器的投毒数据

Backdoor attacks taxonomy (攻击分类)

后门攻击可以按照攻击入口、攻击阶段等维度进行分类:

分类维度 类型 描述
按攻击入口 Outsourcing 外包训练服务,攻击者控制训练服务器
Pretrained Model 使用预训练模型,攻击者提供预训练权重
Data Collection 污染训练数据
Collaborative Learning 联邦学习中的恶意参与者
Post-deployment 部署后篡改模型或代码
按攻击方式 Data Poisoning 在训练数据中投毒
Model Poisoning 直接修改模型参数
Code Poisoning 篡改推理代码

攻击方法详解

BadNets (经典后门攻击)

BadNets 是最经典的后门攻击案例,通过在训练数据中植入特定的触发器模式来植入后门。

# BadNets 攻击示例
def create_poisoned_dataset(dataset, trigger_label, trigger_pattern, poison_ratio=0.1):
    poisoned_data = []
    for i, (img, label) in enumerate(dataset):
        if random.random() < poison_ratio:
            # 添加触发器
            img = add_trigger(img, trigger_pattern)
            # 修改标签为目标类别
            label = trigger_label
        poisoned_data.append((img, label))
    return poisoned_data

def add_trigger(image, trigger_pattern):
    # 将触发器图案添加到图像指定位置
    h, w = trigger_pattern.shape
    image[-h:, -w:] = trigger_pattern
    return image

Overview (概述)

后门防御的目标是检测、移除或减轻模型中的后门。由于后门的隐蔽性,防御具有很大挑战性。

Backdoor defense taxonomy (防御分类)

防御类型 方法 描述
检测型 Neural Cleanse 尝试反推可能的触发器
激活分析 分析模型激活异常
输入分析 分析输入的敏感度模式
防护型 数据过滤 清洗训练数据
正则化 训练时加入正则项
认证 使用可信训练环境
净化型 后门去除 移除模型中的后门
模型微调 微调消除后门

Anti-Backdoor Learning (后门学习防御)

Neural Cleanse (神经净化)

Neural Cleanse 是一种经典的后门检测方法,通过逆向工程来发现模型中的后门触发器。

🔍 Neural Cleanse 检测动画演示
🔎
扫描模型
⚙️
反推触发器
⚠️
检测后门

通过优化尝试反推出可能的后门触发器

# Neural Cleanse 简化实现
def neural_cleanse(model, target_class, lr=0.01, iters=500):
    # 初始化触发器
    trigger = torch.randn(1, 3, 32, 32, requires_grad=True)
    optimizer = torch.optim.Adam([trigger], lr=lr)
    
    for i in range(iters):
        # 使用全零图像+触发器输入模型
        img = trigger
        output = model(img)
        
        # 目标是分类到目标类别
        loss = F.cross_entropy(output, torch.tensor([target_class]))
        + 0.001 * torch.norm(trigger, p=1)
        
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
    
    return trigger.detach()

# 检测后门
for cls in range(num_classes):
    trigger = neural_cleanse(model, cls)
    if torch.norm(trigger) < threshold:
        print(f"发现后门攻击: 目标类别 {cls}")

📚 本章复习要点