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!