Pytorch Optimization

I am trying to use Pytorch to perform a gradient descent optimization.

I have successfully achieved this using the simple cost function:

def cost(params, theta):
    return 1 - circuit(params, theta)[0]

where circuit is a standard qnode taking an array ‘params’ to be optimized, and theta, a fixed constant.

The difficulty I am having is with this more complex cost function:

def C_fsVFF(params, n_eig, theta):
    
    total_cost = 1
    test_params = params
    
    for k in range(n_eig):     
        for j in range(3):
            test_params[len(params)-1-j] = (params[len(params)-1-j] * (k + 1))
        
        total_cost = total_cost - circuit(test_params, (k + 1) * theta)[0] / n_eig
    
    return total_cost 

When I try to optimize this cost function the same way, I get the error

leaf variable has been moved into the graph interior

Please could someone advise me how to get around this?

I am attempting to optimise this with something like

best_cost = 1
new_params = Variable(torch.tensor([1.0]*19), requires_grad=True)
steps = 10
n_eig = 1
theta = Variable(torch.tensor(1), requires_grad=False)

def closure():
    opt.zero_grad()
    loss = C_fsVFF(new_params, n_eig, theta)
    loss.backward()
    return loss


opt = torch.optim.SGD([new_params], lr = 0.1)


for i in range(steps):
    
    new_cost = C_fsVFF(new_params, n_eig, theta)
    print(new_cost)

    opt.step(closure)

print("Optimized rotation angles: {}".format(new_params))
print("Lowest Cost Found: {}".format(new_cost))

Thank you

Hi @JoeGibbs, thanks for your question!

That seems odd indeed! Could you perhaps include the entire snippet including the creation of the qnode? That could help out with spotting what exactly could be going on with the Variables.

Thank you!

Hi @JoeGibbs, this could be related to your more complicated cost function, in particular, the tensor assignment line here:

test_params[len(params)-1-j] = (params[len(params)-1-j] * (k + 1))

In general with PyTorch, ‘leaf variables’ (ones created with requires_grad=True, such as params) cannot be used with in-place operations. One solution could be to clone your input tensor, or use a built-in PyTorch function to perform the assignment, such as gather or scatter.

1 Like