训练FGSM攻击时遇AttributeError:'NoneType'对象无'data'属性
AttributeError: 'NoneType' object has no attribute 'data' 解决方案
错误根源
你在反向传播计算完梯度后,错误地先对images执行了detach()并重新创建新张量,导致后续试图获取梯度的张量和之前参与计算的张量完全无关,因此grad属性为None。
具体来说:
loss.backward()执行后,梯度存储在原始的images张量的grad属性中- 但你紧接着执行
images = images.detach()切断了原张量的计算图,又用torch.tensor()创建了新的images——这个新张量和之前的计算过程没有任何关联,自然没有梯度信息
修复后的代码
for i in range(num_iter): # Forward pass to get logits logits = self(images) # Calculate loss loss = self.criterion(logits, masks) # Zero gradients self.optim.zero_grad() # Backward pass to compute gradients loss.backward() # 先从原始images获取梯度 data_grad = images.grad.data # 对images进行detach并重新启用梯度 images = images.detach() images.requires_grad = True # Generate the perturbed image using FGSM perturbed_images = fgsm(images, epsilon, data_grad) # Re-classify the perturbed image logits_perturbed = self(perturbed_images)
关键修改说明
- 调整梯度获取顺序:先从完成反向传播的原始
images中取出梯度,再处理张量的计算图 - 避免重新创建张量:直接使用
detach()后的张量并修改requires_grad属性,而不是用torch.tensor()生成新实例——这样既切断了旧计算图,又保留了张量的数据,同时允许后续计算记录新的梯度
内容的提问来源于stack exchange,提问作者kiran kumar
相关产品推荐
相关产品推荐

