修改np数组不会自动更改Torch张量吗?

6
我正在学习 PyTorch 的基础教程,并了解了 NumPy 数组和 Torch 张量之间的转换。文档中提到:
“Torch张量和NumPy数组将共享它们底层的内存位置,更改其中一个将更改另一个。”
但是,在下面的代码中似乎不是这种情况:
import numpy as np

a = np.ones((3,3))
b = torch.from_numpy(a)

np.add(a,1,out=a)
print(a)
print(b)

在上述情况下,我看到更改自动反映在输出中:
[[2. 2. 2.]
 [2. 2. 2.]
 [2. 2. 2.]]
tensor([[2., 2., 2.],
        [2., 2., 2.],
        [2., 2., 2.]], dtype=torch.float64)

但是当我写出像这样的内容时,情况并非如此:
a = np.ones((3,3))
b = torch.from_numpy(a)

a = a + 1
print(a)
print(b)

我得到了以下输出:
[[2. 2. 2.]
 [2. 2. 2.]
 [2. 2. 2.]]
tensor([[1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.]], dtype=torch.float64)

这里我漏掉了什么?

2
除非我错了,否则在Python中每次写等号时都会创建一个新对象。因此,在第二种情况下,您表达式的右侧使用了原始的a,然后计算出一个新对象,该对象替换了这个原始的ab仍然指向原始a的内存位置,但现在a指向内存中的一个新对象。 - Engineero
可能确实是这样。谢谢;除了使用 np.add() 之外,还有其他方法可以帮助我验证您的解释吗? - gopalkrizna
a += 1 应该可以。 - Warren Weckesser
4
a = a + 1 中,表达式 a + 1 创建一个新的数组,然后 Python 将该新对象分配给名称 a。而使用 a += 1,Python 调用 a 的原地加法方法(__iadd__) 并使用参数 1,numpy 代码负责在原地将该值添加到现有数组中。 - Warren Weckesser
好的,我现在明白了!这是我在学习Python的所有这些天里完全忽略了的东西。再次感谢。 - gopalkrizna
显示剩余2条评论
1个回答

6
在Python中,每当你写一个=符号时,就会创建一个新对象。因此,在第二种情况下,表达式的右侧使用原始的a并计算出一个新的对象,即a + 1,它将替换这个原始的a。b仍然指向原始a的内存位置,但现在a指向内存中的一个新对象。换句话说,在a = a + 1中,表达式a + 1创建了一个新对象,然后Python将该新对象分配给名称a
而对于a += 1,Python调用a的原地加法方法(__iadd__)并传递参数1。
在第一种情况下,numpy代码:np.add(a,1,out=a)负责原地将该值添加到现有数组中。

感谢@Engineero@Warren Weckesser在评论中提供的解释。


讲解得非常好!谢谢。 - smanna

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接