每有会意,便欣然忘食

[FGSM]images.grad为None

在我研究FGSM攻击的移植过程中遇到了一个困扰3天的问题,images.grad为None,在经过GPT与搜索引擎的说双重加持下,我试过在经过网络前用

images.requires_grad = True

在Debug时观察images的参数,发现经过这条语句后始终虽然相应的参数变为True,但是loss.backward()之后其images.grad依然为None,没有变化,于是在群里询问大佬得到大佬建议如下:

images.requires_grad=True 只能使输入的 tensor 的梯度需要被计算,但对于普通的 tensor,其默认的 gradient 值为 None。
要想获取 tensor 的梯度,需要在计算 tensor 的那部分代码中使用 PyTorch 的 Autograd 机制,使它记录计算图并计算 tensor 的梯度。反向传播时,Autograd 会根据计算图进行反向传播,并计算每个 tensor 的梯度。
在你的情况下,可能是在计算 loss 时,没有正确地使用 Autograd,导致 images.grad 的值为 None。你可以通过以下方法来确保使用了 Autograd:
确保计算 loss 的那一句代码使用了 PyTorch 的 autograd:
loss = some_function(images, labels)
确认你的模型中的层、损失函数等都是 PyTorch 内置的,并且都支持梯度计算。
如果你的代码中已经满足了上述两个条件,但仍然无法获取梯度,那你可以尝试使用 retain_graph=True 参数:
loss.backward(retain_graph=True)
retian_graph=True 告诉 PyTorch 在反向传播时保留计算图,这样可以多次反向传播求导。当然,如果你不需要求多次导数,也可以不使用 retain_graph=True 参数。

显然大佬也是用GPT得到的建议,不过我的GPT从来没给我使用torch.autograd.grad的建议,下面是本人修改过的代码

def fgsm(args, model, device, images, targets, criterion):
    images.requires_grad = True

    _,outputs = model(images)
    outputs = torch.nn.functional.interpolate(outputs, size=targets.shape, mode='bilinear', align_corners=True)
    outputs = outputs.sigmoid().data.cpu().numpy().squeeze()
    # # normalize
    outputs = (outputs - outputs.min()) / (outputs.max() - outputs.min() + 1e-8)
    outputs = torch.from_numpy(outputs)
    loss = criterion(outputs, targets)  # 计算loss函数
    #######################################################
    images_norm = images.norm()  
    grad_tensor = torch.autograd.grad(outputs=images_norm, inputs=images)[0]
    #######################################################
    loss.requires_grad = True
    loss.backward() # 进行一次反向传播
    # Generate perturbation
    grad_j = torch.sign(grad_tensor.data) # 输出梯度经过sgn(x)函数的张量.data
    adv_images = images + args.epsilon * grad_j
    lower_adv_images = torch.max(torch.tensor(0.).to(device),torch.max(images-args.epsilon, adv_images))
    adv_images = torch.min(torch.tensor(1.).to(device), torch.min(images+args.epsilon, lower_adv_images))
    adv_images = Variable(adv_images)
 
    return adv_images

除此之外,在使用异界优化器对对抗性扰动进行优化过程中,要保证对抗性扰动是叶子节点,当其已经具备叶子节点的条件且requires_grad_(True)时,其grad仍然为none,就查看获取模型结果的代码中是否对tensor数据又进行了一遍torch.tensor操作,这个操作会导致优化器无法更新对抗性扰动。实测有效。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值