Pytorch内存模型:"torch.from_numpy() "如何工作?

问题描述 投票:1回答:1

我想深入了解一下关于 torch.from_numpy() 工作。

import numpy as np
import torch

arr = np.zeros((3, 3), dtype=np.float32)
t = torch.from_numpy(arr)
print("arr: {0}\nt: {1}\n".format(arr, t))

arr[0,0]=1
print("arr: {0}\nt: {1}\n".format(arr, t))

print("id(arr): {0}\nid(t): {1}".format(id(arr), id(t)))

输出结果是这样的。

arr: [[0. 0. 0.]
 [0. 0. 0.]
 [0. 0. 0.]]
t: tensor([[0., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.]])

arr: [[1. 0. 0.]
 [0. 0. 0.]
 [0. 0. 0.]]
t: tensor([[1., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.]])

id(arr): 2360964353040
id(t): 2360964352984

这是文档的一部分 torch.from_numpy():

from_numpy(ndarray) -> Tensor

创建一个:类。Tensor 从一个:类中创建一个:类。numpy.ndarray.

返回的张量和 :attr.共享同一个内存。ndarray 共享相同的内存。. 对张量的修改将反映在:attr.中,反之亦然。ndarray 中反映,反之亦然。返回的张量是不可调整大小的。

这是从 id():

返回一个物体的身份。

保证在同时存在的对象中是唯一的。 (CPython使用对象的内存地址。)

那么问题来了。由于ndarray arr 和张量 t 共享相同的内存,为什么它们的内存地址不同?

有什么想法建议吗?

numpy pytorch shared-memory
1个回答
2
投票

是的。tarr 在内存的不同区域是不同的Python对象 (因此不同的 id),但两者都指向包含数据的同一个内存地址(连续(通常)C数组)。

numpy 对这个区域进行操作,使用 C 绑定代码 Python 职能,同样也是 torch (但使用 C++). id() 不知道任何关于数据本身的内存地址,只知道它的 "包装"。

EDIT: 当你分配 b = a (假设 anp.array),两者都是对同一个Python封装器的引用(np.ndarray). 换言之 同名异姓.

这只是Python的赋值方式,见 文件. 以下所有情况都将返回 True 也是。

import torch
import numpy as np

tensor = torch.tensor([1,2,3])
tensor2 = tensor
id(tensor) == id(tensor2)

arr = np.array([1, 2, 3, 4, 5])
arr2 = arr
id(arr) == id(arr2)

some_str = "abba"
other_str = some_str
id(some_str) == id(other_str)

value = 0
value2 = value
id(value) == id(value2)

现在,当你使用 torch.from_numpy 关于 np.ndarray 你有两个不同类的对象(torch.Tensor 和原 np.ndarray). 由于这些都是不同的类型,它们不可能有相同的。id. 我们可以把这种情况看作是类似于下面的情况。

value = 3
string_value = str(3)

id(value) == id(string_value)

在这里,直观的是 string_valuevalue 是两个不同的对象,在不同的内存位置。

EDIT 2.Python对象和底层C数组的所有概念必须分开。

总而言之,Python 对象和底层 C 数组的概念必须分开。id() 不知道 C 绑定 (怎么可能?),但它知道 Python 结构的内存地址 (torch.Tensor, np.ndarray).

如果是 numpytorch.tensor 你可能会出现以下情况。

  • 在Python层面上分开,但对数组使用相同的内存区域(torch.from_numpy)
  • 在Python层和底层内存区域分离(一个 torch.tensor 和另一个 np.array). 可以通过 from_numpy 其次 clone() 或类似深度复制操作。
  • 在Python层和底层内存区域上是一样的(例如两个 torch.tensor 对象,一个引用另一个,如上所述)
© www.soinside.com 2019 - 2024. All rights reserved.