Ë
    ýÿæiÔ=  ã                   óþ   — d dl mZ d dlmZmZmZ d dlZd dlmZ d dlm	Z	 d dl
mZ d dlmZmZmZmZmZmZmZmZmZ d dlmZ d d	lmZ d d
lmZ d dlmZmZ esddgZ G d„ de«      Z  G d„ de«      Z! G d„ de«      Z"y)é    )ÚSequence)ÚAnyÚOptionalÚUnionN)ÚTensor)ÚLiteral)Ú_ClassificationTaskWrapper)	Ú_binary_confusion_matrix_formatÚ!_binary_hinge_loss_arg_validationÚ$_binary_hinge_loss_tensor_validationÚ_binary_hinge_loss_updateÚ_hinge_loss_computeÚ#_multiclass_confusion_matrix_formatÚ%_multiclass_hinge_loss_arg_validationÚ(_multiclass_hinge_loss_tensor_validationÚ_multiclass_hinge_loss_update)ÚMetric)ÚClassificationTaskNoMultilabel)Ú_MATPLOTLIB_AVAILABLE)Ú_AX_TYPEÚ_PLOT_OUT_TYPEzBinaryHingeLoss.plotzMulticlassHingeLoss.plotc                   óö   ‡ — e Zd ZU dZdZeed<   dZeed<   dZeed<   dZ	e
ed<   d	Ze
ed
<   eed<   eed<   	 	 	 ddedee   dededdf
ˆ fd„Zdededdfd„Zdefd„Z	 ddeeeee   f      dee   defd„Zˆ xZS )ÚBinaryHingeLossa'  Compute the mean `Hinge loss`_ typically used for Support Vector Machines (SVMs) for binary tasks.

    .. math::
        \text{Hinge loss} = \max(0, 1 - y \times \hat{y})

    Where :math:`y \in {-1, 1}` is the target, and :math:`\hat{y} \in \mathbb{R}` is the prediction.

    As input to ``forward`` and ``update`` the metric accepts the following input:

    - ``preds`` (:class:`~torch.Tensor`): A float tensor of shape ``(N, ...)``. Preds should be a tensor containing
      probabilities or logits for each observation. If preds has values outside [0,1] range we consider the input
      to be logits and will auto apply sigmoid per element.
    - ``target`` (:class:`~torch.Tensor`): An int tensor of shape ``(N, ...)``. Target should be a tensor containing
      ground truth labels, and therefore only contain {0,1} values (except if `ignore_index` is specified). The value
      1 always encodes the positive class.

    .. tip::
       Additional dimension ``...`` will be flattened into the batch dimension.

    As output to ``forward`` and ``compute`` the metric returns the following output:

    - ``bhl`` (:class:`~torch.Tensor`): A tensor containing the hinge loss.

    Args:
        squared:
            If True, this will compute the squared hinge loss. Otherwise, computes the regular hinge loss.
        ignore_index:
            Specifies a target value that is ignored and does not contribute to the metric calculation
        validate_args: bool indicating if input arguments and tensors should be validated for correctness.
            Set to ``False`` for faster computations.
        kwargs: Additional keyword arguments, see :ref:`Metric kwargs` for more info.

    Example:
        >>> from torchmetrics.classification import BinaryHingeLoss
        >>> preds = torch.tensor([0.25, 0.25, 0.55, 0.75, 0.75])
        >>> target = torch.tensor([0, 0, 1, 1, 1])
        >>> bhl = BinaryHingeLoss()
        >>> bhl(preds, target)
        tensor(0.6900)
        >>> bhl = BinaryHingeLoss(squared=True)
        >>> bhl(preds, target)
        tensor(0.6905)

    TÚis_differentiableFÚhigher_is_betterÚfull_state_updateç        Úplot_lower_boundç      ð?Úplot_upper_boundÚmeasuresÚtotalNÚsquaredÚignore_indexÚvalidate_argsÚkwargsÚreturnc                 ó  •— t        ‰| �  di |¤Ž |rt        ||«       || _        || _        || _        | j                  dt        j                  d«      d¬«       | j                  dt        j                  d«      d¬«       y )Nr!   r   Úsum©ÚdefaultÚdist_reduce_fxr"   r   © )	ÚsuperÚ__init__r   r%   r#   r$   Ú	add_stateÚtorchÚtensor)Úselfr#   r$   r%   r&   Ú	__class__s        €úv/Volumes/fast/ai/experiments/voice-extract-mac/.venv/lib/python3.12/site-packages/torchmetrics/classification/hinge.pyr/   zBinaryHingeLoss.__init__a   sn   ø€ ô 	‰ÑÑ"˜6Ò"ÙÜ-¨g°|ÔDØ*ˆÔØˆŒØ(ˆÔà�‰�z¬5¯<©<¸Ó+<ÈUˆÔSØ�‰�w¬¯©°Q«ÈˆÕNó    ÚpredsÚtargetc                 ó  — | j                   rt        ||| j                  «       t        ||d| j                  d¬«      \  }}t	        ||| j
                  «      \  }}| xj                  |z  c_        | xj                  |z  c_        y)úUpdate metric state.r   F)Ú	thresholdr$   Úconvert_to_labelsN)r%   r   r$   r
   r   r#   r!   r"   ©r3   r7   r8   r!   r"   s        r5   ÚupdatezBinaryHingeLoss.updater   sq   € à×ÒÜ0°¸À×@QÑ@QÔRÜ7Ø�6 S°t×7HÑ7HÐ\aô
‰ˆˆvô 4°E¸6À4Ç<Á<ÓP‰ˆ�%Ø�Š˜Ñ!�Ø�
Š
�eÑŽ
r6   c                 óB   — t        | j                  | j                  «      S ©zCompute metric.©r   r!   r"   ©r3   s    r5   ÚcomputezBinaryHingeLoss.compute}   ó   € ä" 4§=¡=°$·*±*Ó=Ð=r6   ÚvalÚaxc                 ó&   — | j                  ||«      S )a5  Plot a single or multiple values from the metric.

        Args:
            val: Either a single result from calling `metric.forward` or `metric.compute` or a list of these results.
                If no value is provided, will automatically call `metric.compute` and plot that result.
            ax: An matplotlib axis object. If provided will add plot to that axis

        Returns:
            Figure object and Axes object

        Raises:
            ModuleNotFoundError:
                If `matplotlib` is not installed

        .. plot::
            :scale: 75

            >>> # Example plotting a single value
            >>> from torch import rand, randint
            >>> from torchmetrics.classification import BinaryHingeLoss
            >>> metric = BinaryHingeLoss()
            >>> metric.update(rand(10), randint(2,(10,)))
            >>> fig_, ax_ = metric.plot()

        .. plot::
            :scale: 75

            >>> # Example plotting multiple values
            >>> from torch import rand, randint
            >>> from torchmetrics.classification import BinaryHingeLoss
            >>> metric = BinaryHingeLoss()
            >>> values = [ ]
            >>> for _ in range(10):
            ...     values.append(metric(rand(10), randint(2,(10,))))
            >>> fig_, ax_ = metric.plot(values)

        ©Ú_plot©r3   rE   rF   s      r5   ÚplotzBinaryHingeLoss.plot�   ó   € ðP �z‰z˜#˜rÓ"Ð"r6   )FNT©NN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   ÚboolÚ__annotations__r   r   r   Úfloatr    r   r   Úintr   r/   r>   rC   r   r   r   r   rK   Ú__classcell__©r4   s   @r5   r   r   *   sû   ø… ñ+ðZ #Ð�tÓ"Ø"Ð�dÓ"Ø#Ð�tÓ#Ø!Ð�eÓ!Ø!Ð�eÓ!àÓØƒMð Ø&*Ø"ñ	OàðOð ˜s‘mðOð ð	Oð
 ðOð 
