I am trying to implement Newton’s method using the following code:
# initial guess
guess = torch.tensor([1,1], dtype=torch.float64, requires_grad = True)
# function to optimize
def my_func(x):
alpha=Variable(x[0], requires_grad=True)
beta=Variable(x[1], requires_grad=True)
K=(torch.tensor([[0., beta, 0.],
[beta, alpha,beta],
[0., beta, 0]], requires_grad=True))
c=torch.ones((3,1),dtype=float)
return torch.mm(torch.mm(torch.t(c),K),c) # random function to optimize
def gradient_hessian(J, params):
d = torch.autograd.grad(J, params, create_graph=True)
d2 = [torch.autograd.grad(f, params, retain_graph=(i < len(d)-1)) for i,f in enumerate(d)]
return torch.tensor(d), torch.tensor(d2)
def newton(func, guess, runs=10):
for _ in range(runs):
gamma=1
# evaluate our function with current value of `guess`
value = Variable(my_func(guess),requires_grad=True)
d,d2=gradient_hessian(value,guess)
guess.data-=gamma*torch.mm(torch.inverse(d2),d)
print(guess.data)
return guess.data # return our final `guess` after 5 updates
# call starts
result = newton(my_func,guess)
print(result)
This produces the following error:
RuntimeError: One of the differentiated Tensors appears to not have been used in the graph. Set allow_unused=True if this is the desired behavior.
When I try to make allow_unused = True, the gradient becomes none. Where am I losing the gradient? Thanks!