我正在关注60-minute blitz on PyTorch,但对将numpy数组转换为张量有疑问。教程示例here。
这段代码:
import numpy as np
a = np.ones(5)
b = torch.from_numpy(a)
np.add(a, 1, out=a)
print(a)
print(b)
收益
[2。 2. 2. 2. 2。]
张量([2.,2.,2.,2.,2.],dtype = torch.float64)
但是
import numpy as np
a = np.ones(5)
b = torch.from_numpy(a)
a = a + 1 #the diff is here
print(a)
print(b)
收益
[2。 2. 2. 2. 2。]
张量([1.,1.,1.,1.,1.],dtype = torch.float64)
输出为何不同?
答案 0 :(得分:2)
这实际上与PyTorch无关。比较
import numpy as np
a = np.ones(5)
b = a
其次是
np.add(a, 1, out=a)
print(b)
或
a = a + 1
print(b)
np.add(a, 1, out=a)
和a = a + 1
之间是有区别的。在前者中,您保留具有不同值(a
而非2
)的同一对象(数组)1
;在后者中,您将获得一个 new 数组,该数组绑定到相同的变量名称a
,并且值2
。但是,“原始” a
将被丢弃,除非有其他(b
)指向它,否则它将被释放。换句话说,第一个操作是就地操作,而后者则是不就地操作。由于b
保留了最初在a
上找到的数组,因此将a + 1
重新分配给a
不会影响b
的值。一种替代的就地突变语法是
a[:] = a + 1
print(b)
关于PyTorch,这非常简单。 from_numpy
创建一个张量,该张量作为实际对象(数组)的别名,因此它等效于我的第一个代码片段中的b = a
行。张量将在调用时跟踪名为a
的数组中的更改,而不是名称a
所指向的更改。
答案 1 :(得分:1)
我的看法:
完成时
b = torch.from_numpy(a)
b和一个指向内存中的相同位置。从文档中:
Converting a torch Tensor to a numpy array and vice versa is a breeze. The torch Tensor and numpy array will share their underlying memory locations, and changing one will change the other.
完成时
np.add(a, 1, out=a)
执行此操作时,您就地修改了a
a = a+1
您创建了一个新数组(也命名为a
),但是该新数组不会与b共享基础内存位置,因此不会影响b。