SamplerQNN

class SamplerQNN(*, circuit, sampler=None, input_params=None, weight_params=None, sparse=False, interpret=None, output_shape=None, gradient=None, input_gradients=False, pass_manager=None)[source]

Bases: NeuralNetwork

A neural network implementation based on the Sampler primitive.

The SamplerQNN is a neural network that takes in a parametrized quantum circuit with designated parameters for input data and/or weights and translates the quasi-probabilities estimated by the Sampler primitive into predicted classes. Quite often, a combined quantum circuit is used. Such a circuit is built from two circuits: a feature map, it provides input parameters for the network, and an ansatz (weight parameters). In this case a QNNCircuit can be passed as circuit to simplify the composition of a feature map and ansatz. If a QNNCircuit is passed as circuit, the input and weight parameters do not have to be provided, because these two properties are taken from the QNNCircuit.

The output can be set up in different formats, and an optional post-processing step can be used to interpret the sampler’s output in a particular context (e.g. mapping the resulting bitstring to match the number of classes).

In this example the network maps the output of the quantum circuit to two classes via a custom interpret function:

from qiskit import QuantumCircuit
from qiskit.circuit.library import ZZFeatureMap, RealAmplitudes
from qiskit_machine_learning.circuit.library import QNNCircuit

from qiskit_machine_learning.neural_networks import SamplerQNN

num_qubits = 2

def parity(x):
    return f"{bin(x)}".count("1") % 2

# Using the QNNCircuit:
# Create a parameterized 2 qubit circuit composed of the default ZZFeatureMap feature map
# and RealAmplitudes ansatz.
qnn_qc = QNNCircuit(num_qubits)

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])

# Explicitly specifying the ansatz and feature map:
feature_map = ZZFeatureMap(feature_dimension=num_qubits)
ansatz = RealAmplitudes(num_qubits=num_qubits)

qc = QuantumCircuit(num_qubits)
qc.compose(feature_map, inplace=True)
qc.compose(ansatz, inplace=True)

qnn = SamplerQNN(
    circuit=qc,
    input_params=feature_map.parameters,
    weight_params=ansatz.parameters,
    interpret=parity,
    output_shape=2
)

qnn.forward(input_data=[1, 2], weights=[1, 2, 3, 4, 5, 6, 7, 8])

The following attributes can be set via the constructor but can also be read and updated once the SamplerQNN object has been constructed.

sampler

The sampler primitive used to compute the neural network’s results.

Type:

BaseSampler

gradient

A sampler gradient to be used for the backward pass.

Type:

BaseSamplerGradient

Parameters:
  • circuit (QuantumCircuit) – The parametrized quantum circuit that generates the samples of this network. If a QNNCircuit is passed, the input_params and weight_params do not have to be provided, because these two properties are taken from the QNNCircuit.

  • sampler (BaseSampler | None) –

    The sampler primitive used to compute the neural network’s results. If None is given, a default instance of the reference sampler defined by Sampler will be used.

    Warning

    The assignment sampler=None defaults to using Sampler, which points to a deprecated Sampler V1 (as of Qiskit 1.2). SamplerQNN will adopt Sampler V2 as default no later than Qiskit Machine Learning 0.9.

  • input_params (Sequence[Parameter] | None) – The parameters of the circuit corresponding to the input. If a QNNCircuit is provided the input_params value here is ignored. Instead, the value is taken from the QNNCircuit input_parameters.

  • weight_params (Sequence[Parameter] | None) – The parameters of the circuit corresponding to the trainable weights. If a QNNCircuit is provided the weight_params value here is ignored. Instead, the value is taken from the QNNCircuit weight_parameters.

  • sparse (bool) – Returns whether the output is sparse or not.

  • interpret (Callable[[int], int | tuple[int, ...]] | None) – A callable that maps the measured integer to another unsigned integer or tuple of unsigned integers. These are used as new indices for the (potentially sparse) output array. If no interpret function is passed, then an identity function will be used by this neural network.

  • output_shape (int | tuple[int, ...] | None) – The output shape of the custom interpretation. For SamplerV1, it is ignored if no custom interpret method is provided where the shape is taken to be 2^circuit.num_qubits.

  • gradient (BaseSamplerGradient | None) – An optional sampler gradient to be used for the backward pass. If None is given, a default instance of ParamShiftSamplerGradient will be used.

  • input_gradients (bool) – Determines whether to compute gradients with respect to input data. Note that this parameter is False by default, and must be explicitly set to True for a proper gradient computation when using TorchConnector.

  • pass_manager (BasePassManager | None) – The pass manager to transpile the circuits, if necessary. Defaults to None, as some primitives do not need transpiled circuits.

Raises:

QiskitMachineLearningError – Invalid parameter values.

Attributes

circuit

Returns the underlying quantum circuit.

input_gradients

Returns whether gradients with respect to input data are computed by this neural network in the backward method or not. By default such gradients are not computed.

input_params

Returns the list of input parameters.

interpret

Returns interpret function to be used by the neural network. If it is not set in the constructor or can not be implicitly derived, then None is returned.

num_inputs

Returns the number of input features.

num_weights

Returns the number of trainable weights.

output_shape

Returns the output shape.

sparse

Returns whether the output is sparse or not.

weight_params

Returns the list of trainable weights parameters.

Methods

backward(input_data, weights)

Backward pass of the network.

Parameters:
  • input_data (float | list[float] | ndarray | None) – input data of the shape (num_inputs). In case of a single scalar input it is directly cast to and interpreted like a one-element array.

  • weights (float | list[float] | ndarray | None) – trainable weights of the shape (num_weights). In case of a single scalar weight

  • array. (it is directly cast to and interpreted like a one-element)

Returns:

The result of the neural network of the backward pass, i.e., a tuple with the gradients for input and weights of shape (output_shape, num_input) and (output_shape, num_weights), respectively.

Return type:

tuple[ndarray | SparseArray | None, ndarray | SparseArray | None]

forward(input_data, weights)

Forward pass of the network.

Parameters:
  • input_data (float | list[float] | ndarray | None) – input data of the shape (num_inputs). In case of a single scalar input it is directly cast to and interpreted like a one-element array.

  • weights (float | list[float] | ndarray | None) – trainable weights of the shape (num_weights). In case of a single scalar weight it is directly cast to and interpreted like a one-element array.

Returns:

The result of the neural network of the shape (output_shape).

Return type:

ndarray | SparseArray

set_interpret(interpret=None, output_shape=None)[source]

Change ‘interpret’ and corresponding ‘output_shape’.

Parameters:
  • interpret (Callable[[int], int | tuple[int, ...]] | None) – A callable that maps the measured integer to another unsigned integer or tuple of unsigned integers. See constructor for more details.

  • output_shape (int | tuple[int, ...] | None) – The output shape of the custom interpretation. It is ignored if no custom interpret method is provided where the shape is taken to be 2^circuit.num_qubits.