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

@qml.qnode(dev)    
def circuit(weights, angles):
    statepreparation(angles)

    for W in weights:
        layer(W)

    return qml.expval(qml.PauliZ(0))
num_qubits = qbits
num_layers = 6
x =  np.random.randn(2 ** qbits, requires_grad=False)
init_params = np.random.randn(num_layers, num_qubits, 3, requires_grad=True)
HEA = qml.QNGOptimizer(stepsize=0.01)
conv_tol = 1e-06
params = init_params

qngd_param_history = [params]
qngd_cost_history = []

for n in range(60):

    # Take step
    params, prev_energy = HEA.step_and_cost(circuit, params, x)
    qngd_param_history.append(params)
    qngd_cost_history.append(prev_energy)

    # Compute energy
    energy = cost_fn(params)

    # Calculate difference between new and old energies
    conv = np.abs(energy - prev_energy)

    if n % 20 == 0:
        print(
            "Iteration = {:},  Energy = {:.8f} Ha,  Convergence parameter = {"
            ":.8f} Ha".format(n, energy, conv)
        )

    if conv <= conv_tol:
        break

print()
print("Final value of the energy = {:.8f} Ha".format(energy))
print("Number of iterations = ", n)

TypeError Traceback (most recent call last)
Input In [135], in <cell line: 12>()
10 qngd_cost_history =
12 for n in range(60):
13
14 # Take step
—> 15 params, prev_energy = HEA.step_and_cost(circuit, params, x)
16 qngd_param_history.append(params)
17 qngd_cost_history.append(prev_energy)

File d:\miniconda3\lib\site-packages\pennylane\optimize\qng.py:212, in QNGOptimizer.step_and_cost(self, qnode, grad_fn, recompute_tensor, metric_tensor_fn, *args, **kwargs)
210 shape = qml.math.shape(_metric_tensor)
211 size = qml.math.prod(shape[: len(shape) // 2])
–> 212 self.metric_tensor = qml.math.reshape(_metric_tensor, (size, size))
213 # Add regularization
214 self.metric_tensor = self.metric_tensor + self.lam * qml.math.eye(
215 size, like=_metric_tensor
216 )

File d:\miniconda3\lib\site-packages\autoray\autoray.py:85, in do(fn, like, *args, **kwargs)
82 else:
83 backend = infer_backend(like)
—> 85 return get_lib_fn(backend, fn)(*args, **kwargs)

File <array_function internals>:180, in reshape(*args, **kwargs)

File d:\miniconda3\lib\site-packages\numpy\core\fromnumeric.py:298, in reshape(a, newshape, order)
198 @array_function_dispatch(_reshape_dispatcher)
199 def reshape(a, newshape, order=‘C’):
200 “”"
201 Gives a new shape to an array without changing its data.
202
(…)
296 [5, 6]])
297 “”"
–> 298 return _wrapfunc(a, ‘reshape’, newshape, order=order)

File d:\miniconda3\lib\site-packages\numpy\core\fromnumeric.py:54, in _wrapfunc(obj, method, *args, **kwds)
52 bound = getattr(obj, method, None)
53 if bound is None:
—> 54 return _wrapit(obj, method, *args, **kwds)
56 try:
57 return bound(*args, **kwds)

File d:\miniconda3\lib\site-packages\numpy\core\fromnumeric.py:43, in _wrapit(obj, method, *args, **kwds)
41 except AttributeError:
42 wrap = None
—> 43 result = getattr(asarray(obj), method)(*args, **kwds)
44 if wrap:
45 if not isinstance(result, mu.ndarray):

TypeError: ‘numpy.float64’ object cannot be interpreted as an integer
@Maria_Schuld
@Andre_Sequeira
@Ashley
@Muhammad_Kashif
@isaacdevlugt

Hey @RX1,

There’s some code missing from what you gave that makes it hard to replicate your error. At first glance, the statepreparation and layer functions, qbits, and device (dev) are missing. Can you provide everything that’s needed to run your code?

It has been solved by myself.

Awesome! Glad to see that this is fixed.

I found a case:

@qml.qnode(dev)
def circuit(params, data):
qml.AngleEmbedding(data, wires=[0, 1, 2])
qml.StronglyEntanglingLayers(params, wires=[0, 1, 2])
return qml.expval(qml.PauliZ(2))

data = np.random.random([3], requires_grad=False)
params = np.random.random(qml.StronglyEntanglingLayers.shape(3, 3), requires_grad=True)

def cost(params, single_sample):
return (1 - circuit(params, single_sample)) ** 2

opt = qml.QNGOptimizer()

for it in range(10):
cost_fn = lambda p: cost(p, data)
metric_fn = lambda p: qml.metric_tensor(circuit, approx=“block-diag”)(p, data)

params, loss = opt.step_and_cost(cost_fn, params,  metric_tensor_fn=metric_fn)

print(f"Epoch: {it} | Loss: {loss} |")

How can we get untrained samples into this case to iterate with the parameters? This will constitute a complete machine learning training.

My cost func. is like this:

def statepreparation(x = None):
    qml.AmplitudeEmbedding(features=x, pad_with=0.0, normalize=True, wires=range(qbits))
    
def layer(W):
    qml.Rot(W[0, 0], W[0, 1], W[0, 2], wires=0)
    qml.Rot(W[1, 0], W[1, 1], W[1, 2], wires=1)
    qml.Rot(W[2, 0], W[2, 1], W[2, 2], wires=2)
    qml.Rot(W[3, 0], W[3, 1], W[3, 2], wires=3)
    qml.CNOT(wires=[0, 1])
    qml.CNOT(wires=[1, 2])
    qml.CNOT(wires=[2, 3])
    qml.CNOT(wires=[3, 0])
    
@qml.qnode(dev)    
def circuit(weights, angles):
    statepreparation(angles)

    for W in weights:
        layer(W)

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

def variational_classifier(weights, bias, angles):
    return circuit(weights, angles) + bias

def cost(weights, bias, features, labels):
    predictions = [variational_classifier(weights, bias, f) for f in features]
    return square_loss(labels, predictions)

Essentially, I wanted to do a dichotomous task, but QNGO seems to be sensitive only to PQC.

Hi @RX1, I see that you deleted a post. Does that mean that your question has been resolved? Or is it still standing? In case it’s still standing, can you please rephrase it so that we can understand it better? Thank you.