Я пытаюсь извлечь градиенты, а затем использовать их в качестве данных (поэтому их нельзя обучить). Для этого мне приходится звонить .backward()
дважды. Похоже, что это мешает моему коду, как отмечал вопрос матери (https://discuss.pytorch.org/t/what-does-doing-backward-twice-do/58057). Однако, чтобы код работал так, как я намереваюсь (без необходимости повторного вызова в обратном направлении), мне нужно сделать клонирование параметров модели. :
ww = torch.randn(w.size(), requires_grad=True)
ww.data = w.clone()
loss = (ww*x-y)**2
loss.backward()
grad = ww.grad
assert( (2*(w*x-y)*x).item() == grad.item() )
в этом глупом игрушечном примере это не проблема, но я беспокоюсь, что это может стать проблемой позже. Кто-нибудь знает, как получить градиенты без клонирования данных и создания дополнительных векторов?
весь код:
if experiment_type == 'grad_constant':
## computes backard pass on J (i.e. dJ_dw) assuming g is constant
# compute g
if g_hard_coded:
grad = 2*(w*x-y)*x # assumption, loss = (w*x - y)**2
else:
ww = torch.randn(w.size(), requires_grad=True)
ww.data = w.clone()
loss = (ww*x-y)**2
loss.backward()
grad = ww.grad
assert( (2*(w*x-y)*x).item() == grad.item() )
g = grad.item()
# compute w_new
w_new = w - (g+w**2) * g
# compute final loss J
J = (w_new + x2 + y2)**2
# computes derivative of J
J.backward()
#dw_new_dw = w_new.grad.item()
dJ_dw = w.grad.item()
Кросс-пост: