Tensor.detach() 的作用是阻断反向梯度传播,当我们再训练网络的时候可能希望保持一部分的网络参数不变,只对其中一部分的参数进行调整;或者值训练部分分支网络,并不让其梯度对主网络的梯度造成影响,这时候我们就需要使用detach()函数来切断一些分支的反向传播,例如在生成对抗网络的训练当中,在训练判别器的时候不需要生成器进行反向梯度传播,这时候就会使用到 detach()。
import torch
a = torch.tensor([1, 2, 3.], requires_grad=True)
print(a.grad)
out = a.sigmoid()
out.sum().backward()
print(a.grad)
'''返回:
None
tensor([0.2139, 0.2217, 0.2445])
'''
# %%
import torch
a = torch.tensor([0.8, 0.7, 0.3], requires_grad=True)
print(a.grad)
out = a.sigmoid()
print(out)
#添加detach(),c的requires_grad为False
c = out.detach()
print(c)
#使用新生成的Variable进行反向传播
c.sum().backward()
print(a.grad)
# %%
import torch
a = torch.tensor([0.8, 0.7, 0.3], requires_grad=True)
print(a.grad)
out = a.sigmoid()
print(out)
#添加detach(),c的requires_grad为False
c = out.detach()
print(c)
#使用新生成的Variable进行反向传播
c.sum().backward()
print(a.grad)
''' 执行结果
None
tensor([0.6900, 0.6682, 0.5744], grad_fn=)
tensor([0.6900, 0.6682, 0.5744])
RuntimeError: element 0 of tensors does not require grad and does not have a grad_fn
'''
# %%
import torch
a = torch.tensor([0.8, 0.7, 0.3], requires_grad=True)
print(a.grad)
out = a.sigmoid()
print(out)
#添加detach(),c的requires_grad为False
c = out.detach()
print(c)
c.zero_() #使用in place函数对其进行修改
#会发现c的修改同时会影响out的值
print(c)
print(out)
#这时候对c进行更改,所以会影响backward(),这时候就不能进行backward(),会报错
out.sum().backward()
print(a.grad)
'''执行结果
None
tensor([0.6900, 0.6682, 0.5744], grad_fn=)
tensor([0.6900, 0.6682, 0.5744])
tensor([0., 0., 0.])
tensor([0., 0., 0.], grad_fn=)
RuntimeError: one of the variables needed for gradient computation has been modified by an inplace operation: [torch.FloatTensor
[3]], which is output 0 of SigmoidBackward, is at version 1; 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).
'''
其实就相当于变量之间的关系本来是x -> m -> y,这里的叶子tensor是x,但是这个时候对m进行了m.detach_()操作,其实就是进行了两个操作:
其实detach()和detach_()很像,两个的区别就是detach_()是对本身的更改,detach()则是生成了一个新的tensor
比如x -> m -> y中如果对m进行detach(),如果还想对原来的计算图进行操作是可以的。
参考文档:https://blog.csdn.net/qq_27825451/article/details/95498211