-
Notifications
You must be signed in to change notification settings - Fork 415
Description
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,
)
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!