• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

qiskit-community / qiskit-machine-learning / 8545395904

03 Apr 2024 08:55PM CUT coverage: 92.711% (+0.08%) from 92.636%
8545395904

Pull #793

github

web-flow
Merge 240d02fb3 into 97513d377
Pull Request #793: Patches einsum dimensionality in `torch_connector` - #716

25 of 25 new or added lines in 1 file covered. (100.0%)

10 existing lines in 1 file now uncovered.

1908 of 2058 relevant lines covered (92.71%)

0.93 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

92.0
/qiskit_machine_learning/utils/loss_functions/kernel_loss_functions.py
1
# This code is part of a Qiskit project.
2
#
3
# (C) Copyright IBM 2021, 2023.
4
#
5
# This code is licensed under the Apache License, Version 2.0. You may
6
# obtain a copy of this license in the LICENSE.txt file in the root directory
7
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
8
#
9
# Any modifications or derivative works of this code must retain this
10
# copyright notice, and modified files need to carry a notice indicating
11
# that they have been altered from the originals.
12

13
""" Kernel Loss utilities """
1✔
14

15
from abc import ABC, abstractmethod
1✔
16
from typing import Sequence
1✔
17

18
import numpy as np
1✔
19
from sklearn.svm import SVC
1✔
20

21
# Prevent circular dependencies caused from type checking
22
from ...kernels import TrainableKernel
1✔
23

24

25
class KernelLoss(ABC):
1✔
26
    """
27
    Abstract base class for computing the loss of a kernel function.
28
    Unlike many loss functions, which only take into account the labels and predictions
29
    of a model, kernel loss functions may be a function of internal model parameters or
30
    quantities that are generated during training.
31
    """
32

33
    def __call__(
1✔
34
        self,
35
        parameter_values: Sequence[float],
36
        quantum_kernel: TrainableKernel,
37
        data: np.ndarray,
38
        labels: np.ndarray,
39
    ) -> float:
40
        """
41
        This method calls the ``evaluate`` method. This is a convenient method to compute loss.
42
        """
43
        return self.evaluate(parameter_values, quantum_kernel, data, labels)
×
44

45
    @abstractmethod
1✔
46
    def evaluate(
1✔
47
        self,
48
        parameter_values: Sequence[float],
49
        quantum_kernel: TrainableKernel,
50
        data: np.ndarray,
51
        labels: np.ndarray,
52
    ) -> float:
53
        """
54
        An abstract method for evaluating the loss of a kernel function on a labeled dataset.
55

56
        Args:
57
            parameter_values: An array of values to assign to the user params
58
            quantum_kernel: A trainable quantum kernel object to evaluate
59
            data: An ``(N, M)`` matrix containing the data
60
                    ``N = # samples, M = dimension of data``
61
            labels: A length-N array containing the truth labels
62

63
        Returns:
64
            A loss value
65
        """
66
        raise NotImplementedError
×
67

68

69
class SVCLoss(KernelLoss):
1✔
70
    r"""
71
    This class provides a kernel loss function for classification tasks by fitting an ``SVC`` model
72
    from scikit-learn. Given training samples, :math:`x_{i}`, with binary labels, :math:`y_{i}`,
73
    and a kernel, :math:`K_{θ}`, parameterized by values, :math:`θ`, the loss is defined as:
74

75
    .. math::
76

77
        SVCLoss = \sum_{i} a_i - 0.5 \sum_{i,j} a_i a_j y_{i} y_{j} K_θ(x_i, x_j)
78

79
    where :math:`a_i` are the optimal Lagrange multipliers found by solving the standard SVM
80
    quadratic program. Note that the hyper-parameter ``C`` for the soft-margin penalty can be
81
    specified through the keyword args.
82

83
    Minimizing this loss over the parameters, :math:`θ`, of the kernel is equivalent to maximizing a
84
    weighted kernel alignment, which in turn yields the smallest upper bound to the SVM
85
    generalization error for a given parameterization.
86

87
    See https://arxiv.org/abs/2105.03406 for further details.
88
    """
89

90
    def __init__(self, **kwargs):
1✔
91
        """
92
        Args:
93
            **kwargs: Arbitrary keyword arguments to pass to SVC constructor within
94
                      SVCLoss evaluation.
95
        """
96
        self.kwargs = kwargs
1✔
97

98
    def evaluate(
1✔
99
        self,
100
        parameter_values: Sequence[float],
101
        quantum_kernel: TrainableKernel,
102
        data: np.ndarray,
103
        labels: np.ndarray,
104
    ) -> float:
105
        # Bind training parameters
106
        quantum_kernel.assign_training_parameters(parameter_values)
1✔
107

108
        # Get estimated kernel matrix
109
        kmatrix = quantum_kernel.evaluate(np.array(data))
1✔
110

111
        # Train a quantum support vector classifier
112
        svc = SVC(kernel="precomputed", **self.kwargs)
1✔
113
        svc.fit(kmatrix, labels)
1✔
114

115
        # Get dual coefficients
116
        dual_coefs = svc.dual_coef_[0]
1✔
117

118
        # Get support vectors
119
        support_vecs = svc.support_
1✔
120

121
        # Prune kernel matrix of non-support-vector entries
122
        kmatrix = kmatrix[support_vecs, :][:, support_vecs]
1✔
123

124
        # Calculate loss
125
        loss = np.sum(np.abs(dual_coefs)) - (0.5 * (dual_coefs.T @ kmatrix @ dual_coefs))
1✔
126

127
        return loss
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc