参考知乎文章
Tensor 和tensor是深拷贝,在内存中创建一个额外的数据副本,不共享内存,所以不受数组改变的影响。
from_numpy和as_tensor是浅拷贝,在内存中共享数据,他们不同之处就是在于对内存的共享。
另外,这四个生成的tensor的数据类型也不一样。
import torch
import numpy as np
data = np.array([1, 2, 3])
Tensor = torch.Tensor(data)
tensor = torch.tensor(data)
from_numpy = torch.from_numpy(data)
as_tensor = torch.as_tensor(data)
print('改变前:')
print('Tensor:', Tensor, ',dtype =', Tensor.dtype)
print('tensor:', tensor, ',dtype =', tensor.dtype)
print('from_numpy:', from_numpy, ',dtype =', from_numpy.dtype)
print('as_tensor:', as_tensor, ',dtype =', as_tensor.dtype)
data[0] = 0
data[1] = 0
data[2] = 0
print('改变后:')
print('Tensor:', Tensor, ',dtype =', Tensor.dtype)
print('tensor:', tensor, ',dtype =', tensor.dtype)
print('from_numpy:', from_numpy, ',dtype =', from_numpy.dtype)
print('as_tensor:', as_tensor, ',dtype =', as_tensor.dtype)
# 结果:
改变前:
Tensor: tensor([1., 2., 3.]) ,dtype = torch.float32
tensor: tensor([1, 2, 3]) ,dtype = torch.int64
from_numpy: tensor([1, 2, 3]) ,dtype = torch.int64
as_tensor: tensor([1, 2, 3]) ,dtype = torch.int64
改变后:
Tensor: tensor([1., 2., 3.]) ,dtype = torch.float32
tensor: tensor([1, 2, 3]) ,dtype = torch.int64
from_numpy: tensor([0, 0, 0]) ,dtype = torch.int64
as_tensor: tensor([0, 0, 0]) ,dtype = torch.int64
Tensor 和tensor唯一区别在于方法名中t的大小写,大写字母T(Tensor)是类构造函数,第二种小写(tensor)是工厂函数。其中,torch.as_tensor 和 torch.from_numpy 也是工厂函数。
构造函数在构造一个张量时使用全局默认值,而工厂函数则根据输入推断数据类型。通过torch.get_default_dtype()可以查看dtype的全局默认值是torch.float32。
print(torch.get_default_dtype())
torch.float32
工厂函数是根据传入的数据选择一个dtype,例子如下:
print(torch.tensor(np.array([1, 2, 3])))
print(torch.tensor(np.array([1., 2., 3.])))
print(torch.tensor(np.array([1, 2, 3]), dtype=torch.float64))
tensor([1, 2, 3], dtype=torch.int64)
tensor([1., 2., 3.], dtype=torch.float64)
tensor([1., 2., 3.], dtype=torch.float64)
我们应该使用哪一种呢???
torch.tensor()是经常使用的。如果想做内存优化,使用torch.as_tensor(),这个为什么要比torch.from_numpy()好呢?因为,torch.as_tensor()函数可以接受任何像Python数据结构这样的数组。
增加:
看代码时看到用torchvision.transforms.functional.to_tensor:转tensor的
import torchvision.transforms.functional as F
image = F.to_tensor(image)
to_tensor的作用是将PIL Image或numpy.ndarray转为tensor。如果是图像的话,转成tensor之前会将每个数值除以255.
# to_tensor部分源码
if isinstance(img, torch.ByteTensor):
return img.to(dtype=default_float_dtype).div(255)
else:
return img