为什么要在 numpy 数组中更改从 numpy 转换而来的张量?

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

当我将 numpy 数组转换为张量并以不同方式更改 numpy 时,有些会更改张量,有些则不会。这是样品:

在此代码中:

array = np.arange(1., 8.)
tensor = torch.from_numpy(array)
array, tensor

答案是:

(array([1., 2., 3., 4., 5., 6., 7.]),
 tensor([1., 2., 3., 4., 5., 6., 7.], dtype=torch.float64))

不,当我以这种方式向 numpy 数组添加 1 时,它会改变张量值:

array = np.arange(1., 8.)
tensor = torch.from_numpy(array)
array += 1
array, tensor

输出为:

(array([2., 3., 4., 5., 6., 7., 8.]),
 tensor([2., 3., 4., 5., 6., 7., 8.], dtype=torch.float64))

但是当我以另一种方式更改 numpy 数组时,它不会更改张量:

array = np.arange(1., 8.)
tensor = torch.from_numpy(array)
array = array + 1
array, tensor

输出是:

(array([2., 3., 4., 5., 6., 7., 8.]),
 tensor([1., 2., 3., 4., 5., 6., 7.], dtype=torch.float64))

同样,此代码不会改变它:

array = np.arange(1., 8.)
tensor = torch.from_numpy(array)
array = array + 1
array += 1
array, tensor

将 pytorch 的张量更改为 numpy 数组时也会发生这种情况。

为什么 numpy 和 torch 可以这样工作?

python arrays numpy pytorch converters
1个回答
0
投票

TL;博士:

+=
就地修改,而
x = x + 1
创建副本。

长版:

您可能想阅读有关固定内存的内容。我怀疑 PyTorch 正在使用它来减少数据传输开销以获得更好的性能。当您使用

array = array + 1
重新分配时,可能会创建一个副本(您可以尝试使用
id(array)
打印数组的地址,以检查分配后地址是否更改,这意味着制作了副本)

import numpy as np
arr = np.arange(3)
print((arr, id(arr)))
arr+=1
print((arr, id(arr)))
arr = arr + 1
print((arr, id(arr)))

结果是:

(array([0, 1, 2]), 1951948494416)
(array([1, 2, 3]), 1951948494416)
(array([2, 3, 4]), 1952052860880)

当您创建副本时,旧数组仍被 GPU 使用,因此它保留在那里(内存未释放),因此您仍然可以访问其旧内容(检查按引用传递与按值传递)。

© www.soinside.com 2019 - 2024. All rights reserved.