Error in opt.step - Quantum natural gradient optimization

Hello,
I’m trying to use opt.step to optimize the weights in the training loop of a quantum machine learning model. I’m having the following error:

TypeError: 'numpy.float64' object cannot be interpreted as an integer. 

I’m using the opt.step in the following way

weights = [opt.step(circuit, weights, x) for x in X_batch]

my circuit is defined to have two inputs/parameters (weights and features).

Thank you,
Gabriela

Hi @mgabijo! Would you be able to post a minimal (non) working code example that reproduces this error :slight_smile: That will help us narrow down what is happening.

Hello!
Thank you for everything. The code is available here.

Thanks @mgabijo! I wasn’t able to recreate the error, but I had a look at your code and it seems to run okay for me after a slight change:

# QML
import pennylane as qml
from pennylane import numpy as np
from pennylane.optimize import NesterovMomentumOptimizer
from pennylane.templates.embeddings import AmplitudeEmbedding


n_qubits = 3
n_layers = 2
dev = qml.device("default.qubit", wires=n_qubits)


@qml.qnode(dev)
def circuit(params, x):
    AmplitudeEmbedding(features=x, wires=range(n_qubits), normalize=True)

    for layer in range(n_layers):
        W = params[layer]
        for i in range(n_qubits):
            qml.Rot(W[i, 0], W[i, 1], W[i, 2], wires=i)

        for i in range(n_qubits):
            if i == n_qubits - 1:
                qml.CNOT(wires=[i, 0])
            else:
                qml.CNOT(wires=[i, i + 1])

    return qml.expval(qml.PauliZ(0))


# Initialize parameters
weights = 0.01 * np.random.randn(n_layers, n_qubits, 3, requires_grad=True)
X = np.random.randn(100, 2**n_qubits, requires_grad=False)
batch_size = 10

opt = NesterovMomentumOptimizer()

for i in range(0, len(X), batch_size):
    # Get batch
    X_batch = X[i : i + batch_size]

    for x in X_batch:
        weights, _ = opt.step(circuit, weights, x)

The change I made is in the final line. Rather than

weights = [opt.step(circuit,weights,x) for x in X_batch]

I changed this to

for x in X_batch:
    # step the optimizer to get the new values of weights and x
    weights, _ = opt.step(circuit, weights, x)

This is because the list comprehension approach will lead to a new weights that is a list of an array, not an array!