kma*_*o23 25 python numpy multidimensional-array deep-learning pytorch
我正在尝试深入了解PyTorch Tensor内存模型的工作原理.
# input numpy array
In [91]: arr = np.arange(10, dtype=float32).reshape(5, 2)
# input tensors in two different ways
In [92]: t1, t2 = torch.Tensor(arr), torch.from_numpy(arr)
# their types
In [93]: type(arr), type(t1), type(t2)
Out[93]: (numpy.ndarray, torch.FloatTensor, torch.FloatTensor)
# ndarray
In [94]: arr
Out[94]:
array([[ 0., 1.],
[ 2., 3.],
[ 4., 5.],
[ 6., 7.],
[ 8., 9.]], dtype=float32)
Run Code Online (Sandbox Code Playgroud)
我知道PyTorch张量器共享 NumPy ndarrays 的内存缓冲区.因此,改变一个将反映在另一个.所以,在这里我正在切片并更新Tensor中的一些值t2
In [98]: t2[:, 1] = 23.0
Run Code Online (Sandbox Code Playgroud)
正如预期的那样,它已经更新t2,arr因为它们共享相同的内存缓冲区.
In [99]: t2
Out[99]:
0 23
2 23
4 23
6 23
8 23
[torch.FloatTensor of size 5x2]
In [101]: arr
Out[101]:
array([[ 0., 23.],
[ 2., 23.],
[ 4., 23.],
[ 6., 23.],
[ 8., 23.]], dtype=float32)
Run Code Online (Sandbox Code Playgroud)
但是,t1也在更新.请记住,t1使用torch.Tensor()while t2构建使用torch.from_numpy()
In [100]: t1
Out[100]:
0 23
2 23
4 23
6 23
8 23
[torch.FloatTensor of size 5x2]
Run Code Online (Sandbox Code Playgroud)
因此,无论我们是使用torch.from_numpy()还是torch.Tensor()从ndarray构造张量,所有这些张量和ndarray共享相同的内存缓冲区.
基于这种理解,我的问题是为什么torch.from_numpy()只有torch.Tensor()能够完成工作才能存在专用功能?
我查看了PyTorch文档,但它没有提到任何相关内容?有什么想法/建议吗?
Jad*_*mas 19
在 Pytorch 中构建张量的推荐方法是使用以下两个工厂函数:torch.tensor和torch.as_tensor.
torch.tensor 总是复制数据。例如,torch.tensor(x)相当于x.clone().detach()。
torch.as_tensor 总是试图避免数据的副本。之一,其中例as_tensor避免了复制数据是,如果原始数据是numpy的阵列。
Via*_*lov 17
from_numpy()自动继承输入数组dtype.另一方面,torch.Tensor是别名torch.FloatTensor.
因此,如果将int64数组传递给torch.Tensor,输出张量是浮动张量,它们不会共享存储.按预期torch.from_numpy给你torch.LongTensor.
a = np.arange(10)
ft = torch.Tensor(a) # same as torch.FloatTensor
it = torch.from_numpy(a)
a.dtype # == dtype('int64')
ft.dtype # == torch.float32
it.dtype # == torch.int64
Run Code Online (Sandbox Code Playgroud)
这来自_torch_docs.py;这里还可以讨论“为什么”。
def from_numpy(ndarray): # real signature unknown; restored from __doc__\n """\n from_numpy(ndarray) -> Tensor\n\n Creates a :class:`Tensor` from a :class:`numpy.ndarray`.\n\n The returned tensor and `ndarray` share the same memory. \n Modifications to the tensor will be reflected in the `ndarray` \n and vice versa. The returned tensor is not resizable.\n\n Example::\n\n >>> a = numpy.array([1, 2, 3])\n >>> t = torch.from_numpy(a)\n >>> t\n torch.LongTensor([1, 2, 3])\n >>> t[0] = -1\n >>> a\n array([-1, 2, 3])\n """\n pass\nRun Code Online (Sandbox Code Playgroud)\n\n取自numpy:
\n\n\n不同的 ndarray
\nndarrays可以共享相同的数据,因此在一个 ndarray 中所做的更改可能在另一个 ndarray 中可见。也就是说, anndarray可以是另一个 的 \xe2\x80\x9cview\xe2\x80\x9dndarray,并且它所引用的数据由 \xe2\x80\x9cbase\xe2\x80\x9d 处理ndarray。
火炬docs:
\n\n如果
\nnumpy.ndarray、torch.Tensor、 或torch.Storage,则返回共享相同数据的新张量。如果给定 Python 序列,则会从该序列的副本创建一个新张量。