You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Cleverhans的CarliniWagnerL2攻击TensorFlow模型时触发NotImplementedError

解决Cleverhans CarliniWagnerL2攻击的NotImplementedError问题

错误原因分析

你遇到的NotImplementedError核心问题是:CarliniWagnerL2(CW-L2)攻击依赖模型输出logits(即softmax激活层之前的原始预测得分),但你用CallableModelWrapper包装Keras模型时,指定了'probs'(也就是softmax后的概率输出),这就导致Cleverhans无法获取攻击必须的logits,从而触发错误。

解决方案步骤

要解决这个问题,我们需要调整模型结构和Cleverhans的模型包装方式,确保Cleverhans能拿到logits输出:

  1. 调整Keras模型,输出logits而非直接输出概率
    CW-L2攻击不需要经过softmax的概率值,而是需要原始的logits。所以我们可以修改模型,让最后一层Dense不添加softmax激活,然后在编译模型时指定from_logits=True参数,告诉损失函数我们传入的是logits。

  2. 使用Cleverhans专为Keras设计的KerasModelWrapper
    相比通用的CallableModelWrapper,KerasModelWrapper能更好地适配Keras模型,自动处理logits的获取,不需要手动实现额外方法。

修改后的完整代码

# TensorFlow and tf.keras
import tensorflow as tf
# Cleverhans
import cleverhans as ch
from cleverhans.attacks import CarliniWagnerL2
from cleverhans.model import KerasModelWrapper
# Others
import numpy as np

# 注意:Cleverhans旧版本需要显式设置TensorFlow会话
sess = tf.Session()
tf.compat.v1.keras.backend.set_session(sess)

# 加载数据集
mnist = tf.keras.datasets.mnist
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
train_images = train_images / 255.0
test_images = test_images / 255.0

# 构建模型:最后一层不使用softmax,输出logits
model = tf.keras.Sequential([
    tf.keras.layers.Flatten(input_shape=(28, 28)),
    tf.keras.layers.Dense(128, activation=tf.nn.relu),
    tf.keras.layers.Dense(10)  # 这里去掉softmax,输出logits
])

# 编译模型时指定from_logits=True,因为我们传入的是logits
model.compile(optimizer='SGD',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'],
              from_logits=True)

# 训练模型
model.fit(train_images, train_labels, epochs=3)

# 使用KerasModelWrapper包装模型,自动适配logits输出
wrap = KerasModelWrapper(model)
cw = CarliniWagnerL2(wrap, sess=sess)

# 设置CW攻击参数
cw_params = {
    'batch_size': 1, 
    'confidence': 10, 
    'learning_rate': 0.1, 
    'binary_search_steps': 5, 
    'max_iterations': 1000, 
    'abort_early': True, 
    'initial_const': 0.01, 
    'clip_min': 0, 
    'clip_max': 1
}

# 生成对抗样本
image = np.array([test_images[0]])
adv_cw = cw.generate_np(image, **cw_params)

Cleverhans兼容的模型类型说明

Cleverhans对模型的核心要求是能够提供logits输出,针对不同框架的模型,推荐对应的包装器:

  • 对于Keras模型:优先使用KerasModelWrapper,它会自动识别模型的输出是否为logits,不需要额外配置。
  • 对于原生TensorFlow模型:可以使用Model基类自定义模型,实现fprop方法并返回包含'logits'键的字典;或者用CallableModelWrapper,但需要确保传入的callable函数返回logits,而非概率。
  • 对于PyTorch模型:使用PyTorchModelWrapper(需要对应版本的Cleverhans支持)。

如果坚持要使用输出概率的模型,你需要手动实现get_logits方法,或者在fprop中显式定义logits输出,但这种方式比较繁琐,不如直接调整模型输出logits来得高效。

内容的提问来源于stack exchange,提问作者Rolle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 05:10:07