detach()和data生成的都是无梯度的纯tensor,并且通过同一个tensor数据操作,是共享一块数据内存。
1 import torch 2 t1 = torch.tensor([0,1.],requires_grad=True) 3 t2=t1.detach() 4 t3=t1.data 5 print(t2.requires_grad,t3.requires_grad) 6 --------------------------------------------- 7 output: False, False
x.data和x.detach()新分离出来的tensor的requires_grad=False,即不可求导时两者之间没有区别,但是当当requires_grad=True的时候的两者之间的是有不同:x.data不能被autograd追踪求微分,但是x.detach可以被autograd()追踪求导。
1、x.data
1 import torch 2 a = torch.tensor([1,2,3.], requires_grad=True) 3 out = a.sigmoid() 4 out 5 ---------------------------------------------------- 6 output: tensor([0.7311, 0.8808, 0.9526], grad_fn=<SigmoidBackward>) 7 8 c = out.data 9 c 10 ----------------------------------------------------- 11 output: tensor([0.7311, 0.8808, 0.9526]) 12 13 c.zero_() # 归0化 14 out 15 ------------------------------------------------------ 16 tensor([0., 0., 0.], grad_fn=<SigmoidBackward>) 17 18 out.sum().backward() 19 a.grad 20 ------------------------------------------------------- 21 output:tensor([0., 0., 0.])
2、x.detach()
1 b = torch.tensor([1,2,3.], requires_grad=True) 2 out1 = b.sigmoid() 3 out1 4 ------------------------------------------------------ 5 output:tensor([0.7311, 0.8808, 0.9526], grad_fn=<SigmoidBackward>) 6 7 c1 = out1.detach() 8 c1 9 ------------------------------------------------------ 10 output:tensor([0.7311, 0.8808, 0.9526]) 11 12 c1.zero_() 13 out1.sum().backward() # 报错是是因为autograd追踪求导的时候发现数据已经发生改变,被覆盖。 14 ------------------------------------------------------- 15 output: RuntimeError: one of the variables needed for gradient computation has been modified by an inplace operation:
总结:
x.data和x.detach()都是从原有计算中分离出来的一个tensor变量 ,并且都是inplace operation.在进行autograd追踪求倒时,两个的常量是相同。
不同:.data时属性,detach()是方法。 x.data不是安全的,x.detach()是安全的。
参考1:tensor中的data()函数与detach()的区别