õOð"	˜Fð 	¨Fð 	°tó 	ð>˜ó >ð
 _cñ(#Ø˜E &¨(°6Ñ*:Ð":Ñ;Ñ<ð(#ØIQÐRZÑI[ð(#à	÷(#r6   r   c                   ó  ‡ — e Zd ZU dZdZeed<   dZeed<   dZeed<   dZ	e
ed<   d	Ze
ed
<   dZeed<   eed<   eed<   	 	 	 	 d dededed   dee   dededdfˆ fd„Zdededdfd„Zdefd„Z	 d!deeeee   f      dee   defd„Zˆ xZS )"ÚMulticlassHingeLossaˆ  Compute the mean `Hinge loss`_ typically used for Support Vector Machines (SVMs) for multiclass tasks.

    The metric can be computed in two ways. Either, the definition by Crammer and Singer is used:

    .. math::
        \text{Hinge loss} = \max\left(0, 1 - \hat{y}_y + \max_{i \ne y} (\hat{y}_i)\right)

    Where :math:`y \in {0, ..., \mathrm{C}}` is the target class (where :math:`\mathrm{C}` is the number of classes),
    and :math:`\hat{y} \in \mathbb{R}^\mathrm{C}` is the predicted output per class. Alternatively, the metric can
    also be computed in one-vs-all approach, where each class is valued against all other classes in a binary fashion.

    As input to ``forward`` and ``update`` the metric accepts the following input:

    - ``preds`` (:class:`~torch.Tensor`): A float tensor of shape ``(N, C, ...)``. Preds should be a tensor
      containing probabilities or logits for each observation. If preds has values outside [0,1] range we consider
      the input to be logits and will auto apply softmax per sample.
    - ``target`` (:class:`~torch.Tensor`): An int tensor of shape ``(N, ...)``. Target should be a tensor containing
      ground truth labels, and therefore only contain values in the [0, n_classes-1] range (except if `ignore_index`
      is specified).

    .. tip::
       Additional dimension ``...`` will be flattened into the batch dimension.

    As output to ``forward`` and ``compute`` the metric returns the following output:

    - ``mchl`` (:class:`~torch.Tensor`): A tensor containing the multi-class hinge loss.

    Args:
        num_classes: Integer specifying the number of classes
        squared:
            If True, this will compute the squared hinge loss. Otherwise, computes the regular hinge loss.
        multiclass_mode:
            Determines how to compute the metric
        ignore_index:
            Specifies a target value that is ignored and does not contribute to the metric calculation
        validate_args: bool indicating if input arguments and tensors should be validated for correctness.
            Set to ``False`` for faster computations.
        kwargs: Additional keyword arguments, see :ref:`Metric kwargs` for more info.

    Example:
        >>> from torchmetrics.classification import MulticlassHingeLoss
        >>> preds = torch.tensor([[0.25, 0.20, 0.55],
        ...                       [0.55, 0.05, 0.40],
        ...                       [0.10, 0.30, 0.60],
        ...                       [0.90, 0.05, 0.05]])
        >>> target = torch.tensor([0, 1, 2, 0])
        >>> mchl = MulticlassHingeLoss(num_classes=3)
        >>> mchl(preds, target)
        tensor(0.9125)
        >>> mchl = MulticlassHingeLoss(num_classes=3, squared=True)
        >>> mchl(preds, target)
        tensor(1.1131)
        >>> mchl = MulticlassHingeLoss(num_classes=3, multiclass_mode='one-vs-all')
        >>> mchl(preds, target)
        tensor([0.8750, 1.1250, 1.1000])

    Tr   Fr   r   r   r   r   r    ÚClassÚplot_legend_namer!   r"   NÚnum_classesr#   Úmulticlass_mode©úcrammer-singerz
