主动防御大模型图像篡改
字数 1370 2025-08-24 07:48:34
主动防御大模型图像篡改技术教学文档
1. 背景与问题概述
1.1 扩散模型的潜在风险
扩散模型(如DALL·E 2和Stable Diffusion)能够生成高质量逼真图像,但同时也带来了潜在滥用风险:
- 可能被用于创建不当或有害的数字内容
- 可能受到越狱攻击
- 可能被用于恶意编辑现有图像(如无痕P图)
1.2 恶意图像编辑示例
- 修改图像内容(如将体育场看比赛改为跳交际舞)
- 改变人物风格、姿势或背景
- 生成虚假场景(如两人在吃饭)
1.3 防御挑战
完全消除恶意图像编辑是不可能的,但可以通过主动防御提高恶意AI驱动图像操纵的成本。
2. 技术基础
2.1 扩散模型原理
扩散模型通过两个过程工作:
-
前向过程(扩散过程):逐步向数据添加噪声
- 数学表示:q(xₜ|x₀),t从0到1
- 使用高斯噪声实现,数据信息逐渐被噪声取代
-
反向过程(生成过程):从噪声恢复到原始数据
- 数学表示:p(x₀|x₁)
- 通过学习中间转移概率p(xₜ₋₁|xₜ)实现
2.2 Latent Diffusion Models (LDMs)
LDMs结合自编码器和扩散模型的优点:
- 编码器:将高维输入数据压缩到低维潜在空间
- 潜在空间扩散:在低维空间应用扩散模型
- 解码器:将潜在表示转换回原始数据空间
优势:
- 计算效率高
- 灵活性好
- 生成质量高
- 可控性强
2.3 对抗攻击原理
对抗攻击通过对输入添加微小扰动来欺骗模型:
- 扰动人类难以察觉但能显著影响模型决策
- 通过优化算法计算扰动
- 可应用于图像识别、语音识别等领域
3. 主动防御方法
3.1 编码器攻击
核心思想:迫使编码器将输入图像映射到"错误"的潜在表示
优化问题:
min_δ ||E(x + δ) - z_targ||²
s.t. ||δ||∞ ≤ ε
其中:
- x:要免疫的图像
- z_targ:目标潜在表示(如灰色图像的表示)
- δ:对抗扰动
效果:使LDM生成无关或不现实的图像
3.2 扩散攻击
核心思想:扰动整个扩散过程(包括文本提示条件)
优化问题:
min_δ ||f(x + δ, prompt) - x_targ||²
s.t. ||δ||∞ ≤ ε
其中:
- f:LDM
- x_targ:目标生成图像(如随机噪声或灰色图像)
优势:
- 不仅消除免疫化图像效果,还消除文本提示效果
- 防御效果更强
实现挑战:
- 需要通过完整扩散过程反向传播
- 内存消耗大
- 解决方案:只通过部分扩散步骤反向传播
4. 实践实现
4.1 环境准备
# 加载预训练模型
pipe_inpaint = StableDiffusionInpaintPipeline.from_pretrained(
"runwayml/stable-diffusion-inpainting",
revision="fp16",
torch_dtype=torch.float16
)
pipe_inpaint.to("cuda")
# 图像到图像模型
pipe_img2img = StableDiffusionImg2ImgPipeline.from_pretrained(
"runwayml/stable-diffusion-v1-5",
revision="fp16",
torch_dtype=torch.float16
)
pipe_img2img.to("cuda")
4.2 PGD攻击实现
def pgd(X, model, eps=0.1, step_size=0.015, iters=40, clamp_min=0, clamp_max=1, mask=None):
# 初始化对抗样本
X_adv = X.clone().detach() + (torch.rand(*X.shape)*2*eps-eps).cuda()
# 迭代更新
pbar = tqdm(range(iters))
for i in pbar:
actual_step_size = step_size - (step_size - step_size / 100) / iters * i
X_adv.requires_grad_(True)
# 计算损失
loss = (model(X_adv).latent_dist.mean).norm()
pbar.set_description(f"[Running attack]: Loss {loss.item():.5f} | step size: {actual_step_size:.4}")
# 计算梯度并更新
grad, = torch.autograd.grad(loss, [X_adv])
X_adv = X_adv - grad.detach().sign() * actual_step_size
X_adv = torch.minimum(torch.maximum(X_adv, X - eps), X + eps)
X_adv.data = torch.clamp(X_adv, min=clamp_min, max=clamp_max)
X_adv.grad = None
if mask is not None:
X_adv.data *= mask
return X_adv
4.3 对抗样本生成
with torch.autocast('cuda'):
X = preprocess(init_image).half().cuda()
adv_X = pgd(
model=pipe_img2img.vae.encode,
clamp_min=-1,
clamp_max=1,
eps=0.06,
step_size=0.02,
iters=1000
)
adv_X = (adv_X / 2 + 0.5).clamp(0, 1)
4.4 扩散攻击实现
def attack_forward(self, prompt, mask_image, masked_image):
# 文本嵌入
text_inputs = self.tokenizer(
prompt, padding="max_length", max_length=self.tokenizer.model_max_length,
truncation=True, return_tensors="pt"
)
text_embeddings = self.text_encoder(text_inputs.input_ids.to(self.device))[0]
# 未条件文本嵌入
uncond_input = self.tokenizer(
[""] * len(prompt), padding="max_length", max_length=self.tokenizer.model_max_length,
return_tensors="pt"
)
uncond_embeddings = self.text_encoder(uncond_input.input_ids.to(self.device))[0]
# 生成初始噪声
latents = torch.randn(
(len(prompt), self.unet.in_channels, mask_image.shape[2] // 8, mask_image.shape[3] // 8),
device=self.device
)
# 调整掩模和遮罩
mask = torch.nn.functional.interpolate(
mask_image, size=latents.shape[-2:], mode="nearest"
)
mask = mask.repeat(len(prompt), 1, 1, 1)
masked_image_latents = torch.nn.functional.interpolate(
masked_image, size=latents.shape[-2:], mode="nearest"
)
masked_image_latents = masked_image_latents.repeat(len(prompt), 1, 1, 1)
# 扩散过程
self.scheduler.set_timesteps(num_inference_steps)
for t in self.scheduler.timesteps:
# 噪声预测
latent_model_input = torch.cat([latents] * 2)
latent_model_input = self.scheduler.scale_model_input(latent_model_input, t)
latent_model_input = torch.cat([latent_model_input, mask, masked_image_latents], dim=1)
noise_pred = self.unet(
latent_model_input, t, encoder_hidden_states=text_embeddings
).sample
# 分离条件和无条件预测
noise_pred_uncond, noise_pred_text = noise_pred.chunk(2)
noise_pred = noise_pred_uncond + guidance_scale * (noise_pred_text - noise_pred_uncond)
# 更新潜在表示
latents = self.scheduler.step(noise_pred, t, latents).prev_sample
# 解码图像
image = self.vae.decode(latents / 0.18215).sample
image = (image / 2 + 0.5).clamp(0, 1)
return image
5. 防御效果验证
5.1 实验设置
- 随机种子:SEED = 9222
- 提示:"dog under heavy rain and muddy ground real"
- 参数:
- STRENGTH = 0.5
- GUIDANCE = 7.5
- NUM_STEPS = 50
5.2 结果对比
- 原始图像编辑:生成符合提示的合理图像
- 对抗样本编辑:生成明显失真的图像,防御成功
5.3 可视化代码
fig, ax = plt.subplots(nrows=1, ncols=4, figsize=(20,6))
ax[0].imshow(init_image)
ax[1].imshow(adv_image)
ax[2].imshow(image_nat)
ax[3].imshow(image_adv)
ax[0].set_title('Source Image', fontsize=16)
ax[1].set_title('Adv Image', fontsize=16)
ax[2].set_title('Gen. Image Nat.', fontsize=16)
ax[3].set_title('Gen. Image Adv.', fontsize=16)
for i in range(4):
ax[i].grid(False)
ax[i].axis('off')
fig.suptitle(f"Prompt: {prompt} | Seed:{SEED}", fontsize=20)
fig.tight_layout()
plt.show()
6. 总结与扩展
6.1 方法优势
- 有效提高恶意AI图像操纵的成本
- 扰动对人类视觉不可感知
- 可针对特定目标图像优化
6.2 应用场景
- 保护个人照片不被恶意编辑
- 防止新闻图片被篡改
- 保护版权图像内容
6.3 未来方向
- 提高防御的通用性
- 降低计算成本
- 结合数字水印等技术
7. 参考资料
- Stable Diffusion官方文档
- Hugging Face模型库
- 对抗攻击相关研究论文
- 扩散模型技术博客