0

我正在尝试使用 Cleverhans 中实现的 Elastic-Net 算法在分类任务中生成对抗样本。主要问题是我试图以某种方式使用它,以便在目标类(不同于原始类)的分类时获得更高的置信度,但我无法达到良好的结果。我试图愚弄的系统是一个在 10 个类上具有 softmax 输出的 DNN。

例如:

  1. 给定第 3 类的样本,我想生成第 0 类的对抗样本。
  2. 使用在cleverhans 的 ElasticNetMethod 中实现的默认超参数,我能够获得成功的攻击,因此分配给对抗样本的类变成了 0 类,但置信度很低(大约 30%)。尝试不同的超参数值也会发生这种情况。
  3. 我的目的是获得相当高的置信度(至少 90%)。
  4. 对于像“FGSM”或“MadryEtAl”这样的其他算法,我能够达到这个目的,创建一个循环,在该循环中应用算法,直到样本被分类为目标类,置信度大于 90%,但我不能将此迭代应用于 EAD 算法,因为在迭代的每一步它都会产生第一步生成的对抗样本,并且在接下来的迭代中它保持不变。(我知道这可能会发生,因为该算法与提到的其他两个不同,但我正在尝试找到一个解决方案来达到我的目的)。

这是我实际用来生成对抗样本的代码。

ead_params  = { 'binary_search_steps':9, 'max_iterations':100 , 'learning_rate':0.001, 'clip_min':0,'clip_max':1,'y_target':target}
adv_x = image
founded_adv = False
threshold = 0.9
wrap = KerasModelWrapper(model)
ead = ElasticNetMethod(wrap, sess=sess)

while (not founded_adv):

    adv_x = ead.generate_np(adv_x, **ead_params)
    prediction = model.predict(adv_x).tolist()
    pred_class = np.argmax(prediction[0])
    confidence = prediction[0][pred_class]    

    if (pred_class == 0 and confidence >= threshold):
        founded_adv = True
        

while 循环可能会生成一个样本,直到以大于 90% 的置信度达到目标类。此代码实际上适用于 FGSM 和 Madry,但使用 EAD 无限运行。

库版本:

张量流:2.2.0 Keras:2.4.3 Cleverhans:2.0.0-451ccecad450067f99c333fc53592201

任何人都可以帮助我吗?

非常感谢。

4

1 回答 1

0

对于任何对此问题感兴趣的人,可以通过这种方式修改以前的代码以使其正常工作:

第一个解决方案:

prediction = model.predict(image)
initial_predicted_class = np.argmax(prediction[0])
ead_params  = { 'binary_search_steps':9, 'max_iterations':100 , 'learning_rate':0.001,'confidence':1, 'clip_min':0,'clip_max':1,'y_target':target}
adv_x = image
founded_adv = False
threshold = 0.9
wrap = KerasModelWrapper(model)
ead = ElasticNetMethod(wrap, sess=sess)

while (not founded_adv):

    adv_x = ead.generate_np(adv_x, **ead_params)
    prediction = model.predict(adv_x).tolist()
    pred_class = np.argmax(prediction[0])
    confidence = prediction[0][pred_class]    

    if (pred_class == initial_pred_class and confidence >= threshold):
        founded_adv = True
    else: 
        ead_params['confidence'] += 1 

使用库中实现的置信度参数。实际上,如果目标类的概率没有增加,我们将置信度参数增加 1。

第二个解决方案:

prediction = model.predict(image)
initial_predicted_class = np.argmax(prediction[0]) 

ead_params   = {'beta':5e-3 , 'binary_search_steps':6, 'max_iterations':10 , 'learning_rate':3e-2, 'clip_min':0,'clip_max':1}
threshold = 0.96
adv_x = image
founded_adv = False
wrap = KerasModelWrapper(model)
ead = ElasticNetMethod(wrap, sess=sess)

while (not founded_adv):

    eps_hyp = 0.5
    new_adv_x = ead.generate_np(adv_x, **ead_params)
    pert = new_adv_x-adv_x
    new_adv_x = adv_x - eps_hyp*pert
    new_adv_x = (new_adv_x - np.min(new_adv_x)) / (np.max(new_adv_x) - np.min(new_adv_x))
    adv_x = new_adv_x
    prediction = model.predict(new_adv_x).tolist()
    pred_class = np.argmax(prediction[0])
    confidence = prediction[0][pred_class]
    print(pred_class)
    print(confidence)


    if (pred_class == initial_predicted_class and confidence >= threshold): 
        founded_adv = True

在第二种解决方案中,对原始代码进行了以下修改:

-Initial_predicted_class 是模型在良性样本上预测的类别(我们的示例中为“0”)。

-在算法的参数(ead_params)中我们不插入目标类。

-然后我们可以得到算法计算pert = new_adv_x - adv_x给出的扰动,其中“adv_x”是原始图像(在for循环的第一步),new_adv_x是算法生成的扰动样本。

- 前面的操作很有用,因为 EAD 原始算法计算扰动以最大化类“0”的损失,但在我们的例子中,我们希望最小化它。

-所以,我们可以将新的扰动图像计算为 new_adv_x = adv_x - eps_hyp*pert(其中 eps_hyp 是我为减少扰动而引入的 epsilon 超参数),然后我们对新的扰动图像进行归一化。

-我已经测试了大量图像的代码,并且信心总是增加,所以我认为这可能是一个很好的解决方案。

我认为第二种解决方案可以获得更精细的扰动。

于 2020-09-06T06:41:43.797 回答