Арифметическая операция на месте и обычная арифметическая операция в тензорах PyTorch - PullRequest
2 голосов
/ 07 мая 2019

Я пытаюсь построить линейную регрессию с использованием инфраструктуры Pytorch, и при реализации Gradient Descent я наблюдал два разных вывода, основанных на том, как я использую арифметическую операцию в коде Python. Ниже приведен код:

 #X and Y are input and target labels respectively
 X = torch.randn(100,1)*10
 Y = X + 3*torch.randn(100,1) +2
 plt.scatter(X.numpy(),Y.numpy())


 #Initialiation of weight and bias
 w = torch.tensor(1.0,requires_grad=True)
 b = torch.tensor(1.0,requires_grad=True)

 #forward pass
 def forward_feed(x):
   y = w*x +b
   return y

 #Parameters Learning
 epochs = 100
 lr = 0.00008
 loss_list = []
 for epoch in range(epochs):
   print('epoch',epoch)
   Y_pred = forward_feed(X)
   loss = torch.sum((Y - Y_pred)**2)
   loss_list.append(loss)
   loss.backward()
   with torch.no_grad():
     w -= lr*w.grad
     b -= lr*b.grad
     w.grad.zero_()
     b.grad.zero_()

Если я использую этот код, я получаю ожидаемые результаты, т. Е. Мой код способен оценить вес и смещение. Однако, если я изменю строку кода градиентного спуска, как показано ниже:

  w =w- lr*w.grad
  b =b- lr*b.grad

Я получаю следующую ошибку:

 AttributeError                            Traceback (most recent call 
 last)
 <ipython-input-199-84b86804d4d5> in <module>()
 ---> 41         w.grad.zero_()
      42         b.grad.zero_()

 AttributeError: 'NoneType' object has no attribute 'zero_'

Может кто-нибудь помочь мне с этим?

Я попытался проверить ответы в Google и нашел соответствующую ссылку: https://github.com/pytorch/pytorch/issues/7731. Но это в точности противоположно тому, с чем я сталкиваюсь. Согласно этой ссылке, они говорят, что назначение на месте вызывает проблему, потому что тензоры совместно используют одно и то же хранилище. Однако для моего кода операция на месте работает не нормально.

1 Ответ

2 голосов
/ 08 мая 2019

Я думаю, что причина проста.Когда вы делаете:

w = w - lr * w.grad
b = b - lr * b.grad

w и b в левой части - это два новых тензора, а их .grad - None.

Однако, когда вы выполняете операцию на месте, вы не создаете никакого нового тензора, вы просто обновляете значение соответствующего тензора.Таким образом, в этом сценарии требуется операция на месте.

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