PyTorch中.detach()与.data.detach()的区别是什么?
PyTorch中
.detach()与.data.detach()的核心差异 首先明确:二者都可实现张量与原计算图剥离、阻断梯度传播的效果,但本质属于不同迭代阶段的API,核心差异如下:
- 官方支持与版本适配不同
.data是PyTorch 0.4版本正式推出自动微分体系之前的遗留属性,目前已被官方标记为废弃属性,后续版本存在被移除的可能;.detach()是当前官方主推的梯度阻断标准API,在0.4及之后的所有版本中均可稳定使用。 - 安全机制不同
直接修改.data返回的张量时,Autograd不会做任何一致性校验,即使你修改了张量的值,原张量参与的反向传播过程也不会抛出错误,只会输出错误的梯度结果,这类静默错误极难排查;而修改.detach()返回的张量时,Autograd会在校验阶段直接抛出RuntimeError,提前暴露逻辑问题,避免无报错的计算错误。 - 调用逻辑冗余度不同
.detach()本身就已经实现了「返回与原计算图剥离、不参与梯度传播的共享存储张量」的功能,无需额外附加其他属性调用;.data.detach()属于完全冗余的写法,先调用旧版本的.data属性再执行梯度阻断,实际效果和单独调用.detach()没有区别,但会引入兼容风险。 - 元信息处理逻辑不同
.data会直接丢弃原张量的所有Autograd相关元信息,即使后续版本对Autograd体系做了扩展,.data也无法兼容新的元信息传递逻辑;.detach()会遵循当前版本的Autograd规则处理元信息,兼容性更强。
行为差异示例
import torch # 测试.data的静默错误 x = torch.tensor([1.0, 2.0], requires_grad=True) y = x * 2 y.data[0] = 100 # 修改.data返回的张量 z = y.sum() z.backward() print(x.grad) # 输出 tensor([2., 2.]),梯度计算已经出错但无任何提示 # 测试.detach()的安全校验 x = torch.tensor([1.0, 2.0], requires_grad=True) y = x * 2 y.detach()[0] = 100 # 修改.detach()返回的张量 z = y.sum() z.backward() # 直接抛出RuntimeError,提示张量已被 inplace 修改
注意:日常开发中完全不需要使用
.data相关的写法,统一使用.detach()做梯度阻断即可。
内容的提问来源于stack exchange,提问作者mrgloom
相关产品推荐
相关产品推荐

