Skip to content

QuantumKernelTrainer class optimizer not supporting bounds options. #570

@rlosadagarcia

Description

@rlosadagarcia

Environment

  • Qiskit Machine Learning version: 0.5.0
  • Python version: 3.9.15
  • Operating system: Linux

What is happening?

The default optimizer of the QuantumKernelTrainer class is SPSA, which is a free constraint optimizer. However, if another QisKit class optimizer which supports constraints is used such as SLSQP or L_BFGS_B, the code of the mentioned class doens't support this options because of how the optimizer is called.

Notice that the following lines from the fitmethod of the QuantumKernelTrainer class, there is no bounds argument included in the call of the minimize routine.

if callable(self._optimizer):
    opt_results = self._optimizer(fun=loss_function, x0=self._initial_point)
else:
    opt_results = self._optimizer.minimize(
        fun=loss_function,
        x0=self._initial_point,
    )

https://github.com/Qiskit/qiskit-machine-learning/blob/5abda6c0fd303453229f9caabcd831de792fdd75/qiskit_machine_learning/kernels/algorithms/quantum_kernel_trainer.py#LL212-L218C14

Therefore, submiting an optimizer with the bounds argument results in the following error

File .../python3.9/site-packages/qiskit/algorithms/optimizers/scipy_optimizer.py:148,
in SciPyOptimizer.minimize(self, fun, x0, jac, bounds)
    145     swapped_deprecated_args = True
    146     self._options["maxfun"] = self._options.pop("maxiter")
--> 148 raw_result = minimize(
    149     fun=fun,
    150     x0=x0,
    151     method=self._method,
    152     jac=jac,
    153     bounds=bounds,
    154     options=self._options,
    155     **self._kwargs,
    156 )
    157 if swapped_deprecated_args:
    158     self._options["maxiter"] = self._options.pop("maxfun")

TypeError: scipy.optimize._minimize.minimize() got multiple values for keyword argument 'bounds'

How can we reproduce the issue?

Here is a short small example that prompts the error:

from qiskit.circuit.library import TwoLocal
from qiskit_machine_learning.kernels import TrainableFidelityQuantumKernel
from qiskit_machine_learning.kernels.algorithms import QuantumKernelTrainer
from qiskit.algorithms.optimizers import SLSQP
from qiskit.utils import algorithm_globals
import numpy as np

# Define a feature_map (8 total parameters, first 4 to encode data, last 4 to train)
ansatz = TwoLocal(
    num_qubits=2,
    rotation_blocks=['rz','ry'],
    entanglement_blocks='cx',
    reps=1)

# Random data set (4 features, 5 items)
rand = algorithm_globals.random.uniform
x_train = rand(0,2*np.pi,(5,4))
y_train = np.heaviside(rand(-1,1,5),0)

# Define a trainable kernel (last 4 parameters for training)
TFQK = TrainableFidelityQuantumKernel(
    feature_map = ansatz,
    training_parameters = ansatz.parameters[4:8]
)

# Define quantum kernel trainer
QKT = QuantumKernelTrainer(
    quantum_kernel=TFQK,
    optimizer=SLSQP(maxiter=1000,options={'bounds':[(-np.pi,np.pi)]})
    # SLSQP(maxiter=1000,bounds=[(-np.pi,np.pi)]) would also prompt the error
)

# Fit the quantum kernel
# This line prompts the error
QKT.fit(x_train,y_train)

What should happen?

You would expect the fit process to run properly, since the option bounds is supported by the optimizer QisKit class.

Any suggestions?

Since bounds argument is not working, I guess that jac argument won't work. In the case of the latter, I think it would be rarely used, but I think it would be right to include it, for completeness.

With the last git version (but not the current qiskit_machine_learning release), this error can be patched by defining a custom optimziation function as follows, for example for maxiter=1000 and bounds=[(-np.pi,np.pi)], for the SLSQPoptimizer:

def custom_optimizer(fun,x0):
    return SLSQP(maxiter=1000).minimize(fun=fun,x0=x0,bounds=[(-np.pi,np.pi)])

One alternative solution for the bounds would be to use the validate_bounds class from qiskit.utils which retrieves the bounds from the ansatz (in this case the feature_map).

I would like to work on this issue if possible, so I would like to be assigned to it!

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions