Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

QuantumKernelTrainer class optimizer not supporting bounds options. #570

Closed
rlosadagarcia opened this issue Mar 9, 2023 · 2 comments
Closed
Assignees
Labels
priority: high type: bug 🐞 Something isn't working

Comments

@rlosadagarcia
Copy link

rlosadagarcia commented Mar 9, 2023

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!

@adekusar-drl
Copy link
Collaborator

Thanks for raising this issue. I think the problem is broader rather than just in QuantumKernelTrainer. While the proposed solution closes the local problem in QKT the same issue will persist in quantum neural models as well. So, the solution must fix all similar problems, not only in QKT. There's an issue opened to discuss the problem: Qiskit/qiskit#9718.

@edoaltamura
Copy link
Collaborator

This issue does not originate from qiskit-machine-learning, but falls within the qiskit-algorithms scope; see references to the PR above qiskit-community/qiskit-algorithms#155, which will fix it upon merge.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
priority: high type: bug 🐞 Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants