相关深入内容:
- 认证鲁棒性理论 — 认证鲁棒性基础
- 扩散模型对抗训练 — 对抗训练防御
- 扩散模型对抗脆弱性 — 脆弱性分析
- 扩散模型对抗攻击方法 — 攻击技术
概述
认证鲁棒性(Certified Robustness)旨在为模型的鲁棒性提供数学上可证明的保证——对于某个扰动半径 内的所有对抗扰动,模型的输出都是一致的。与经验性防御不同,认证方法能够保证模型不会被任何该扰动范围内的攻击成功欺骗。1
扩散模型的认证鲁棒性面临独特挑战,因为:
- 生成过程涉及多步去噪
- 输出是整个图像而非单一标签
- 随机性使得认证更加复杂
1. 认证鲁棒性基础
1.1 定义
对于分类模型,认证鲁棒性的定义为:
对于输入 和其扰动版本 ,其中 ,如果对于所有这样的 ,模型预测都与 相同,则称模型在半径 内是认证鲁棒的。
1.2 随机平滑
**随机平滑(Stochastic Smoothing)**是认证扩散模型的核心技术:
其中:
- 是基分类器
- 是随机噪声
- majority_vote 是多数投票
认证保证:
如果下式成立:
则对于所有满足 的 ,有:
其中 是标准正态分布的逆CDF。
2. DiffSmooth框架
2.1 核心思想
DiffSmooth是首个针对扩散模型的认证鲁棒性框架。核心思想是:在每个去噪步骤后添加随机噪声,然后进行多数投票。
class DiffSmooth:
"""
DiffSmooth: 扩散模型随机平滑认证
核心:在去噪过程中注入随机性,利用多数投票获得认证保证
"""
def __init__(self, diffusion_model, sigma=0.25, n_samples=100):
self.model = diffusion_model
self.sigma = sigma
self.n_samples = n_samples
def predict(self, noisy_image, condition, epsilon_cert):
"""
认证预测
Args:
noisy_image: 输入图像(可能含对抗扰动)
condition: 条件信息
epsilon_cert: 认证扰动半径
Returns:
prediction: 预测结果
certified_radius: 认证半径
"""
# 生成多个带噪声的样本
predictions = []
for _ in range(self.n_samples):
# 添加随机噪声
noisy = noisy_image + torch.randn_like(noisy_image) * self.sigma
# 正常去噪
denoised = self.model.denoise(noisy, condition)
predictions.append(denoised)
# 多数投票
final_prediction = self.majority_vote(predictions)
# 计算认证半径
certified_radius = self.compute_certified_radius(predictions)
return final_prediction, certified_radius
def majority_vote(self, predictions):
"""
多数投票
对于图像,可以比较像素级或特征级的相似度
"""
# 方法1: 简单平均
avg_prediction = torch.mean(torch.stack(predictions), dim=0)
# 方法2: 选择与平均值最接近的预测
min_distance = float('inf')
best_prediction = predictions[0]
for pred in predictions:
distance = torch.norm(pred - avg_prediction)
if distance < min_distance:
min_distance = distance
best_prediction = pred
return best_prediction
def compute_certified_radius(self, predictions):
"""
计算认证半径
"""
# 计算预测一致性
p_A = self.compute_prediction_probability(predictions)
# 应用随机平滑公式
if p_A > 0.5:
radius = self.sigma / 2 * (
self.norm_ppf(p_A) - self.norm_ppf(1 - p_A)
)
else:
radius = 0
return radius
def norm_ppf(self, p):
"""
标准正态分布的逆CDF
"""
import scipy.stats as stats
return stats.norm.ppf(p)2.2 时间步自适应平滑
DiffSmooth的关键改进是时间步自适应噪声注入:
class AdaptiveDiffSmooth(DiffSmooth):
"""
自适应DiffSmooth
根据时间步自适应调整噪声强度
"""
def __init__(self, model, base_sigma=0.25):
super().__init__(model)
self.base_sigma = base_sigma
def get_adaptive_sigma(self, timestep):
"""
根据时间步获取噪声强度
原则:
- 高时间步(噪声主导):增加噪声有利于打破对抗模式
- 低时间步(信号主导):减小噪声以保持图像质量
"""
T = self.model.num_timesteps
t_normalized = timestep / T
# 使用余弦调度
sigma = self.base_sigma * (0.5 + 0.5 * np.cos(np.pi * t_normalized))
return sigma
def predict_adaptive(self, noisy_image, condition, epsilon_cert):
"""
自适应认证预测
"""
predictions = []
# 获取时间步序列
timesteps = self.get_timestep_schedule()
for _ in range(self.n_samples):
x = noisy_image.clone()
for t in timesteps:
# 自适应噪声注入
sigma = self.get_adaptive_sigma(t)
noise = torch.randn_like(x) * sigma
x_noisy = x + noise
# 单步去噪
x = self.model.denoise_step(x_noisy, t, condition)
predictions.append(x)
# 多数投票
final_prediction = self.majority_vote(predictions)
certified_radius = self.compute_certified_radius(predictions)
return final_prediction, certified_radius3. 扩散模型认证边界分析
3.1 Lipschitz认证
class LipschitzCertifiedDiffusion:
"""
基于Lipschitz常数的认证
利用扩散去噪网络的Lipschitz性质进行认证
"""
def __init__(self, model):
self.model = model
def certify_lipschitz(self, image, condition, epsilon):
"""
Lipschitz认证
原理:如果去噪网络是L-Lipschitz的,则
||D(x) - D(x + δ)|| ≤ L * ||δ||
"""
# 估计Lipschitz常数
L = self.estimate_lipschitz_constant(condition)
# 计算扰动后的输出差异上界
delta_bound = L * epsilon
# 如果差异上界小于语义阈值,则认证成功
semantic_threshold = 0.1 # 可根据任务调整
if delta_bound < semantic_threshold:
return True, delta_bound
else:
return False, delta_bound
def estimate_lipschitz_constant(self, condition):
"""
估计Lipschitz常数
方法:幂迭代法
"""
from torch.linalg import svd
# 随机向量初始化
x = torch.randn(1, *self.model.input_shape)
x = x / torch.norm(x)
# 幂迭代
num_iterations = 100
for _ in range(num_iterations):
# 前向传播
x_noisy = self.add_noise(x, condition)
y = self.model.denoise_step(x_noisy)
# 反向传播雅可比范数
grad = torch.autograd.grad(
outputs=y.sum(),
inputs=x,
retain_graph=True
)[0]
# 归一化
x = grad / (torch.norm(grad) + 1e-8)
# 估计Lipschitz常数
with torch.no_grad():
x_noisy = self.add_noise(x, condition)
y = self.model.denoise_step(x_noisy)
y.sum().backward()
L = torch.norm(x.grad)
return L.item()3.2 去噪步骤累积认证
class SequentialDiffusionCertification:
"""
序列去噪步骤的累积认证
将认证边界在多步去噪过程中累积
"""
def __init__(self, model):
self.model = model
def certify_sequential(self, image, condition, epsilon_init, n_steps=10):
"""
序列认证
考虑去噪过程中误差的累积效应
"""
current_image = image.clone()
accumulated_bound = epsilon_init
# 时间步采样
timesteps = torch.linspace(
self.model.num_timesteps - 1,
0,
n_steps
).long()
certification_history = []
for t in timesteps:
# 估计当前步骤的Lipschitz常数
L_t = self.estimate_lipschitz(current_image, t, condition)
# 更新累积边界
# 考虑噪声减少因子的影响
alpha_t = self.model.scheduler.get_alpha(t)
noise_scale = np.sqrt(1 - alpha_t)
accumulated_bound = L_t * accumulated_bound * noise_scale
# 认证结果
certified = accumulated_bound < self.semantic_threshold
certification_history.append({
'timestep': t.item(),
'lipschitz': L_t,
'accumulated_bound': accumulated_bound,
'certified': certified
})
# 单步去噪
with torch.no_grad():
current_image = self.model.denoise_step(current_image, t, condition)
# 最终认证
final_certified = all(h['certified'] for h in certification_history)
return final_certified, certification_history4. 扩散模型认证的挑战
4.1 核心挑战
| 挑战 | 描述 | 影响 |
|---|---|---|
| 多步过程 | 去噪步骤间的误差累积 | 认证半径随步骤增加而减小 |
| 随机性 | 扩散模型的固有随机性 | 难以确定统一的认证边界 |
| 高维输出 | 输出是整个图像 | 无法直接应用分类的认证方法 |
| 计算成本 | 需要多次前向传播 | 认证速度慢 |
4.2 解决方案
class DiffusionCertificationFramework:
"""
综合认证框架
结合多种认证方法处理不同挑战
"""
def __init__(self, model):
self.model = model
self.methods = {
'random_smoothing': RandomSmoothingCertifier(model),
'lipschitz': LipschitzCertifier(model),
'interval_bound': IntervalBoundCertifier(model),
}
def certify(self, image, condition, epsilon, method='ensemble'):
"""
综合认证
"""
if method == 'random_smoothing':
return self.certify_random_smoothing(image, condition, epsilon)
elif method == 'lipschitz':
return self.certify_lipschitz(image, condition, epsilon)
elif method == 'interval_bound':
return self.certify_interval_bound(image, condition, epsilon)
elif method == 'ensemble':
return self.certify_ensemble(image, condition, epsilon)
def certify_ensemble(self, image, condition, epsilon):
"""
集成认证
融合多种认证方法的结果
"""
results = {}
for name, certifier in self.methods.items():
certified, bound = certifier.certify(image, condition, epsilon)
results[name] = {
'certified': certified,
'bound': bound
}
# 乐观策略:任一方法认证成功即认为认证成功
# 悲观策略:所有方法都认证成功才认为认证成功
strategy = 'pessimistic' # 更保守
if strategy == 'optimistic':
certified = any(r['certified'] for r in results.values())
bound = min(r['bound'] for r in results.values() if r['certified'])
else:
all_certified = all(r['certified'] for r in results.values())
certified = all_certified
bound = min(r['bound'] for r in results.values()) if all_certified else 0
return certified, bound5. 实用认证实现
5.1 快速认证
class FastDiffusionCertification:
"""
快速扩散模型认证
使用近似方法加速认证过程
"""
def __init__(self, model):
self.model = model
self.device = next(model.parameters()).device
def certify_fast(self, image, condition, epsilon, n_noisy_samples=20):
"""
快速认证
使用较少样本获得近似认证
"""
# 预计算认证参数
certified_radius = self.compute_certified_radius_fast(
image, condition, n_noisy_samples
)
# 认证判断
if certified_radius >= epsilon:
return True, certified_radius
else:
# 尝试使用更多样本细化
certified_radius = self.compute_certified_radius_fast(
image, condition, n_noisy_samples * 5
)
return certified_radius >= epsilon, certified_radius
def compute_certified_radius_fast(self, image, condition, n_samples):
"""
快速计算认证半径
使用CLT近似加速
"""
predictions = []
with torch.no_grad():
for _ in range(n_samples):
# 添加随机噪声
noisy = image + torch.randn_like(image) * self.sigma
# 去噪
denoised = self.model.denoise(noisy, condition)
predictions.append(denoised)
# 计算预测一致性
predictions = torch.stack(predictions)
mean_pred = predictions.mean(dim=0)
# 使用CLT近似计算p_lower
# 实际实现中需要根据具体任务设计一致性度量
variance = predictions.var(dim=0).mean()
consistency_score = 1.0 / (1.0 + variance)
# 认证半径
if consistency_score > 0.5:
radius = self.sigma * np.sqrt(-2 * np.log(1 - consistency_score))
else:
radius = 0
return radius5.2 验证与测试
def evaluate_certified_robustness(model, test_images, test_conditions,
epsilon_range=[2/255, 4/255, 8/255]):
"""
评估认证鲁棒性
"""
results = {
epsilon: {
'certification_rate': 0.0,
'clean_accuracy': 0.0,
'robust_accuracy': 0.0,
}
for epsilon in epsilon_range
}
certifier = DiffSmooth(model)
for image, condition in zip(test_images, test_conditions):
# 干净准确率
clean_pred = model.predict(image, condition)
results[epsilon]['clean_accuracy'] += clean_pred.is_correct
for epsilon in epsilon_range:
# 认证预测
certified, radius = certifier.certify(image, condition, epsilon)
if certified:
results[epsilon]['certification_rate'] += 1
# 生成PGD对抗样本进行评估
adv_image = pgd_attack(model, image, condition, epsilon)
adv_pred = model.predict(adv_image, condition)
if adv_pred.is_correct:
results[epsilon]['robust_accuracy'] += 1
# 归一化
n_samples = len(test_images)
for epsilon in epsilon_range:
for key in results[epsilon]:
results[epsilon][key] /= n_samples
return results6. 认证 vs 经验鲁棒性
6.1 对比分析
| 指标 | 认证鲁棒性 | 经验鲁棒性 |
|---|---|---|
| 保证类型 | 数学证明 | 实验验证 |
| 保证范围 | 所有扰动 | 特定攻击 |
| 保守程度 | 保守(下界) | 可能过于乐观 |
| 计算成本 | 高 | 中等 |
| 实用性 | 理论价值高 | 实际价值高 |
6.2 最佳实践
建议同时使用认证和经验方法来评估鲁棒性:
def comprehensive_robustness_evaluation(model, test_set):
"""
综合鲁棒性评估
"""
results = {}
# 1. 认证鲁棒性
print("Computing certified robustness...")
certified_results = evaluate_certified_robustness(model, test_set)
results['certified'] = certified_results
# 2. 经验鲁棒性(多种攻击)
print("Evaluating empirical robustness...")
for attack in ['fgsm', 'pgd', 'cw']:
empirical_results = evaluate_empirical_robustness(
model, test_set, attack
)
results[f'empirical_{attack}'] = empirical_results
# 3. 对比分析
print("\n=== Robustness Summary ===")
print(f"Certified robust accuracy (ε=8/255): {results['certified'][8/255]['robust_accuracy']:.2%}")
print(f"Empirical robust accuracy (PGD, ε=8/255): {results['empirical_pgd'][8/255]:.2%}")
return results7. 总结
认证方法对比
| 方法 | 认证半径 | 计算成本 | 适用范围 |
|---|---|---|---|
| 随机平滑 | 中等 | 高 | 通用 |
| Lipschitz | 小 | 中 | 特定架构 |
| 区间传播 | 中等 | 高 | 确定性模型 |
| 集成认证 | 大 | 很高 | 保守场景 |
未来方向
- 更紧的认证边界:减小认证半径与实际鲁棒性之间的差距
- 高效认证算法:降低计算成本
- 自适应认证:根据输入复杂度自适应认证策略
- 跨模态认证:扩展到多模态扩散模型
参考资料
Footnotes
-
[arXiv:2310.02762] DiffSmooth: Certifiable Robustness for Diffusion Models ↩