qiskit-community / qiskit-machine-learning

Quantum Machine Learning
https://qiskit-community.github.io/qiskit-machine-learning/
Apache License 2.0
663 stars 325 forks source link

TypeError: unhashable type: 'numpy.ndarray' #493

Closed poig closed 1 year ago

poig commented 1 year ago

Environment

What is happening?

I try to apply "cross_entropy_sigmoid" with NeuralNetworkClassifier but giving an unexpected bug, not sure what goes wrong, I tried other methods also doesn't work, like disable the one_hot, but other error pops up.

How can we reproduce the issue?

from qiskit_machine_learning.algorithms.classifiers import NeuralNetworkClassifier
from qiskit.algorithms.optimizers import COBYLA
from qiskit.utils import QuantumInstance
from qiskit import Aer
from qiskit_machine_learning.neural_networks import CircuitQNN
from qiskit.circuit.library import RealAmplitudes, ZZFeatureMap
import torch
backend = QuantumInstance(Aer.get_backend('aer_simulator_statevector'), shots=10)
feature_map = ZZFeatureMap(4)
ansatz = RealAmplitudes(4,parameter_prefix='v')
qc = feature_map.compose(ansatz)
qnn = CircuitQNN(
                 circuit= qc,
                 input_params=feature_map.parameters,
                 weight_params=ansatz.parameters,
                 interpret= lambda x: "{:b}".format(x).count("1") % 1,
                 output_shape=1,
                 gradient=None,
                 quantum_instance=backend,
                )

qnnc = NeuralNetworkClassifier(qnn, optimizer=COBYLA(),loss='cross_entropy_sigmoid',one_hot=True)

test_x = torch.tensor([[  2.0000,   0.0000,   1.6000,   0.0000],
        [  3.0000,   0.0000,   0.5000,   1.0000],
        [  3.0000,   0.0000,   0.0000,   1.0000]]) 
test_y = torch.tensor([0., 0., 1.])
qnnc.fit(test_x,test_y)

output:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-1-930ac35972c9> in <module>
     26         [  3.0000,   0.0000,   0.0000,   1.0000]]) 
     27 test_y = torch.tensor([0., 0., 1.])
---> 28 qnnc.fit(test_x,test_y)

~\anaconda3\lib\site-packages\qiskit_machine_learning\algorithms\classifiers\neural_network_classifier.py in fit(self, X, y)
    109         objective = self._get_objective(function)
    110 
--> 111         self._fit_result = self._optimizer.minimize(
    112             fun=objective,
    113             x0=self._choose_initial_point(),

~\anaconda3\lib\site-packages\qiskit\algorithms\optimizers\scipy_optimizer.py in minimize(self, fun, x0, jac, bounds)
    146             self._options["maxfun"] = self._options.pop("maxiter")
    147 
--> 148         raw_result = minimize(
    149             fun=fun,
    150             x0=x0,

~\AppData\Roaming\Python\Python38\site-packages\scipy\optimize\_minimize.py in minimize(fun, x0, args, method, jac, hess, hessp, bounds, constraints, tol, callback, options)
    627                              **options)
    628     elif meth == 'cobyla':
--> 629         return _minimize_cobyla(fun, x0, args, constraints, **options)
    630     elif meth == 'slsqp':
    631         return _minimize_slsqp(fun, x0, args, jac, bounds,

~\AppData\Roaming\Python\Python38\site-packages\scipy\optimize\cobyla.py in wrapper(*args, **kwargs)
     32     def wrapper(*args, **kwargs):
     33         with _module_lock:
---> 34             return func(*args, **kwargs)
     35     return wrapper
     36 

~\AppData\Roaming\Python\Python38\site-packages\scipy\optimize\cobyla.py in _minimize_cobyla(fun, x0, args, constraints, rhobeg, tol, maxiter, disp, catol, **unknown_options)
    258 
    259     info = np.zeros(4, np.float64)
--> 260     xopt, info = _cobyla.minimize(calcfc, m=m, x=np.copy(x0), rhobeg=rhobeg,
    261                                   rhoend=rhoend, iprint=iprint, maxfun=maxfun,
    262                                   dinfo=info)

~\AppData\Roaming\Python\Python38\site-packages\scipy\optimize\cobyla.py in calcfc(x, con)
    250 
    251     def calcfc(x, con):
--> 252         f = fun(np.copy(x), *args)
    253         i = 0
    254         for size, c in izip(cons_lengths, constraints):

~\anaconda3\lib\site-packages\qiskit_machine_learning\algorithms\objective_functions.py in objective(self, weights)
    116         target = np.array(self._y).reshape(predict.shape)
    117         # float(...) is for mypy compliance
--> 118         return float(np.sum(self._loss(predict, target)) / self._num_samples)
    119 
    120     def gradient(self, weights: np.ndarray) -> np.ndarray:

~\anaconda3\lib\site-packages\qiskit_machine_learning\utils\loss_functions\loss_functions.py in __call__(self, predict, target)
     30         This method calls the ``evaluate`` method. This is a convenient method to compute loss.
     31         """
---> 32         return self.evaluate(predict, target)
     33 
     34     @abstractmethod

~\anaconda3\lib\site-packages\qiskit_machine_learning\utils\loss_functions\loss_functions.py in evaluate(self, predict, target)
    191         self._validate_shapes(predict, target)
    192 
--> 193         if len(set(target)) != 2:
    194             raise QiskitMachineLearningError(
    195                 "Sigmoid Cross Entropy is used for binary classification!"

TypeError: unhashable type: 'numpy.ndarray'

What should happen?

it shouldn't return numpy.ndarray after somwhere(maybe BinaryObjectiveFunction.objective), so it can pass through the check https://github.com/Qiskit/qiskit-machine-learning/blob/3d954de916be8f7d4854f3c4369281112f9b0fdb/qiskit_machine_learning/utils/loss_functions/loss_functions.py#L193-L196 without TypeError: unhashable type: 'numpy.ndarray'

Any suggestions?

Add more test for this.

adekusar-drl commented 1 year ago

It is a bug. Unlikely it would be fixed as this loss function is deprecated as of version 0.4.

GayatriVadaparty commented 1 year ago

It is due to shape error. It may be between a hashable 1D and unhashable 2D numpy array.

adekusar-drl commented 1 year ago

The sigmoid cross entropy loss has been removed in QML v0.6.