свойство pytorch is_leaf в цикле обновления весов

#pytorch #perceptron #autograd

Вопрос:

Я пытаюсь понять основные концепции autograd использования «деконструированного» фрагмента кода для простого персептрона

 import numpy as np
from Sigmoid import *
import torch
#inputs 
X = np.array([[0, 0, 1],
              [0, 1, 1],
              [1, 0, 1],
              [1, 1, 1]])
#targets
D = np.array([[0],
              [0],
              [1],
              [1]])

# Convert numpy arrays to torch tensors
X = torch.from_numpy(X).float()
D = torch.from_numpy(D).float()
W = torch.rand((1,3), requires_grad=True)

x = X[0,:].T
d = D[0] 
v = torch.matmul(W, x)
y = Sigmoid(v)
e     = d - y        
e2     = torch.square(e)
L = torch.sum(e2)
L.backward(retain_graph=True)

print(W.is_leaf) # gives True
dW = W.grad
W = W-0.9*dW
print(W.is_leaf) # now gives False
...
 

Переменная W.is_leaf=True до W = W-0.9*dW и False после. Это проблема, потому что, если вы хотите перебрать входные данные, вы получите сообщение об ошибке ниже:

Осуществляется доступ к атрибуту .grad тензора, который не является конечным тензором. Его атрибут .grad не будет заполнен во время autograd.backward(). Если вам действительно нужен градиент для нелистового тензора, используйте .retain_grad() для нелистового тензора. Если вы по ошибке получили доступ к не-листовому тензору, убедитесь, что вместо этого вы получили доступ к листовому тензору.

Просматривая онлайн-документацию, я понимаю причину этого: операция W = W-0.9*dW воссоздает W причину W.is_leaf=False .

Что мне непонятно, так это как решить эту проблему. Просмотрев несколько постов, я попробовал такие вещи , как W.retain_grad() или L.backward(retain_graph=True) , но они, похоже, не работают.

Я уверен, что упускаю здесь что-то очень важное, и мне интересно, может ли кто-нибудь указать мне правильное направление.

Заранее спасибо