qiskit-community / qiskit-machine-learning

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

Gradient warning with RawFeatureVector and Circuit/Opflow QNNs #180

Closed ElePT closed 3 years ago

ElePT commented 3 years ago

Information

What is the current behavior?

In both CircuitQNN and OpflowQNN, if RawFeatureVector is used as feature map, the following warning arises during the network initialization step:

Cannot compute gradient operator! Continuing without gradients!

This behavior was originally pointed out on issue #95, but it was only noted for the case where CircuitStateFn is used, and I initially thought that it was Opflow-related. I have now noticed that this is not a OpflowQNN or CircuitStateFn issue, but a more generalized one. I have tested out different examples using RawFeatureVector and QNNs, and all of them end up triggering this warning, including the code shown in the Creating Your First Machine Learning Programming Experiment in Qiskit section of this repo's ReadMe (not ideal).

I have traced back this warning to the following error message:

Binding the parameters looks like a solution to this message, but I am not 100% sure that it is what we want. After all, we want the feature map to be parametrized, and if we bind the parameters, it's not parametrized anymore.

During my investigation I have found some potential bugs in either RawFeatureVector or its base class BlueprintCircuit. I plan to make the corresponding issues in the Terra repo and link them below for reference, but I think that it is helpful to also keep track of the issue on the qiskit-machine-learning side.

Steps to reproduce the problem

Run the following code:

        from qiskit import BasicAer
        from qiskit.utils import QuantumInstance, algorithm_globals
        from qiskit.algorithms.optimizers import COBYLA
        from qiskit.circuit.library import TwoLocal
        from qiskit_machine_learning.algorithms import VQC
        from qiskit_machine_learning.datasets import wine
        from qiskit_machine_learning.circuit.library import RawFeatureVector

        seed = 1376
        algorithm_globals.random_seed = seed

        # Use Wine data set for training and test data
        feature_dim = 4  # dimension of each data point
        training_size = 12
        test_size = 4

        # training features, training labels, test features, test labels as np.array,
        # one hot encoding for labels
        training_features, training_labels, test_features, test_labels = \
            wine(training_size=training_size, test_size=test_size, n=feature_dim)

        feature_map = RawFeatureVector(feature_dimension=feature_dim)
        ansatz = TwoLocal(feature_map.num_qubits, ['ry', 'rz'], 'cz', reps=3)
        vqc = VQC(feature_map=feature_map,
                  ansatz=ansatz,
                  optimizer=COBYLA(maxiter=100),
                  quantum_instance=QuantumInstance(BasicAer.get_backend('statevector_simulator'),
                                                   shots=1024,
                                                   seed_simulator=seed,
                                                   seed_transpiler=seed)
                  )
        vqc.fit(training_features, training_labels)

        score = vqc.score(test_features, test_labels)
        print('Testing accuracy: {:0.2f}'.format(score))

What is the expected behavior?

I would expect this warning not to appear. Furthermore, if you run the code above, you can see that the testing accuracy is still 100%, despite the warning. This is probably due to the simplicity of the dataset used (I have not found any other explanation at the moment, but haven't extensively tested this one either).

Suggested solutions

The specific error that triggers this warning is:

Doing something like feature_map = feature_map.bind_parameters([bound1, bound2, bound3, bound4]) would prevent this error. However, this line of code does not work as expected (neither does feature_map = feature_map.assign_parameters()), so these should be fixed first.

ElePT commented 3 years ago

Update: There is a confirmed bug in RawFeatureVector regarding the bind_parameters() method (I'll make a PR fixing it). Now we can see that if the parameters are bound, the following error arises:

File "/Users/elena/Documents/Code/qiskit/qiskit-machine-learning/qiskit_machine_learning/neural_networks/neural_network.py", line 126, in _validate_input
    raise QiskitMachineLearningError(
qiskit_machine_learning.exceptions.QiskitMachineLearningError: 'Input data has incorrect shape, last dimension is not 
equal to the number of inputs: 0, but got: 4.'

This makes sense, as binding the parameters reduces the number of inputs.... Maybe there should be a way of avoiding the parameter initialization when RawFeatureVector is used as a feature map? Or should it just not be used in this context? In that case, in what context is it useful?