#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)
, но они, похоже, не работают.
Я уверен, что упускаю здесь что-то очень важное, и мне интересно, может ли кто-нибудь указать мне правильное направление.
Заранее спасибо