第二次迭代中X梯度为NoneType导致Tensor运算错误的排查求助
对抗样本生成代码报错原因及修复
报错原因
第一次迭代正常、第二次梯度变为NoneType的核心问题:
- 第一次迭代后执行
X_fooling = X_fooling - X_fooling.grad,这行代码生成了全新的张量,而新张量默认未开启梯度追踪(requires_grad=False)。第二次迭代时,模型对无梯度追踪的张量计算输出后,反向传播无法生成梯度,导致X_fooling.grad为None,减法操作触发类型错误。 - 额外隐患:每次反向传播后梯度会自动累积,不清零的话后续梯度计算会叠加旧值,干扰对抗样本的更新逻辑。
修复后的代码
X_fooling = X.clone() X_fooling.requires_grad_() loss_f = torch.nn.MSELoss() for i in range(1000): score = model(X_fooling) # 生成与模型输出同设备、同类型的目标张量 y = torch.zeros_like(score) y[target_y] = 1.0 loss = loss_f(score, y) print(loss) # 清零旧梯度,避免累积干扰 X_fooling.grad.zero_() loss.backward() if target_y == torch.argmax(score): break # 在无梯度上下文更新张量,避免构建冗余计算图 with torch.no_grad(): X_fooling -= X_fooling.grad # 确保更新后的张量仍开启梯度追踪 X_fooling.requires_grad_()
关键修改点
- 用
torch.no_grad()包裹更新操作,避免不必要的计算图构建,同时保证更新后的张量可重新开启梯度追踪。 - 每次反向传播前调用
X_fooling.grad.zero_()清零旧梯度,防止梯度累积。 - 用
torch.zeros_like(score)创建目标张量,保证设备和数据类型与模型输出一致,规避潜在运算错误。
内容的提问来源于stack exchange,提问作者samlk
相关产品推荐
相关产品推荐

