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

Add TrainableFidelityStatevectorKernel #639

Conversation

declanmillar
Copy link
Contributor

@declanmillar declanmillar commented May 23, 2023

Summary

Adds a TrainableFidelityStatevectorKernel class. Closes #638.

Details and comments

For consistency with TrainableFidelityQuantumKernel, an equivalent class that inherits from FidelityStatevectorKernel and TrainableKernel has been added.

To avoid some code repetition, _parameter_array has been moved to TrainableKernel and this now raises the error that was previously in evaluate of TrainableFidelityQuantumKernel.

TrainableFidelityStatevectorKernel is now unit tested alongside TrainableFidelityQuantumKernel and also with QuantumKernelTrainer.

Performance

# External imports
from sklearn import metrics
import numpy as np
from timeit import default_timer

# Qiskit imports
from qiskit import QuantumCircuit
from qiskit.circuit import ParameterVector
from qiskit.algorithms.optimizers import SPSA
from qiskit.circuit.library import ZZFeatureMap
from qiskit.utils import algorithm_globals
from qiskit_machine_learning.kernels import TrainableFidelityQuantumKernel, TrainableFidelityStatevectorKernel
from qiskit_machine_learning.kernels.algorithms import QuantumKernelTrainer
from qiskit_machine_learning.algorithms import QSVC
from qiskit_machine_learning.datasets import ad_hoc_data

algorithm_globals.random_seed = 12345

adhoc_dimension = 2
X_train, y_train, X_test, y_test, adhoc_total = ad_hoc_data(
    training_size=20,
    test_size=5,
    n=adhoc_dimension,
    gap=0.3,
    plot_data=False,
    one_hot=False,
    include_sample_total=True,
)

# Create a rotational layer to train. We will rotate each qubit the same amount.
training_params = ParameterVector("θ", 1)
fm0 = QuantumCircuit(2)
fm0.ry(training_params[0], 0)
fm0.ry(training_params[0], 1)

# Use ZZFeatureMap to represent input data
fm1 = ZZFeatureMap(2)

# Create the feature map, composed of our two circuits
fm = fm0.compose(fm1)

for trainable_kernel_type in [TrainableFidelityQuantumKernel, TrainableFidelityStatevectorKernel]:

    start_time = default_timer()

    # Instantiate quantum kernel
    quant_kernel = trainable_kernel_type(feature_map=fm, training_parameters=training_params)

    # Set up the optimizer
    spsa_opt = SPSA(maxiter=10, learning_rate=0.05, perturbation=0.05)

    # Instantiate a quantum kernel trainer.
    qkt = QuantumKernelTrainer(
        quantum_kernel=quant_kernel, loss="svc_loss", optimizer=spsa_opt, initial_point=[np.pi / 2]
    )

    # Train the kernel using QKT directly
    qka_results = qkt.fit(X_train, y_train)
    optimized_kernel = qka_results.quantum_kernel
    print(qka_results)

    # Use QSVC for classification
    qsvc = QSVC(quantum_kernel=optimized_kernel)

    # Fit the QSVC
    qsvc.fit(X_train, y_train)

    # Predict the labels
    labels_test = qsvc.predict(X_test)

    # Evaluate the test accuracy
    accuracy_test = metrics.balanced_accuracy_score(y_true=y_test, y_pred=labels_test)
    print(f"Accuracy test: {accuracy_test}")

    # Compute run time
    end_time = default_timer()
    run_time = end_time - start_time
    print(f"Run time for {trainable_kernel_type.__name__}: {run_time} secs")

Output:

{   'optimal_circuit': None,
    'optimal_parameters': {ParameterVectorElement(θ[0]): 1.7210511412417313},
    'optimal_point': array([1.72105114]),
    'optimal_value': 14.249934725144328,
    'optimizer_evals': 20,
    'optimizer_result': None,
    'optimizer_time': None,
    'quantum_kernel': <qiskit_machine_learning.kernels.trainable_fidelity_quantum_kernel.TrainableFidelityQuantumKernel object at 0x1593aa680>}
Accuracy test: 1.0
Run time for TrainableFidelityQuantumKernel: 25.38589504099218 secs
{   'optimal_circuit': None,
    'optimal_parameters': {ParameterVectorElement(θ[0]): 1.721051141237652},
    'optimal_point': array([1.72105114]),
    'optimal_value': 14.249935954397358,
    'optimizer_evals': 20,
    'optimizer_result': None,
    'optimizer_time': None,
    'quantum_kernel': <qiskit_machine_learning.kernels.trainable_fidelity_statevector_kernel.TrainableFidelityStatevectorKernel object at 0x15a9386d0>}
Accuracy test: 1.0
Run time for TrainableFidelityStatevectorKernel: 0.8832503749872558 secs

@coveralls
Copy link

coveralls commented May 23, 2023

Pull Request Test Coverage Report for Build 5144942540

  • 35 of 35 (100.0%) changed or added relevant lines in 4 files are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage increased (+0.06%) to 92.915%

Totals Coverage Status
Change from base Build 5134410619: 0.06%
Covered Lines: 2649
Relevant Lines: 2851

💛 - Coveralls

@declanmillar declanmillar force-pushed the add-trainable-fidelity-statevector-kernel branch from 6d14324 to 4b1b144 Compare May 24, 2023 12:35
@declanmillar declanmillar marked this pull request as ready for review May 24, 2023 14:38
@declanmillar declanmillar self-assigned this May 24, 2023
@declanmillar declanmillar requested a review from ElePT May 24, 2023 14:39
@declanmillar declanmillar force-pushed the add-trainable-fidelity-statevector-kernel branch 2 times, most recently from 767877a to b3d3ec6 Compare May 30, 2023 10:59
Copy link
Collaborator

@ElePT ElePT left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for my late review, I think that Steve already commented on all the key points, so LGTM. Maybe now that we are at it, we could also sneak in the fix for #649 in this PR?

@declanmillar declanmillar force-pushed the add-trainable-fidelity-statevector-kernel branch from 94350c6 to f24ad8d Compare June 1, 2023 13:27
@woodsp-ibm woodsp-ibm added this to the 0.7.0 milestone Jun 1, 2023
Copy link
Member

@woodsp-ibm woodsp-ibm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@declanmillar declanmillar force-pushed the add-trainable-fidelity-statevector-kernel branch from f24ad8d to fd24b86 Compare June 2, 2023 01:53
@CLAassistant
Copy link

CLAassistant commented Jun 7, 2023

CLA assistant check
All committers have signed the CLA.

@coveralls
Copy link

coveralls commented Jun 8, 2023

Pull Request Test Coverage Report for Build 5222812947

  • 35 of 35 (100.0%) changed or added relevant lines in 4 files are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage increased (+0.06%) to 92.915%

Totals Coverage Status
Change from base Build 5222270613: 0.06%
Covered Lines: 2649
Relevant Lines: 2851

💛 - Coveralls

@adekusar-drl adekusar-drl merged commit 2471792 into qiskit-community:main Jun 10, 2023
@declanmillar declanmillar deleted the add-trainable-fidelity-statevector-kernel branch June 10, 2023 14:02
oscar-wallis pushed a commit that referenced this pull request Feb 16, 2024
* add trainable fidelity statevector kernel

* fix copyright

* refactor check on trainable parameters

* fix copyright

* consolidate trainable kernels tests

* avoid string flags in tests

* fix copyright

* test trainer with statevector kernel

* add release note

* fix style

* format release note

* lint

* style

* Update release note based on Steve's comments

* add imports to release note snippet

* fix typo

---------

Co-authored-by: Anton Dekusar <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add TrainableFidelityStatevectorKernel
6 participants