one-vs-allr$   r%   r&   r'   c                 ón  •— t        ‰| �  di |¤Ž |rt        ||||«       || _        || _        || _        || _        || _        | j                  d| j                  dk(  rt        j                  d«      nt        j                  |«      d¬«       | j                  dt        j                  d«      d¬«       y )	Nr!   r_   r   r)   r*   r"   r   r-   )r.   r/   r   r%   r\   r#   r]   r$   r0   r1   r2   Úzeros)r3   r\   r#   r]   r$   r%   r&   r4   s          €r5   r/   zMulticlassHingeLoss.__init__ñ   s¯   ø€ ô 	‰ÑÑ"˜6Ò"ÙÜ1°+¸wÈÐYeÔfØ*ˆÔØ&ˆÔØˆŒØ.ˆÔØ(ˆÔà�‰Øà×#Ñ#Ð'7Ò7ô —L‘L Ô%ä—‘Øóð !ð 	ô 	
ð 	�‰�w¬¯©°Q«ÈˆÕNr6   r7   r8   c                 ó6  — | j                   r"t        ||| j                  | j                  «       t	        ||| j                  d¬«      \  }}t        ||| j                  | j                  «      \  }}| xj                  |z  c_        | xj                  |z  c_	        y)r:   F)r<   N)
r%   r   r\   r$   r   r   r#   r]   r!   r"   r=   s        r5   r>   zMulticlassHingeLoss.update  s|   € à×ÒÜ4°U¸FÀD×DTÑDTÐVZ×VgÑVgÔhÜ;¸EÀ6È4×K\ÑK\ÐpuÔv‰ˆˆvÜ7¸¸vÀtÇ|Á|ÐUY×UiÑUiÓj‰ˆ�%Ø�Š˜Ñ!�Ø�
Š
�eÑŽ
r6   c                 óB   — t        | j                  | j                  «      S r@   rA   rB   s    r5   rC   zMulticlassHingeLoss.compute  rD   r6   rE   rF   c                 ó&   — | j                  ||«      S )a€  Plot a single or multiple values from the metric.

        Args:
            val: Either a single result from calling `metric.forward` or `metric.compute` or a list of these results.
                If no value is provided, will automatically call `metric.compute` and plot that result.
            ax: An matplotlib axis object. If provided will add plot to that axis

        Returns:
            Figure object and Axes object

        Raises:
            ModuleNotFoundError:
                If `matplotlib` is not installed

        .. plot::
            :scale: 75

            >>> # Example plotting a single value per class
            >>> from torch import randint, randn
            >>> from torchmetrics.classification import MulticlassHingeLoss
            >>> metric = MulticlassHingeLoss(num_classes=3)
            >>> metric.update(randn(20, 3), randint(3, (20,)))
            >>> fig_, ax_ = metric.plot()

        .. plot::
            :scale: 75

            >>> # Example plotting a multiple values per class
            >>> from torch import randint, randn
            >>> from torchmetrics.classification import MulticlassHingeLoss
            >>> metric = MulticlassHingeLoss(num_classes=3)
            >>> values = []
            >>> for _ in range(20):
            ...     values.append(metric(randn(20, 3), randint(3, (20,))))
            >>> fig_, ax_ = metric.plot(values)

        rH   rJ   s      r5   rK   zMulticlassHingeLoss.plot  rL   r6   )Fr_   NTrM   )rN   rO   rP   rQ   r   rR   rS   r   r   r   rT   r    r[   Ústrr   rU   r   r   r   r/   r>   rC   r   r   r   r   rK   rV   rW   s   @r5   rY   rY   ¬   s%  ø… ñ8ðt #Ð�tÓ"Ø"Ð�dÓ"Ø#Ð�tÓ#Ø!Ð�eÓ!Ø!Ð�eÓ!Ø#Ð�cÓ#àÓØƒMð
 ØCSØ&*Ø"ñOàðOð ðOð !Ð!?Ñ@ð	Oð
 ˜s‘mðOð ðOð ðOð 
õOð:˜Fð ¨Fð °tó ð>˜ó >ð
 _cñ(#Ø˜E &¨(°6Ñ*:Ð":Ñ;Ñ<ð(#ØIQÐRZÑI[ð(#à	÷(#r6   rY   c                   ól   — e Zd ZdZ	 	 	 	 	 dded    ded   dee   dedeed	      d
ee   dede	de
fd„Zy)Ú	HingeLossaî  Compute the mean `Hinge loss`_ typically used for Support Vector Machines (SVMs).

    This function is a simple wrapper to get the task specific versions of this metric, which is done by setting the
    ``task`` argument to either ``'binary'`` or ``'multiclass'``. See the documentation of
    :class:`~torchmetrics.classification.BinaryHingeLoss` and :class:`~torchmetrics.classification.MulticlassHingeLoss`
    for the specific details of each argument influence and examples.

    Legacy Example:
        >>> from torch import tensor
        >>> target = tensor([0, 1, 1])
        >>> preds = tensor([0.5, 0.7, 0.1])
        >>> hinge = HingeLoss(task="binary")
        >>> hinge(preds, target)
        tensor(0.9000)

        >>> target = tensor([0, 1, 2])
        >>> preds = tensor([[-1.0, 0.9, 0.2], [0.5, -1.1, 0.8], [2.2, -0.5, 0.3]])
        >>> hinge = HingeLoss(task="multiclass", num_classes=3)
        >>> hinge(preds, target)
        tensor(1.5551)

        >>> target = tensor([0, 1, 2])
        >>> preds = tensor([[-1.0, 0.9, 0.2], [0.5, -1.1, 0.8], [2.2, -0.5, 0.3]])
        >>> hinge = HingeLoss(task="multiclass", num_classes=3, multiclass_mode="one-vs-all")
        >>> hinge(preds, target)
        tensor([1.3743, 1.1945, 1.2359])

    NÚclsÚtask)ÚbinaryÚ
