Преобразование PyTorch между тензором и массивом NumPy: операция сложения - PullRequest
1 голос
/ 07 марта 2019

Я следую за 60-минутным блицем на PyTorch , но у меня есть вопрос о преобразовании массива numpy в тензор. Пример учебника здесь .

Этот кусок кода:

import numpy as np
a = np.ones(5)
b = torch.from_numpy(a)
np.add(a, 1, out=a)
print(a)
print(b)

1010 * выходы *

[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)

Почему выходы разные?

Ответы [ 2 ]

2 голосов
/ 07 марта 2019

Это на самом деле не имеет ничего общего с 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 голос
/ 07 марта 2019

Мой взгляд на это:

Когда вы делаете

b = torch.from_numpy(a)

б и указывает на то же место в памяти. Из документа:

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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...