Release Notes¶
0.8.0¶
Prelude¶
From this release, Qiskit Machine Learning requires Qiskit 1.0 or above, with important changes and upgrades, such as the introduction of Quantum Bayesian inference and the migration of a subset of Qiskit Algorithms features to Qiskit Machine Learning. These changes are part of the process to build full compatibility with the version-2 (V2) Qiskit primitives available from version 0.8 of Qiskit Machine Learning. V1 primitives are deprecated and will be removed from version 0.9 (please find more information below).
New Features¶
Added a new class
QBayesian
that does quantum Bayesian inference on a a quantum circuit representing a Bayesian network with binary random variables.The computational complexity is reduced from \(O(nmP(e)^{-1})\) to \(O(n2^{m}P(e)^{-\frac{1}{2}})\) per sample, where n is the number of nodes in the Bayesian network with at most m parents per node and e the evidence.
At least a quantum circuit that represents the Bayesian network has to be provided. A quantum circuit can be passed in various forms as long as it represents the joint probability distribution of the Bayesian network. Note that
QBayesian
defines an order for the qubits in the circuit. The last qubit in the circuit will correspond to the most significant bit in the joint probability distribution. For example, if the random variables A, B, and C are entered into the circuit in this order with (A=1, B=0 and C=0), the probability is represented by the probability amplitude of quantum state 001.An example for using this class is as follows:
from qiskit import QuantumCircuit from qiskit_machine_learning.algorithms import QBayesian # Define a quantum circuit qc = QuantumCircuit(...) # Initialize the framework qb = QBayesian(qc) # Perform inference result = qb.inference(query={...}, evidence={...}) print("Probability of query given evidence:", result)
For the new
QBayesian
class, a tutorial was added. Please refer to:New QBI tutorial that introduces a step-by-step approach for how to do quantum Bayesian inference on a Bayesian network.
Added support for using Qiskit Machine Learning with Python 3.12.
Migrated essential Qiskit Algorithms features to Qiskit Machine Learning:
qiskit_algorithms/gradients -> qiskit_machine_learning/gradients. Note: only the SPSA, parameter-shift and linear-combination-of-unitaries gradients are retained. Other gradient strategies, such as reverse and finite-diff are not incorporated.
qiskit_algorithms/optimizers -> qiskit_machine_learning/optimizers. Note: optimizers from scikit-quant are not incorporated.
qiskit_algorithms/state_fidelities -> qiskit_machine_learning/state_fidelities
Partial merge of qiskit_algorithms/utils with qiskit_machine_learning/utils
From the next release, Qiskit Machine Learning will require Qiskit 1.0 or higher. You may be required to upgrade Qiskit Aer accordingly, depending on your set-up.
Support for V2 Primitives: The EstimatorQNN and SamplerQNN classes now support V2 primitives (EstimatorV2 and SamplerV2), allowing direct execution on IBM Quantum backends. This enhancement ensures compatibility with Qiskit IBM Runtime’s Primitive Unified Block (PUB) requirements and instruction set architecture (ISA) constraints for circuits and observables. Users can switch between V1 primitives and V2 primitives from version 0.8. From version 0.9, V1 primitives will be removed.
Upgrade Notes¶
Removed support for using Qiskit Machine Learning with Python 3.8 to reflect the EOL of Python 3.8 in October 2024 (PEP 569). To continue using Qiskit Machine Learning, you must upgrade to a Python: 3.9 or above if you are using older versions of Python.
From version 0.8.0, Qiskit Machine Learning requires Qiskit 1.0 or higher.
The merge of some of the features of Qiskit Algorithms into Qiskit Machine Learning might lead to breaking changes. For this reason, caution is advised when updating to version 0.8 during critical production stages in a project. This change ensures continued enhancement and maintenance of essential features for Qiskit Machine Learning following the end of official support for Qiskit Algorithms. Therefore, Qiskit Machine Learning will no longer depend on Qiskit Algorithms.
Users must update their imports and code references in code that uses Qiskit Machine Leaning and Algorithms:
Change qiskit_algorithms.gradients to qiskit_machine_learning.gradients
Change qiskit_algorithms.optimizers to qiskit_machine_learning.optimizers
Change qiskit_algorithms.state_fidelities to qiskit_machine_learning.state_fidelities
Update utilities as needed due to partial merge.
To continue using sub-modules and functionalities of Qiskit Algorithms that have not been transferred, you may continue using them as before by importing from Qiskit Algorithms. However, be aware that Qiskit Algorithms is no longer officially supported and some of its functionalities may not work in your use case. For any problems directly related to Qiskit Algorithms, please open a GitHub issue at https://github .com/qiskit-community/qiskit-algorithms. Should you want to include a Qiskit Algorithms functionality that has not been incorporated in Qiskit Machine Learning, please open a feature-request issue at https://github.com/qiskit-community/qiskit-machine-learning, explaining why this change would be useful for you and other users.
Four examples of upgrading the code can be found below.
Gradients:
# Before: from qiskit_algorithms.gradients import SPSA, ParameterShift # After: from qiskit_machine_learning.gradients import SPSA, ParameterShift # Usage spsa = SPSA() param_shift = ParameterShift()
Optimizers
# Before: from qiskit_algorithms.optimizers import COBYLA, ADAM # After: from qiskit_machine_learning.optimizers import COBYLA, ADAM # Usage cobyla = COBYLA() adam = ADAM()
Quantum state fidelities
# Before: from qiskit_algorithms.state_fidelities import ComputeFidelity # After: from qiskit_machine_learning.state_fidelities import ComputeFidelity # Usage fidelity = ComputeFidelity()
Algorithm globals (used to fix the random seed)
# Before: from qiskit_algorithms.utils import algorithm_globals # After: from qiskit_machine_learning.utils import algorithm_globals algorithm_globals.random_seed = 1234
Users working with real backends are advised to migrate to V2 primitives (EstimatorV2 and SamplerV2) to ensure compatibility with Qiskit IBM Runtime hardware requirements. These V2 primitives will become the standard in the 0.8 release going forward, while V1 primitives are deprecated.
Deprecation Notes¶
Deprecated V1 Primitives: The V1 primitives (e.g., EstimatorV1 and SamplerV1) are no longer compatible with real quantum backends via Qiskit IBM Runtime. This update provides initial transitional support, but V1 primitives may be fully deprecated and removed in version 0.9. Users should adopt V2 primitives for both local and hardware executions to ensure long-term compatibility.
Bug Fixes¶
Added a max_circuits_per_job parameter to the
FidelityQuantumKernel
used in the case that if more circuits are submitted than the job limit for the backend, the circuits are split up and run through separate jobs.
Removed
QuantumKernelTrainer
dependency on copy.deepcopy that was throwing an error with real backends. Now, it modifies theTrainableKernel
in place. If you would like to use the initial kernel, please callassign_training_parameters()
of theTrainableKernel
using theinitial_point
attribute ofQuantumKernelTrainer
.
Fixes the dimension mismatch error in the torch_connector raised when using other-than 3D datasets. The updated implementation defines the Einstein summation signature dynamically based on the number of dimensions ndim of the input data (up to 26 dimensions).
Fixed a bug where
FidelityStatevectorKernel
threw an error when pickled.
Fixes an issue for the Quantum Neural Networks where the binding order of the inputs and weights might end up being incorrect. Though the params for the inputs and weights are specified to the QNN, the code previously bound the inputs and weights in the order given by the circuit.parameters. This would end up being the right order for the Qiskit circuit library feature maps and ansatzes most often used, as the default parameter names led to the order being as expected. However for custom names etc. this was not always the case and then led to unexpected behavior. The sequences for the input and weights parameters, as supplied, are now always used as the binding order, for the inputs and weights respectively, such that the order of the parameters in the overall circuit no longer matters.
0.7.0¶
Prelude¶
Qiskit Machine Learning has been migrated to the qiskit-community Github organization to further emphasize that it is a community-driven project. To reflect this change, and because we are onboarding additional code-owners and maintainers, with this version (0.7) we have decided to remove all deprecated code, regardless of the time of its deprecation. This ensures that the new members of the development team do not have a large bulk of legacy code to maintain. This can mean one of two things for you as the end-user:
Nothing, if you already migrated your code and no longer rely on any deprecated features.
Otherwise, you should make sure that your workflow doesn’t rely on deprecated classes. If you cannot do that, or want to continue using some of the features that were removed, you should pin your version of Qiskit Machine Learning to 0.6.
For more context on the changes around Qiskit Machine Learning and the other application projects as well as the Algorithms library in Qiskit, be sure to read this blog post.
New Features¶
The
QNNCircuit
class can be passed as circuit to theSamplerQNN
andEstimatorQNN
. This simplifies the interfaces to build aSampler
orEstimator
based neural network implementation from a feature map and an ansatz circuit.Using the
QNNCircuit
comes with the benefit that the feature map and ansatz do not have to be composed explicitly. If aQNNCircuit
is passed to theSamplerQNN
orEstimatorQNN
the input and weight parameters do not have to be provided, because these two properties are taken from theQNNCircuit
.An example of using
QNNCircuit
with theSamplerQNN
class is as follows:from qiskit_machine_learning.circuit.library import QNNCircuit from qiskit_machine_learning.neural_networks import SamplerQNN def parity(x): return f"{bin(x)}".count("1") % 2 # Create a parameterized 2 qubit circuit composed of the default ZZFeatureMap feature map # and RealAmplitudes ansatz. qnn_qc = QNNCircuit(num_qubits = 2) qnn = SamplerQNN( circuit=qnn_qc, interpret=parity, output_shape=2 ) qnn.forward(input_data=[1, 2], weights=[1, 2, 3, 4, 5, 6, 7, 8])
The
QNNCircuit
is used with theEstimatorQNN
class in the same fashion:from qiskit_machine_learning.circuit.library import QNNCircuit from qiskit_machine_learning.neural_networks import EstimatorQNN # Create a parameterized 2 qubit circuit composed of the default ZZFeatureMap feature map # and RealAmplitudes ansatz. qnn_qc = QNNCircuit(num_qubits = 2) qnn = EstimatorQNN( circuit=qnn_qc ) qnn.forward(input_data=[1, 2], weights=[1, 2, 3, 4, 5, 6, 7, 8])
Added a new
QNNCircuit
class that composes a Quantum Circuit from a feature map and an ansatz.At least one parameter, i.e. number of qubits, feature map, ansatz, has to be provided.
If only the number of qubits is provided the resulting quantum circuit is a composition of the
ZZFeatureMap
and theRealAmplitudes
ansatz. If the number of qubits is 1 theZFeatureMap
is used per default. If only a feature map is provided, theRealAmplitudes
ansatz with the corresponding number of qubits is used. If only an ansatz is provided theZZFeatureMap
with the corresponding number of qubits is used.In case number of qubits is provided along with either a feature map, an ansatz or both, a potential mismatch between the three inputs with respect to the number of qubits is resolved by constructing the
QNNCircuit
with the given number of qubits. If one of theQNNCircuit
properties is set after the class construction, the circuit is is adjusted to incorporate the changes. This is, a new valid configuration that considers the latest property update will be derived. This ensures that the classes properties are consistent at all times.An example of using this class is as follows:
from qiskit_machine_learning.circuit.library import QNNCircuit qnn_qc = QNNCircuit(2) print(qnn_qc) # prints: # ┌──────────────────────────┐» # q_0: ┤0 ├» # │ ZZFeatureMap(x[0],x[1]) │» # q_1: ┤1 ├» # └──────────────────────────┘» # « ┌──────────────────────────────────────────────────────────┐ # «q_0: ┤0 ├ # « │ RealAmplitudes(θ[0],θ[1],θ[2],θ[3],θ[4],θ[5],θ[6],θ[7]) │ # «q_1: ┤1 ├ # « └──────────────────────────────────────────────────────────┘ print(qnn_qc.num_qubits) # prints: 2 print(qnn_qc.input_parameters) # prints: ParameterView([ParameterVectorElement(x[0]), ParameterVectorElement(x[1])]) print(qnn_qc.weight_parameters) # prints: ParameterView([ParameterVectorElement(θ[0]), ParameterVectorElement(θ[1]), # ParameterVectorElement(θ[2]), ParameterVectorElement(θ[3]), # ParameterVectorElement(θ[4]), ParameterVectorElement(θ[5]), # ParameterVectorElement(θ[6]), ParameterVectorElement(θ[7])])
A new
TrainableFidelityStatevectorKernel
class has been added that provides a trainable version ofFidelityStatevectorKernel
. This relationship mirrors that between the existingFidelityQuantumKernel
. Thus,TrainableFidelityStatevectorKernel
inherits from bothFidelityStatevectorKernel
andTrainableKernel
.This class is used with
QuantumKernelTrainer
in an identical way toTrainableFidelityQuantumKernel
, except for the arguments specific toTrainableFidelityStatevectorKernel
.For an example, see the snippet below:
from qiskit.quantum_info import Statevector from qiskit_machine_learning.kernels import TrainableFidelityStatevectorKernel from qiskit_machine_learning.kernels.algorithms import QuantumKernelTrainer # Instantiate trainable fidelity statevector kernel. quantum_kernel = TrainableFidelityStatevectorKernel( feature_map=<your_feature_map>, statevector_type=Statevector, training_parameters=<your_training_parameters>, cache_size=None, auto_clear_cache=True, shots=None, enforce_psd=True, ) # Instantiate a quantum kernel trainer (QKT). qkt = QuantumKernelTrainer(quantum_kernel=quantum_kernel) # Train the kernel using QKT directly. qkt_results = qkt.fit(<your_X_train>, <your_y_train>) optimized_kernel = qkt_results.quantum_kernel
The module is migrated to Qiskit Algorithms from the qiskit.algorithms package that is deprecated now.
Upgrade Notes¶
Support for running with Python 3.7 has been removed. To run Qiskit Machine Learning you need a minimum Python version of 3.8.
Removed support of the deprecated parameter quantum_instance in the constructor of
VQC
and inVQR
. Please use sampler and estimator respectively. Refer to the migration guide for more information.Since
qiskit.opflow
andQuantumInstance
are deprecated in Qiskit, Qiskit Machine Learning classes based on the deprecated Qiskit classes have been removed:Class
qiskit_machine_learning.neural_networks.SamplingNeuralNetwork
is removed and has no direct replacement as this is a base class.Class
qiskit_machine_learning.neural_networks.CircuitQNN
is removed and is superseded byqiskit_machine_learning.neural_networks.SamplerQNN
.Class
qiskit_machine_learning.neural_networks.OpflowQNN
is removed and is superseded byqiskit_machine_learning.neural_networks.EstimatorQNN
.Class
qiskit_machine_learning.neural_networks.TwoLayerQNN
is removed and has no direct replacement. Please make use ofqiskit_machine_learning.neural_networks.EstimatorQNN
instead.Class
qiskit_machine_learning.kernels.QuantumKernel
is removed and is superseded byqiskit_machine_learning.kernels.FidelityQuantumKernel
,qiskit_machine_learning.kernels.TrainableFidelityQuantumKernel
, andqiskit_machine_learning.kernels.FidelityStatevectorKernel
.
Please refer to the migration guide on how to replace the deprecated classes with new ones.
The previously deprecated qgan and runtime packages have been removed. Please refer to:
New QGAN tutorial to train a generative quantum neural network.
New primitive based quantum neural networks
EstimatorQNN
,SamplerQNN
, PyTorch connectorTorchConnector
, and Qiskit Runtime Service to get functionality similar to what the removed runtime package provided.
Bug Fixes¶
Compatibility fix to support Python 3.11.
Fixes a bug in
FidelityStatevectorKernel
where kernel entries could potentially have nonzero complex components due to truncation and rounding errors when enforcing a PSD matrix.
Updated
RawFeatureVector
to support changes in the parameter assignment introduced in Qiskit.
Fixed incorrect type conversions in
TorchConnector
. The bug was causing the connector to convert the output to the same type as the input data. As a result, when an integer tensor was passed, the output would also be converted to an integer tensor, leading to rounding errors.
0.6.0¶
New Features¶
Allow callable as an optimizer in
NeuralNetworkClassifier
,VQC
,NeuralNetworkRegressor
,VQR
, as well as inQuantumKernelTrainer
.Now, the optimizer can either be one of Qiskit’s optimizers, such as
SPSA
or a callable with the following signature:from qiskit.algorithms.optimizers import OptimizerResult def my_optimizer(fun, x0, jac=None, bounds=None) -> OptimizerResult: # Args: # fun (callable): the function to minimize # x0 (np.ndarray): the initial point for the optimization # jac (callable, optional): the gradient of the objective function # bounds (list, optional): a list of tuples specifying the parameter bounds result = OptimizerResult() result.x = # optimal parameters result.fun = # optimal function value return result
The above signature also allows to directly pass any SciPy minimizer, for instance as
from functools import partial from scipy.optimize import minimize optimizer = partial(minimize, method="L-BFGS-B")
Added a new
FidelityStatevectorKernel
class that is optimized to use only statevector-implemented feature maps. Therefore, computational complexity is reduced from \(O(N^2)\) to \(O(N)\).Computed statevector arrays are also cached to further increase efficiency. This cache is cleared when the
evaluate
method is called, unlessauto_clear_cache
isFalse
. The cache is unbounded by default, but its size can be set by the user, i.e., limited to the number of samples in the worst case.By default the Terra reference
Statevector
is used, however, the type can be specified via thestatevector_type
argument.Shot noise emulation can also be added. If
shots
isNone
, the exact fidelity is used. Otherwise, the mean is taken of samples drawn from a binomial distribution with probability equal to the exact fidelity.With the addition of shot noise, the kernel matrix may no longer be positive semi-definite (PSD). With
enforce_psd
set toTrue
this condition is enforced.An example of using this class is as follows:
from sklearn.datasets import make_blobs from sklearn.svm import SVC from qiskit.circuit.library import ZZFeatureMap from qiskit.quantum_info import Statevector from qiskit_machine_learning.kernels import FidelityStatevectorKernel # generate a simple dataset features, labels = make_blobs( n_samples=20, centers=2, center_box=(-1, 1), cluster_std=0.1 ) feature_map = ZZFeatureMap(feature_dimension=2, reps=2) statevector_type = Statevector kernel = FidelityStatevectorKernel( feature_map=feature_map, statevector_type=Statevector, cache_size=len(labels), auto_clear_cache=True, shots=1000, enforce_psd=True, ) svc = SVC(kernel=kernel.evaluate) svc.fit(features, labels)
The PyTorch connector
TorchConnector
now fully supports sparse output in both forward and backward passes. To enable sparse support, first of all, the underlying quantum neural network must be sparse. In this case, if the sparse property of the connector itself is not set, then the connector inherits sparsity from the networks. If the connector is set to be sparse, but the network is not, an exception will be raised. Also you may set the connector to be dense if the network is sparse.This snippet illustrates how to create a sparse instance of the connector.
import torch from qiskit import QuantumCircuit from qiskit.circuit.library import ZFeatureMap, RealAmplitudes from qiskit_machine_learning.connectors import TorchConnector from qiskit_machine_learning.neural_networks import SamplerQNN num_qubits = 2 fmap = ZFeatureMap(num_qubits, reps=1) ansatz = RealAmplitudes(num_qubits, reps=1) qc = QuantumCircuit(num_qubits) qc.compose(fmap, inplace=True) qc.compose(ansatz, inplace=True) qnn = SamplerQNN( circuit=qc, input_params=fmap.parameters, weight_params=ansatz.parameters, sparse=True, ) connector = TorchConnector(qnn) output = connector(torch.tensor([[1., 2.]])) print(output) loss = torch.sparse.sum(output) loss.backward() grad = connector.weight.grad print(grad)
In hybrid setup, where a PyTorch-based neural network has classical and quantum layers, sparse operations should not be mixed with dense ones, otherwise exceptions may be thrown by PyTorch.
Sparse support works on python 3.8+.
Upgrade Notes¶
The previously deprecated
CrossEntropySigmoidLoss
loss function has been removed.
The previously deprecated datasets have been removed:
breast_cancer
,digits
,gaussian
,iris
,wine
.
Bug Fixes¶
SamplerQNN
can now correctly handle quantum circuits without both input parameters and weights. If such a circuit is passed to the QNN then this circuit executed once in the forward pass and backward returnsNone
for both gradients.
0.5.0¶
New Features¶
Added support for categorical and ordinal labels to
VQC
. Now labels can be passed in different formats, they can be plain ordinal labels, a one dimensional array that contains integer labels like 0, 1, 2, …, or an array with categorical string labels. One-hot encoded labels are still supported. Internally, labels are transformed to one hot encoding and the classifier is always trained on one hot labels.
Introduced Estimator Quantum Neural Network (
EstimatorQNN
) based on (runtime) primitives. This implementation leverages the estimator primitive (seeBaseEstimator
) and the estimator gradients (seeBaseEstimatorGradient
) to enable runtime access and more efficient computation of forward and backward passes.The new
EstimatorQNN
exposes a similar interface to the Opflow QNN, with a few differences. One is the quantum_instance parameter. This parameter does not have a direct replacement, and instead the estimator parameter must be used. The gradient parameter keeps the same name as in the Opflow QNN implementation, but it no longer accepts Opflow gradient classes as inputs; instead, this parameter expects an (optionally custom) primitive gradient.The existing training algorithms such as
VQR
, that were based on the Opflow QNN, are updated to accept both implementations. The implementation ofNeuralNetworkRegressor
has not changed.For example a VQR using EstimatorQNN can be trained as follows:
import numpy as np from qiskit.algorithms.optimizers import L_BFGS_B from qiskit.circuit import QuantumCircuit, Parameter from qiskit.primitives import Estimator from qiskit_machine_learning.algorithms import VQR num_samples = 20 eps = 0.2 lb, ub = -np.pi, np.pi X = (ub - lb) * np.random.rand(num_samples, 1) + lb Y = np.sin(X[:, 0]) + eps * (2 * np.random.rand(num_samples) - 1) params = [Parameter("θ_0"), Parameter("θ_1")] feature_map = QuantumCircuit(1, name="fm") feature_map.ry(params[0], 0) ansatz = QuantumCircuit(1, name="vf") ansatz.ry(params[1], 0) vqr = VQR( feature_map=feature_map, ansatz=ansatz, optimizer=L_BFGS_B(maxiter=5), initial_point=np.array([0]), estimator=Estimator() ) vqr.fit(X, Y)
Introduced Quantum Kernels based on (runtime) primitives. This implementation leverages the fidelity primitive (see
BaseStateFidelity
) and provides more flexibility to end users. The fidelity primitive calculates state fidelities/overlaps for pairs of quantum circuits and requires an instance ofSampler
. Thus, users may plug in their own implementations of fidelity calculations.The new kernels expose the same interface and the same parameters except the quantum_instance parameter. This parameter does not have a direct replacement and instead the fidelity parameter must be used.
A new hierarchy is introduced:
A base and abstract class
BaseKernel
is introduced. All concrete implementation must inherit this class.A fidelity based quantum kernel
FidelityQuantumKernel
is added. This is a direct replacement ofQuantumKernel
. The difference is that the new class takes either a sampler or a fidelity instance to estimate overlaps and construct kernel matrix.A new abstract class
TrainableKernel
is introduced to generalize ability to train quantum kernels.A fidelity-based trainable quantum kernel
TrainableFidelityQuantumKernel
is introduced. This is a replacement of the existingQuantumKernel
if a trainable kernel is required. The trainerQuantumKernelTrainer
now accepts both quantum kernel implementations, the new one and the existing one.
The existing algorithms such as
QSVC
,QSVR
and other kernel-based algorithms are updated to accept both implementations.For example a QSVM classifier can be trained as follows:
from qiskit.algorithms.state_fidelities import ComputeUncompute from qiskit.circuit.library import ZZFeatureMap from qiskit.primitives import Sampler from sklearn.datasets import make_blobs from qiskit_machine_learning.algorithms import QSVC from qiskit_machine_learning.kernels import FidelityQuantumKernel # generate a simple dataset features, labels = make_blobs(n_samples=20, centers=2, center_box=(-1, 1), cluster_std=0.1) # fidelity is optional and quantum kernel will create it automatically if none is passed fidelity = ComputeUncompute(sampler=Sampler()) feature_map = ZZFeatureMap(2) kernel = FidelityQuantumKernel(feature_map=feature_map, fidelity=fidelity) qsvc = QSVC(quantum_kernel=kernel) qsvc.fit(features, labels)
Introduced Sampler Quantum Neural Network (
SamplerQNN
) based on (runtime) primitives. This implementation leverages the sampler primitive (seeBaseSampler
) and the sampler gradients (seeBaseSamplerGradient
) to enable runtime access and more efficient computation of forward and backward passes more efficiently.The new
SamplerQNN
exposes a similar interface to theCircuitQNN
, with a few differences. One is the quantum_instance parameter. This parameter does not have a direct replacement, and instead the sampler parameter must be used. The gradient parameter keeps the same name as in theCircuitQNN
implementation, but it no longer accepts Opflow gradient classes as inputs; instead, this parameter expects an (optionally custom) primitive gradient. The sampling option has been removed for the time being, as this information is not currently exposed by the Sampler, and might correspond to future lower-level primitives.The existing training algorithms such as
VQC
, that were based on theCircuitQNN
, are updated to accept both implementations. The implementation ofNeuralNetworkClassifier
has not changed.For example a
VQC
usingSamplerQNN
can be trained as follows:from qiskit.circuit.library import ZZFeatureMap, RealAmplitudes from qiskit.algorithms.optimizers import COBYLA from qiskit.primitives import Sampler from sklearn.datasets import make_blobs from qiskit_machine_learning.algorithms import VQC # generate a simple dataset num_inputs = 20 features, labels = make_blobs(n_samples=num_inputs, centers=2, center_box=(-1, 1), cluster_std=0.1) # construct feature map feature_map = ZZFeatureMap(num_inputs) # construct ansatz ansatz = RealAmplitudes(num_inputs, reps=1) # construct variational quantum classifier vqc = VQC( sampler=sampler, feature_map=feature_map, ansatz=ansatz, loss="cross_entropy", optimizer=COBYLA(maxiter=30), ) # fit classifier to data vqc.fit(features, labels)
Expose the callback attribute as public property on
TrainableModel
. This, for instance, allows setting the callback between optimizations and store the history in separate objects.
Gradient operator/circuit initialization in
OpflowQNN
andCircuitQNN
respectively is now delayed until the first call of thebackward
method. Thus, the networks are created faster and gradient framework objects are not created until they are required.
Introduced a new parameter evaluate_duplicates in
QuantumKernel
. This parameter defines a strategy how kernel matrix elements are evaluated if duplicate samples are found. Possible values are:all
means that all kernel matrix elements are evaluated, even the diagonal ones whentraining. This may introduce additional noise in the matrix.
off_diagonal
when training the matrix diagonal is set to 1, the rest elements arefully evaluated, e.g., for two identical samples in the dataset. When inferring, all elements are evaluated. This is the default value.
none
when training the diagonal is set to 1 and if two identical samples are foundin the dataset the corresponding matrix element is set to 1. When inferring, matrix elements for identical samples are set to 1.
In the previous releases, in the
QGAN
class, the gradient penalty could not be enabled to train the discriminator with a penalty function. Thus, a gradient penalty parameter was added during the initialization of the QGAN algorithm. This parameter indicates whether or not penalty function is applied to the loss function of the discriminator during training.
Enable the default construction of the
ZFeatureMap
in theTwoLayerQNN
if the number of qubits is 1. Previously, not providing a feature map for the single qubit case raised an error as default construction assumed 2 or more qubits.
VQC
will now raise an error when training from a warm start when encountering targets with a different number of classes to the previous dataset.
VQC
will now raise an error when a user attempts multi-label classification, which is not supported.
- Added two new properties to the
TrainableModel
class: fit_result
returns a resulting object from the optimization procedure. Please refers to the Terra’s documentation of the OptimizerResult class.weights
returns an array of trained weights, this is a convenient way to get access to the weights, it is the same as callingmodel.fit_result.x
.
- Added two new properties to the
Upgrade Notes¶
The method
fit()
is not abstract any more. Now, it implements basic checks, calls a new abstract method_fit_internal()
to be implemented by sub-classes, and keeps track offit_result
property that is returned by this new abstract method. Thus, any sub-class ofTrainableModel
must implement this new method. ClassesNeuralNetworkClassifier
andNeuralNetworkRegressor
have been updated correspondingly.
Inheriting from sklearn.svm.SVC in PegasosQSVC resulted in errors when calling some inherited methods such as decision_function due to the overridden fit implementation. For that reason, the inheritance has been replaced by a much lighter inheritance from ClassifierMixin providing the score method and a new method decision_function has been implemented. The class is still sklearn compatible due to duck typing. This means that for the user everything that has been working in the previous release still works, except the inheritance. The only methods that are no longer supported (such as predict_proba) were only raising errors in the previous release in practice.
Deprecation Notes¶
The qiskit_machine_learning.algorithms.distribution_learners package is deprecated and will be removed no sooner than 3 months after the release. There’s no direct replacement for the classes from this package. Instead, please refer to the new QGAN tutorial. This tutorial introduces step-by-step how to build a PyTorch-based QGAN using quantum neural networks.
Classes
qiskit_machine_learning.runtime.TorchRuntimeClient
,qiskit_machine_learning.runtime.TorchRuntimeResult
,qiskit_machine_learning.runtime.HookBase
and functionsqiskit_machine_learning.runtime.str_to_obj()
,qiskit_machine_learning.runtime.obj_to_str()
are being deprecated. You should use QiskitRuntimeService to leverage primitives and runtimes.
Class
qiskit_machine_learning.neural_networks.CircuitQNN
is pending deprecation and is superseded byqiskit_machine_learning.neural_networks.SamplerQNN
.Class
qiskit_machine_learning.neural_networks.OpflowQNN
is pending deprecation and is superseded byqiskit_machine_learning.neural_networks.EstimatorQNN
.Class
qiskit_machine_learning.neural_networks.TwoLayerQNN
is pending deprecation and has no direct replacement. Please make use ofqiskit_machine_learning.neural_networks.EstimatorQNN
instead.These classes will be deprecated in a future release and subsequently removed after that.
Class
qiskit_machine_learning.kernels.QuantumKernel
is pending deprecation and is superseded byqiskit_machine_learning.kernels.FidelityQuantumKernel
andqiskit_machine_learning.kernels.TrainableFidelityQuantumKernel
.This class will be deprecated in a future release and subsequently removed after that.
For the class
QuantumKernel
, to improve usability and better describe the usage,user_parameters
has been renamed totraining_parameters
; current behavior is retained. For this change the constructor parameteruser_parameters
is now deprecated and replaced bytraining_parameters
. The related properties and methods are renamed to match. That is to say:argument
user_parameters
->training_parameters
property
user_parameters
->training_parameters
property
user_param_binds
->training_parameter_binds
method
assign_user_parameters
->assign_training_parameters
method
bind_user_parameters
->bind_training_parameters
method
get_unbound_user_parameters
->get_unbound_training_parameters
Bug Fixes¶
Previously in the
QuantumGenerator
of theQGAN
algorithm, if we used a simulator other than the statevector_simulator the result dictionary had not the correct size to compute both the gradient and the loss functions. Now, the values output are stored in a vector of size 2^n and each key is mapped to its value from the result dictionary in the new value array. Also, each key is stored in a vector of size 2^n where each element of the vector keys[i] corresponds to the binary representation of i.
Previously in the
QuantumGenerator
of theQGAN
algorithm, the gradients were computed using the statevector backend even if we specified another backend. To solve this issue, the gradient object is converted into a CircuitStateFn instead of its adjoint as in the previous version. The gradients are converted into the backend-dependent structure using CircuitSampler. After the evaluation of the object, the gradient_function is stored in a dense array to fix a dimension incompatibility when computing the loss function.
Fixed quantum kernel evaluation when duplicate samples are found in the dataset. Originally, kernel matrix elements were not evaluated for identical samples in the dataset and such elements were set wrongly to zero. Now we introduced a new parameter evaluate_duplicates that ensures that elements of the kernel matrix are evaluated correctly. See the feature section for more details.
Previously in the
pytorch_discriminator
class of theQGAN
algorithm, if the gradient penalty parameter was enabled, the latent variable z was not properly initialized : Variable module was used instead of torch.autograd.Variable.
Calling PegasosQSVC.decision_function() raises an error. Fixed by writing own method instead of inheriting from SVC. The inheritance from SVC in the PegasosQSVC class is removed. To keep the score method, inheritance to the mixin class ClassifierMixin from scikit-learn is added.
0.4.0¶
New Features¶
In the previous releases at the backpropagation stage of
CircuitQNN
andOpflowQNN
gradients were computed for each sample in a dataset individually and then the obtained values were aggregated into one output array. Thus, for each sample in a dataset at least one job was submitted. Now, gradients are computed for all samples in a dataset in one go by passing a list of values for a single parameter toCircuitSampler
. Therefore, a number of jobs required for such computations is significantly reduced. This improvement may speed up training process in the cloud environment, where queue time for submitting a job may be a major contribution in the overall training time.
Introduced two new classes,
EffectiveDimension
andLocalEffectiveDimension
, for calculating the capacity of quantum neural network models through the computation of the Fisher Information Matrix. The local effective dimension bounds the generalization error of QNNs and only accepts single parameter sets as inputs. The global effective dimension (or just effective dimension) can be used as a measure of the expressibility of the model, and accepts multiple parameter sets.
Objective functions constructed by the neural network classifiers and regressors now include an averaging factor that is evaluated as
1 / number_of_samples
. Computed averaged objective values are passed to a user specified callback if any. Users may notice a dramatic decrease in the objective values in their callbacks. This is due to this averaging factor.
Added support for saving and loading machine learning models. This support is introduced in
TrainableModel
, so all sub-classes can be saved and loaded. Also, kernel based models can be saved and loaded. A list of models that support saving and loading models:NeuralNetworkClassifier
NeuralNetworkRegressor
VQC
VQR
QSVC
QSVR
PegasosQSVC
When model is saved all model parameters are saved to a file, including a quantum instance that is referenced by internal objects. That means if a model is loaded from a file and is used, for instance, for inference, the same quantum instance and a corresponding backend will be used even if a cloud backend was used.
Added a new feature in
CircuitQNN
that ensures unbound_pass_manager is called when caching the QNN circuit and thatbound_pass_manager
is called when QNN parameters are assigned.
Added a new feature in
QuantumKernel
that ensures the bound_pass_manager is used, when provided via theQuantumInstance
, when transpiling the kernel circuits.
Upgrade Notes¶
Added support for running with Python 3.10. At the the time of the release, Torch didn’t have a python 3.10 version.
The previously deprecated
BaseBackend
class has been removed. It was originally deprecated in the Qiskit Terra 0.18.0 release.
Support for running with Python 3.6 has been removed. To run Machine Learning you need a minimum Python version of 3.7.
Deprecation Notes¶
The functions breast_cancer, digits, gaussian, iris and wine in the datasets module are deprecated and should not be used.
Class
CrossEntropySigmoidLoss
is deprecated and marked for removal.
Removed support of
l2
andl1
values as loss function definitions. Please, useabsolute_error
andsquared_error
respectively.
Bug Fixes¶
Fixes in Ad Hoc dataset. Fixed an
ValueError
whenn=3
is passed toad_hoc_data
. When the value ofn
is not 2 or 3, aValueError
is raised with a message that the only supported values ofn
are 2 and 3.
Previously, VQC would throw an error if trained on batches of data where not all of the target labels that can be found in the full dataset were present. This is because VQC interpreted the number of unique targets in the current batch as the number of classes. Currently, VQC is hard-coded to expect one-hot-encoded targets. Therefore, VQC will now determine the number of classes from the shape of the target array.
Fixes an issue where VQC could not be trained on multiclass datasets. It returned nan values on some iterations. This is fixed in 2 ways. First, the default parity function is now guaranteed to be able to assign at least one output bitstring to each class, so long as 2**N >= C where N is the number of output qubits and C is the number of classes. This guarantees that it is at least possible for every class to be predicted with a non-zero probability. Second, even with this change it is still possible that on a given training instance a class is predicted with 0 probability. Previously this could lead to nan in the CrossEntropyLoss calculation. We now replace 0 probabilities with a small positive value to ensure the loss cannot return nan.
Fixes an issue in
QuantumKernel
where evaluating a quantum kernel for data with dimension d>2 raised an error. This is fixed by changing the hard-coded reshaping of one-dimensional arrays inQuantumKernel.evaluate()
.
Fixes an issue where
VQC
would fail withwarm_start=True
. The extraction of theinitial_point
inTrainableModel
from the final point of the minimization had not been updated to reflect the refactor of optimizers inqiskit-terra
; the oldoptimize
method, that returned a tuple was deprecated and new methodminimize
was created that returns anOptimizerResult
object. We now correctly recover the final point of the minimization from previous fits to use for a warm start in subsequent fits.
Added GPU support to
TorchConnector
. Now, if a hybrid PyTorch model is being trained on GPU,TorchConnector
correctly detaches tensors, moves them to CPU, evaluate forward and backward passes and places resulting tensors to the same device they came from.
Fixed a bug when a sparse array is passed to
VQC
as labels. Sparse arrays can be easily observed when labels are encoded viaOneHotEncoder
fromSciKit-Learn
. Now bothNeuralNetworkClassifier
andVQC
support sparse arrays and convert them dense arrays in the implementation.
0.3.0¶
New Features¶
Addition of a
QuantumKernelTrainer
object which may be used by kernel-based machine learning algorithms to perform optimization of someQuantumKernel
parameters before training the model. Addition of a new base class,KernelLoss
, in theloss_functions
package. Addition of a newKernelLoss
subclass,SVCLoss
.
The class
TrainableModel
, and its sub-classesNeuralNetworkClassifier
,NeuralNetworkRegressor
,VQR
,VQC
, have a new optional argumentcallback
. User can optionally provide a callback function that can access the intermediate training data to track the optimization process, else it defaults toNone
. The callback function takes in two parameters: the weights for the objective function and the computed objective value. For each iteration an optimizer invokes the callback and passes current weights and computed value of the objective function.
Classification models (i.e. models that extend the
NeuralNetworkClassifier
class like VQC) can now handle categorical target data in methods likefit()
andscore()
. Categorical data is inferred from the presence of string type data and is automatically encoded using either one-hot or integer encodings. Encoder type is determined by theone_hot
argument supplied when instantiating the model.
There’s an additional transpilation step introduced in CircuitQNN that is invoked when a quantum instance is set. A circuit passed to
CircuitQNN
is transpiled and saved for subsequent usages. So, every time when the circuit is executed it is already transpiled and overall time of the forward pass is reduced. Due to implementation limitations ofRawFeatureVector
it can’t be transpiled in advance, so it is transpiled every time it is required to be executed and only when all parameters are bound. This means overall performance whenRawFeatureVector
is used stays the same.
Introduced a new classification algorithm, which is an alternative version of the Quantum Support Vector Classifier (QSVC) that is trained via the Pegasos algorithm from https://home.ttic.edu/~nati/Publications/PegasosMPB.pdf instead of the dual optimization problem like in sklearn. This algorithm yields a training complexity that is independent of the size of the training set (see the to be published Master’s Thesis “Comparing Quantum Neural Networks and Quantum Support Vector Machines” by Arne Thomsen), such that the PegasosQSVC is expected to train faster than QSVC for sufficiently large training sets.
QuantumKernel
transpiles all circuits before execution. However, thisinformation was not being passed, which calls the transpiler many times during the execution of the
QSVC/QSVR
algorithm. Now,had_transpiled=True
is passed correctly and the algorithm runs faster.
QuantumKernel
now provides an interface for users to specify a new class field,user_parameters
. User parameters are an array ofParameter
objects corresponding to parameterized quantum gates in the feature map circuit the user wishes to tune. This is useful in algorithms where feature map parameters must be bound and re-bound many times (i.e. variational algorithms). Users may also use a new functionassign_user_parameters
to assign real values to some or all of the user parameters in the feature map.
Introduce the
TorchRuntimeClient
for training a quantum model or a hybrid quantum-classical model faster using Qiskit Runtime. It can also be used for predicting the result using the trained model or calculating the score of the trained model faster using Qiskit Runtime.
Known Issues¶
If positional arguments are passed into QSVR or QSVC and these classes are printed, an exception is raised.
Deprecation Notes¶
Positional arguments in QSVR and QSVC are deprecated.
Bug Fixes¶
Fixed a bug in
QuantumKernel
where for statevector simulator all circuits were constructed and transpiled at once, leading to high memory usage. Now the circuits are batched similarly to how it was previously done for non-statevector simulators (same flag is used for both now; previouslybatch_size
was silently ignored by statevector simulator)
Fix a bug where
TorchConnector
failed on backward pass computation due to empty parameters for inputs or weights. Validation added toqiskit_machine_learning.neural_networks.NeuralNetwork._validate_backward_output()
.
TwoLayerQNN
now passes the value of theexp_val
parameter in the constructor to the constructor ofOpflowNN
whichTwoLayerQNN
inherits from.
In some configurations forward pass of a neural network may return the same value across multiple calls even if different weights are passed. This behavior is confirmed with
AQGD
optimizer. This was due to a bug in the implementation of the objective functions. They cache a value obtained at the forward pass to be re-used in the backward pass. Initially, this cache was based on an identifier (a call of id() function) of the weights array. AQGD re-uses the same array for weights: it updates the values keeping an instance of the array the same. This caused to re-use the same forward pass value across all iteration. Now the forward pass cache is based on actual values of weights instead of identifiers.
Fix a bug, where
qiskit_machine_learning.circuit.library.RawFeatureVector.copy()
didn’t copy all internal settings which could lead to issues with the copied circuit. As a consequenceqiskit_machine_learning.circuit.library.RawFeatureVector.bind_parameters()
is also fixed.
Fixes a bug where
VQC
could not be instantiated unless eitherfeature_map
oransatz
were provided (#217).VQC
is now instantiated with the defaultfeature_map
and/oransatz
.
The QNN weight parameter in TorchConnector is now registered in the torch DAG as
weight
, instead of_weights
. This is consistent with the PyTorch naming convention and theweight
property used to get access to the computed weights.
0.2.0¶
New Features¶
A base class
TrainableModel
is introduced for machine learning models. This class follows Scikit-Learn principles and makes the quantum machine learning compatible with classical models. BothNeuralNetworkClassifier
andNeuralNetworkRegressor
extend this class. A base classObjectiveFunction
is introduced for objective functions optimized by machine learning models. There are three objective functions introduced that are used by ML models:BinaryObjectiveFunction
,MultiClassObjectiveFunction
, andOneHotObjectiveFunction
. These functions are used internally by the models.
The
optimizer
argument for the classesNeuralNetworkClassifier
andNeuralNetworkRegressor
, both of which extends theTrainableModel
class, is made optional with the default value beingSLSQP()
. The same is true for the classesVQC
andVQR
as they inherit fromNeuralNetworkClassifier
andNeuralNetworkRegressor
respectively.
The constructor of
NeuralNetwork
, and all classes that inherit from it, has a new parameterinput_gradients
which defaults to False. Previously this parameter could only be set using the setter method. Note thatTorchConnector
previously setinput_gradients
of theNeuralNetwork
it was instantiated with toTrue
. This is not longer the case. So if you useTorchConnector
and want to compute the gradients w.r.t. the input, make sure you setinput_gradients=True
on theNeuralNetwork
before passing it toTorchConnector
.
Added a parameter
initial_point
to the neural network classifiers and regressors. This an array that is passed to an optimizer as an initial point to start from.
Computation of gradients with respect to input data in the backward method of
NeuralNetwork
is now optional. By default gradients are not computed. They may inspected and turned on, if required, by getting or setting a new propertyinput_gradients
in theNeuralNetwork
class.
Now
NeuralNetworkClassifier
extendsClassifierMixin
andNeuralNetworkRegressor
extendsRegressorMixin
from Scikit-Learn and rely on their methods for score calculation. This also adds an ability to pass sample weights as an optional parameter to the score methods.
Deprecation Notes¶
The valid values passed to the loss argument of the
TrainableModel
constructor were partially deprecated (i.e.loss='l1'
is replaced withloss='absolute_error'
andloss='l2'
is replaced withloss='squared_error'
). This affects instantiation of classes like theNeuralNetworkClassifier
. This change was made to reduce confusion that stems from using lowercase ‘l’ character which can be mistaken for a numeric ‘1’ or capital ‘I’. You should update your model instantiations by replacing ‘l1’ with ‘absolute_error’ and ‘l2’ with ‘squared_error’.
The
weights
property inTorchConnector
is deprecated in favor of theweight
property which is PyTorch compatible. By default, PyTorch layers exposeweight
properties to get access to the computed weights.
Bug Fixes¶
This fixes the exception that occurs when no
optimizer
argument is passed toNeuralNetworkClassifier
andNeuralNetworkRegressor
.
Fixes the computation of gradients in TorchConnector when a batch of input samples is provided.
TorchConnector now returns the correct input gradient dimensions during the backward pass in hybrid nn training.
Added a dedicated handling of
ComposedOp
as a operator inOpflowQNN
. In this case output shape is determined from the first operator in theComposedOp
instance.
Fix the dimensions of the gradient in the quantum generator for the qGAN training.