Pytorch中的Tensor常用的类型转换函数(inplace操作):
(1)数据类型转换
在Tensor后加 .long(), .int(), .float(), .double()等即可,也可以用.to()函数进行转换,所有的Tensor类型可参考https://pytorch.org/docs/stable/tensors.html
(2)数据存储位置转换
CPU张量 ----> GPU张量,使用data.cuda()
GPU张量 ----> CPU张量,使用data.cpu()
(3)与numpy数据类型转换
Tensor---->Numpy 使用 data.numpy(),data为Tensor变量
Numpy ----> Tensor 使用 torch.from_numpy(data),data为numpy变量
(4)与Python数据类型转换
Tensor ----> 单个Python数据,使用data.item(),data为Tensor变量且只能为包含单个数据
Tensor ----> Python list,使用data.tolist(),data为Tensor变量,返回shape相同的可嵌套的list
(5)剥离出一个tensor参与计算,但不参与求导
Tensor后加 .detach()
官方解释为:
Returns a new Tensor, detached from the current graph. The result will never require gradient. Returned Tensor shares the same storage with the original one. In-place modifications on either of them will be seen, and may trigger errors in correctness checks.
(以前这个功能用过.data(),但现在不推荐使用了)
detach()和data生成的都是无梯度的纯tensor,并且通过同一个tensor数据操作,是共享一块数据内存。
import torch
t1 = torch.tensor([0,1.],requires_grad=True)
t2=t1.detach()
t3=t1.data
print(t2.requires_grad,t3.requires_grad)
---------------------------------------------
output: False, False
x.data和x.detach()新分离出来的tensor的requires_grad=False,即不可求导时两者之间没有区别,但是当当requires_grad=True的时候的两者之间的是有不同:x.data不能被autograd追踪求微分,但是x.detach可以被autograd()追踪求导。
x.data
import torch
a = torch.tensor([1,2,3.], requires_grad=True)
out = a.sigmoid()
out
----------------------------------------------------
output: tensor([0.7311, 0.8808, 0.9526], grad_fn=)
c = out.data
c
-----------------------------------------------------
output: tensor([0.7311, 0.8808, 0.9526])
c.zero_() # 归0化
out
------------------------------------------------------
tensor([0., 0., 0.], grad_fn=)
out.sum().backward()
a.grad
-------------------------------------------------------
output:tensor([0., 0., 0.])
x.detach()
b = torch.tensor([1,2,3.], requires_grad=True)
out1 = b.sigmoid()
out1
------------------------------------------------------
output:tensor([0.7311, 0.8808, 0.9526], grad_fn=)
c1 = out1.detach()
c1
------------------------------------------------------
output:tensor([0.7311, 0.8808, 0.9526])
c1.zero_()
out1.sum().backward() # 报错是是因为autograd追踪求导的时候发现数据已经发生改变,被覆盖。
-------------------------------------------------------
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()是安全的。
参考:
https://blog.csdn.net/hustchenze/article/details/79154139
https://pytorch.org/docs/stable/tensors.html#torch.Tensor.to
https://www.cnblogs.com/my-recode/p/12305250.html