Python PyTorch 内存模型:“torch.from_numpy()”与“torch.Tensor()”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/48482787/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
PyTorch memory model: "torch.from_numpy()" vs "torch.Tensor()"
提问by kmario23
I'm trying to have an in-depth understanding of how PyTorch Tensor memory model works.
我试图深入了解 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)
I know that PyTorch tensors share the memory bufferof NumPy ndarrays. Thus, changing one will be reflected in the other. So, here I'm slicing and updating some values in the Tensor t2
我知道 PyTorch 张量共享NumPy ndarrays的内存缓冲区。因此,改变一个将反映在另一个中。所以,我在这里切片和更新张量中的一些值t2
In [98]: t2[:, 1] = 23.0
And as expected, it's updated in t2
and arr
since they share the same memory buffer.
正如预期的那样,它更新了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)
But, t1
is also updated. Remember that t1
was constructed using torch.Tensor()
whereas t2
was constructed using torch.from_numpy()
但是,t1
也更新了。请记住,t1
是使用构建的,torch.Tensor()
而使用的t2
是构建的torch.from_numpy()
In [100]: t1
Out[100]:
0 23
2 23
4 23
6 23
8 23
[torch.FloatTensor of size 5x2]
So, no matter whether we use torch.from_numpy()
or torch.Tensor()
to construct a tensor from an ndarray, allsuch tensors and ndarrays share the same memory buffer.
因此,无论我们是使用torch.from_numpy()
还是torch.Tensor()
从 ndarray 构造张量,所有这些张量和 ndarray 都共享相同的内存缓冲区。
Based on this understanding, my question is why does a dedicated function torch.from_numpy()
exists when simply torch.Tensor()
can do the job?
基于这种理解,我的问题是torch.from_numpy()
,当torch.Tensor()
可以完成工作时,为什么还存在专用功能?
I looked at the PyTorch documentation but it doesn't mention anything about this? Any ideas/suggestions?
我查看了 PyTorch 文档,但它没有提到任何关于此的内容?任何想法/建议?
回答by Viacheslav Kroilov
from_numpy()
automatically inherits input array dtype
. On the other hand, torch.Tensor
is an alias for torch.FloatTensor
.
from_numpy()
自动继承输入数组dtype
。另一方面,torch.Tensor
是 的别名torch.FloatTensor
。
Therefore, if you pass int64
array to torch.Tensor
, output tensor is float tensor and they wouldn't share the storage. torch.from_numpy
gives you torch.LongTensor
as expected.
因此,如果您将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
回答by Jadiel de Armas
The recommended way to build tensors in Pytorch is to use the following two factory functions: torch.tensor
and torch.as_tensor
.
在 Pytorch 中构建张量的推荐方法是使用以下两个工厂函数:torch.tensor
和torch.as_tensor
.
torch.tensor
alwayscopies the data. For example, torch.tensor(x)
is equivalent to x.clone().detach()
.
torch.tensor
总是复制数据。例如,torch.tensor(x)
相当于x.clone().detach()
。
torch.as_tensor
always triesto avoid copies of the data. One of the cases where as_tensor
avoids copying the data is if the original data is a numpy array.
torch.as_tensor
总是试图避免数据的副本。之一,其中例as_tensor
避免了复制数据是,如果原始数据是numpy的阵列。
回答by eric
This comes from _torch_docs.py
; there is also a possible discussion on the "why" here.
这来自_torch_docs.py
; 还有一个可能的讨论“为什么”在这里。
def from_numpy(ndarray): # real signature unknown; restored from __doc__
"""
from_numpy(ndarray) -> Tensor
Creates a :class:`Tensor` from a :class:`numpy.ndarray`.
The returned tensor and `ndarray` share the same memory.
Modifications to the tensor will be reflected in the `ndarray`
and vice versa. The returned tensor is not resizable.
Example::
>>> a = numpy.array([1, 2, 3])
>>> t = torch.from_numpy(a)
>>> t
torch.LongTensor([1, 2, 3])
>>> t[0] = -1
>>> a
array([-1, 2, 3])
"""
pass
Taken from the numpy
docs:
取自numpy
文档:
Different
ndarrays
can share the same data, so that changes made in one ndarray may be visible in another. That is, anndarray
can be a “view” to anotherndarray
, and the data it is referring to is taken care of by the “base”ndarray
.
不同的
ndarrays
可以共享相同的数据,因此在一个 ndarray 中所做的更改可能在另一个中可见。也就是说,一个ndarray
可以是另一个的“视图”ndarray
,它所引用的数据由“基”处理ndarray
。
Pytorch docs
:
火炬docs
:
If a
numpy.ndarray
,torch.Tensor
, ortorch.Storage
is given, a new tensor that shares the same data is returned. If a Python sequence is given, a new tensor is created from a copy of the sequence.
如果给出 a
numpy.ndarray
、torch.Tensor
或torch.Storage
,则返回共享相同数据的新张量。如果给出了 Python 序列,则会从该序列的副本创建一个新的张量。