multiclassr\   r#   r]   r^   r$   r%   r&   r'   c                 óh  — t        j                  |«      }|j                  ||dœ«       |t         j                  k(  rt	        |fi |¤ŽS |t         j
                  k(  rIt        |t        «      st        dt        |«      › d�«      ‚|dvrt        d|› d�«      ‚t        |||fi |¤ŽS t        d|› d�«      ‚)	zInitialize task metric.)r$   r%   z+`num_classes` is expected to be `int` but `z was passed.`r^   zQ`multiclass_mode` is expected to be one of 'crammer-singer' or 'one-vs-all' but `z` was passed.zUnsupported task `Ú`)r   Úfrom_strr>   ÚBINARYr   Ú
MULTICLASSÚ
isinstancerU   Ú
ValueErrorÚtyperY   )rh   ri   r\   r#   r]   r$   r%   r&   s           r5   Ú__new__zHingeLoss.__new__d  sÎ   € ô .×6Ñ6°tÓ<ˆØ�‰ |ÀmÑTÔUØÔ1×8Ñ8Ò8Ü" 7Ñ5¨fÑ5Ð5ØÔ1×<Ñ<Ò<Ü˜k¬3Ô/Ü Ð#NÌtÐT_ÓO`ÐNaÐanÐ!oÓpÐpØÐ&FÑFÜ ðØ'Ð(¨ð7óð ô ' {°G¸_ÑWÐPVÑWÐWÜÐ-¨d¨V°1Ð5Ó6Ð6r6   )NFr_   NT)rN   rO   rP   rQ   rs   r   r   rU   rR   r   r   rt   r-   r6   r5   rg   rg   F  s’   „ ñð@ &*ØØM]Ø&*Ø"ñ7Ø�+Ñð7àÐ,Ñ-ð7ð ˜c‘]ð7ð ð	7ð
 " 'Ð*HÑ"IÑJð7ð ˜s‘mð7ð ð7ð ð7ð 
ô7r6   rg   )#Úcollections.abcr   Útypingr   r   r   r1   r   Útyping_extensionsr   Ú torchmetrics.classification.baser	   Ú,torchmetrics.functional.classification.hinger
   r   r   r   r   r   r   r   r   Útorchmetrics.metricr   Útorchmetrics.utilities.enumsr   Útorchmetrics.utilities.importsr   Útorchmetrics.utilities.plotr   r   Ú__doctest_skip__r   rY   rg   r-   r6   r5   Ú<module>r      ss   ðõ %ß 'Ñ 'ã Ý Ý %å G÷
÷ 
õ 
õ 'Ý GÝ @ß @áØ.Ð0JÐKÐô#�fô #ôDW#˜&ô W#ôt67Ð*õ 67r6   