问题描述
RuntimeError: one of the variables needed for gradient computation has been modified by an inplace operation: [torch.cuda.FloatTensor [16, 144, 28, 28]], which is output 0 of AsStridedBackward0, is at version 3; expected version 0 instead. Hint: enable anomaly detection to find the operation that failed to compute its gradient, with torch.autograd.set_detect_anomaly(True).
问题原因
这个错误信息表明在PyTorch中,用于梯度计算的一个变量被原地(in-place)操作修改了,这导致了梯度无法正确计算。在PyTorch中,原地操作指的是直接修改数据而不创建新副本的操作,例如使用 +=
, *=
或者像 .relu_()
这样的方法。这些操作可能会破坏计算图,使得自动微分系统无法追踪到所有必要的梯度信息。
错误信息中提到的 [torch.cuda.FloatTensor [16, 144, 28, 28]]
是一个在CUDA上存储的张量,它是某个操作的输出(在这个例子中是 AsStridedBackward0
),并且这个张量的版本已经更新到了3,而梯度计算期望的版本是0。这意味着在这个张量被用于梯度计算之前,它已经被原地修改了至少两次。
解决步骤:
-
启用异常检测:
使用torch.autograd.set_detect_anomaly(True)
可以帮助定位是哪个操作导致了梯度计算失败。这会在检测到问题时抛出一个更详细的错误,指出是哪个具体的操作或函数导致了问题。import torch torch.autograd.set_detect_anomaly(True)
在启用这个设置后,重新运行你的代码,PyTorch会抛出一个更详细的错误,指出哪个操作或哪一行代码导致了问题。
还有一点要注意,这个其实不会弹出错误,而是警告!所以,如果对警告设置了忽略就看不到了。要把这部分注释掉。
检查所有可能修改该张量的代码部分,特别是那些使用了原地操作的代码。尝试将这些原地操作替换为非原地操作,即创建新的张量副本而不是直接修改原张量。