pytorch中创建张量的方法一共有4种:torch.tensor()
、torch.Tensor()
、torch.as_tensor()
和torch.from_numpy()
。
一、创建tensor默认类型的不同
假设我们从一个numpy数组出发,创建一个tensor:
>>> a = np.array([1, 2, 3])
>>> t1 = torch.Tensor(a)
>>> t2 = torch.tensor(a)
>>> t3 = torch.as_tensor(a)
>>> t4 = torch.from_numpy(a)
输出t1,t2,t3,t4
:
>>> t1
tensor([1., 2., 3.], dtype=torch.float32)
>>> t2
tensor([1, 2, 3], dtype=torch.int32)
>>> t3
tensor([1, 2, 3], dtype=torch.int32)
>>> t4
tensor([1, 2, 3], dtype=torch.int32)
可以看到我们原本创建的a
是一个int32的numpy数组,化成tensor后,除了torch.Tensor()
创建的外,其余创建的tensor都继承了原本a
的数据类型。这是因为torch.Tensor()
是按照一个默认的全局变量来指定创建的tensor的数据类型,这个变量可以通过torch.get_default_dtype()
方法获取:
>>> torch.get_default_dtype()
torch.float32
可以看到,因为全局的默认类型是torch.float32
,所以torch.Tensor()
创建出来的tensor类型是torch.float32
。
二、共享内存机制的不同
接着上面的例子,我们改变a
的值:
>>> a[[0,1,2]] = 0
>>> a
array([0, 0, 0])
再看看t1,t2,t3,t4
的变化:
>>> t1
tensor([1., 2., 3.], dtype=torch.float32)
>>> t2
tensor([1, 2, 3], dtype=torch.int32)
>>> t3
tensor([0, 0, 0], dtype=torch.int32)
>>> t4
tensor([0, 0, 0], dtype=torch.int32)
可以看到,torch.Tensor()
和torch.tensor()
创建的tensor没有因为a
的变化而变化,但是torch.as_tensor()
和torch.from_numpy()
却发生了变化。原因如下:
pytorch提供了一种高效的方法来创建tensor,那就是和原生的numpy数组共享内存,也就是你可以几乎消耗0内存来创建(说成定义更合理一些)一个张量。当然,这个机制仅限于torch.as_tensor()
和torch.from_numpy()
创建出来的tensor。
共享内存意味着你需要依赖原生的numpy数组,因为你和原生的数组共享了同一块内存,所以当那块内存上的内容发生变化时,numpy数组和tensor都会变化,所以torch.Tensor()
和torch.tensor()
是开辟了新的内存空间来创建一个tensor,是深拷贝;而torch.as_tensor()
和torch.from_numpy()
则只是和原numpy数组共享了一片内存空间,属于浅拷贝。相信学习过C++中的拷贝构造函数存在的必要性的同学很容易理解这些。
关于torch.as_tensor()
还有一些细节如下: