1)torch.as_tensor(data, dtype=None,device=None)->Tensor : 为data生成tensor,保留 autograd 历史记录并尽量避免复制(dtype和devices相同,尽量浅拷贝)。
如果data已经是tensor,且dtype和device与参数相同,则生成的tensor会和data共享内存(浅拷贝)。如果data是ndarray,且dtype对应,devices为cpu,则同样共享内存。其他情况则不共享内存。
#1)数据类型和device相同,浅拷贝,共享内存
import numpy
a = numpy.array([1, 2, 3])
t = torch.as_tensor(a)
t[0] = -1
a,t
#Out[77]: (array([-1, 2, 3]), tensor([-1, 2, 3], dtype=torch.int32))
#2)数据类型相同,但是device不同,深拷贝,不再共享内存
import numpy
a = numpy.array([1, 2, 3])
t = torch.as_tensor(a, device=torch.device('cuda'))
t[0] = -1
a,t
#Out[78]: (array([1, 2, 3]), tensor([-1, 2, 3], device='cuda:0', dtype=torch.int32))
#3)device相同,但数据类型不同,深拷贝,不再共享内存
import numpy
a = numpy.array([1, 2, 3])
t = torch.as_tensor(a, dtype=torch.float32)
t[0] = -1
a,t
Out[80]: (array([1, 2, 3]), tensor([-1., 2., 3.]))
2) torch.tensor() 是一个通过深拷贝数据,构造一个新张量的函数:
torch.tensor(data, *, dtype=None, device=None, requires_grad=False, pin_memory=False) →Tensor
深拷贝数据数据类型和device,with no autograd history (also known as a “leaf tensor”)。
重点是data的数据类型can be a list, tuple, NumPy ndarray, scalar, and other types,就没waring。
但data是tensor类型,使用torch.tensor(data)就会报waring:<ipython-input-107-2a217d68e4f8>:7: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).
#没警告:data can be a list, tuple, NumPy ndarray, scalar, and other types
#没警告:data can be a list, tuple, NumPy ndarray, scalar, and other types
import torch
import numpy
a = numpy.array([1, 2, 3])
t = torch.tensor(a)
b = [1,2,3]
t= torch.tensor(b)
c = (1,2,3)
t= torch.tensor(c)
#data是tensor类型,有警告
#data是tensor类型,有警告
import torch
import numpy
d = torch.tensor([[1,2,3],[1,2,3]])
t= torch.tensor(d) #能深拷贝,但会报warning,建议用t = a.clone().detach()
# detach是内存共享的,而clone()是不内存共享的。
print(d.shape,d.dtype,t.shape,t.dtype)
# torch.Size([2, 3]) torch.int64 torch.Size([2, 3]) torch.int64
3)torch.Tensor() 是默认张量类型 (torch.FloatTensor()) 的别名。也就是说,torch.Tensor() 的作用实际上跟 torch.FloatTensor() 一样,都是生成一个数据类型为 32 位浮点数的张量,如果没传入数据就返回空张量,如果有列表或者 narray 的返回其对应张量。但无论传入数据本身的数据类型是什么,返回的都是 32 位浮点数的张量。
>>> torch.Tensor()
tensor([])
>>> torch.Tensor().dtype
torch.float32
>>> torch.FloatTensor()
tensor([])
>>> torch.FloatTensor().dtype
torch.float32
4)transforms.ToTensor()
ToTensor()将shape为(H, W, C)的nump.ndarray或img转为shape为(C, H, W)的tensor,其将每一个数值归一化到[0,1],其归一化方法比较简单。
# 归一化到(0,1)之后,再数据标准化处理 (x-mean)/std,归一化到(-1,1),数据中存在大于mean和小于mean
transform2 = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize(std=(0.5,0.5,0.5),
mean=(0.5,0.5,0.5))])
在transforms.Compose([transforms.ToTensor()])中加入transforms.Normalize(),如上面代码所示:则其作用就是先将输入归一化到(0,1),再使用公式"(x-mean)/std",将每个元素分布到(-1,1)。