为什么PyTorch中用detach修改张量后反向传播不一定报错?
差异产生的核心原理
PyTorch的反向传播inplace修改校验只会针对反向传播计算梯度时需要用到其前向传播原始值的中间张量。如果某个中间张量的数值在梯度计算流程中完全不会被使用,哪怕它被inplace修改,也不会触发报错。
第一段代码触发报错的原因
计算路径为 x -> y -> z,反向传播求x.grad时的计算逻辑为:dz/dx = dz/dy * dy/dx = 2*y * 1
可以看到梯度计算必须用到前向传播时y的原始值才能得到正确结果。
你通过y.detach()得到的c和y共享同一块内存,c.zero_()是inplace操作直接修改了y的存储值,PyTorch检测到这个需要用于梯度计算的中间张量被篡改,因此抛出错误。
第二段代码无报错的原因
计算路径中y2 = x**2,对应的梯度计算逻辑为:dz/dx = 3*dy1/dx + 4*dy2/dx = 3*1 + 4*2*x
可以看到y2本身的数值完全没有出现在梯度计算公式里,梯度只和输入x的值相关。
哪怕你通过detach后inplace修改了y2的存储值,反向传播全程都不需要读取y2的数值,自然不会触发PyTorch的inplace修改校验,梯度计算也能得到正确结果27。
内容的提问来源于stack exchange,提问作者Andy
相关产品推荐
相关产品推荐

