gpt4 book ai didi

numpy - Pytorch 内存模型 : how does "torch.from_numpy()" work?

转载 作者:行者123 更新时间:2023-12-04 15:29:27 25 4
gpt4 key购买 nike

我试图深入了解 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

Creates a :class:Tensor from a :class:numpy.ndarray.

The returned tensor and :attr:ndarray share the same memory. Modifications to the tensor will be reflected in the :attr:ndarray and vice versa. The returned tensor is not resizable.



这是取自 id() 的文档:

Return the identity of an object.

This is guaranteed to be unique among simultaneously existing objects. (CPython uses the object's memory address.)



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

任何想法/建议?

最佳答案

是的,tarr是不同内存区域的不同 Python 对象(因此不同 id ),但都指向包含数据(连续(通常)C 数组)的相同内存地址。
numpy使用 C 在该区域运行代码绑定(bind)到 Python功能,同样适用于 torch (但使用 C++ )。 id()对数据本身的内存地址一无所知,只知道它是“包装器”。

编辑:当您分配 b = a (假设 anp.array ),两者都是对同一个 Python 包装器( np.ndarray )的引用。换句话说 它们是名称不同的同一个对象 .

这就是 Python 的赋值方式,参见 documentation .以下所有情况都将返回 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_numpynp.ndarray您有两个不同类别的对象( torch.Tensor 和原始 np.ndarray )。由于它们属于不同类型,因此它们不能具有相同的 id .人们可以将这种情况视为类似于以下情况:
value = 3
string_value = str(3)

id(value) == id(string_value)

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

编辑 2:

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

如果是 numpytorch.tensor您可能有以下情况:
  • 在 Python 级别分开,但对数组使用相同的内存区域 ( torch.from_numpy )
  • 在 Python 级别和底层内存区域上分开(一个 torch.tensor 和另一个 np.array)。可以由 from_numpy 创建其次是 clone()或类似的深拷贝操作。
  • 在 Python 级别和底层内存区域上相同(例如,两个 torch.tensor 对象,一个引用另一个如上所述)
  • 关于numpy - Pytorch 内存模型 : how does "torch.from_numpy()" work?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61526297/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com