o
    yi,                     @   s   d dl mZmZ d dl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 G dd deZG d	d
 d
eZG dd dZdS )    )AnyOptionalN)Tensor)Literal)	_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)Metricc                       s   e Zd ZU dZdZeed< dZeed< dZeed< 			dded	e	e
 d
ededdf
 fddZdededdfddZdefddZ  ZS )BinaryHingeLossa>  Computes the mean `Hinge loss`_ typically used for Support Vector Machines (SVMs) for binary tasks. It is
    defined as:

    .. 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.

    .. note::
       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_updateNsquaredignore_indexvalidate_argskwargsreturnc                    sb   t  jdi | |rt|| || _|| _|| _| jdtddd | jdtddd d S )Nmeasures        sumdefaultdist_reduce_fxtotalr    )	super__init__r   r   r   r   	add_statetorchtensor)selfr   r   r   r   	__class__r    U/home/ubuntu/.local/lib/python3.10/site-packages/torchmetrics/classification/hinge.pyr"   S   s   
zBinaryHingeLoss.__init__predstargetc                 C   s^   | j r
t||| j t||d| jdd\}}t||| j\}}|  j|7  _|  j|7  _d S )Nr   F)	thresholdr   convert_to_labels)r   r   r   r   r	   r   r   r   r&   r*   r+   r   r   r    r    r)   updated   s   
zBinaryHingeLoss.updatec                 C      t | j| jS Nr
   r   r   r&   r    r    r)   computen      zBinaryHingeLoss.compute)FNT)__name__
__module____qualname____doc__r   bool__annotations__r   r   r   intr   r"   r   r/   r4   __classcell__r    r    r'   r)   r   "   s*   
 ,
r   c                       s   e Zd ZU dZdZeed< dZeed< dZeed< 				dd	e	d
ede
d dee	 dededdf fddZdededdfddZdefddZ  ZS )MulticlassHingeLossa  Computes 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).

    .. note::
       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 specifing 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   crammer-singerNnum_classesr   multiclass_moder?   z
one-vs-allr   r   r   r   c                    s   t  jdi | |rt|||| || _|| _|| _|| _|| _| jd| jdkr.t	
dnt	|dd | jdt	
ddd d S )	Nr   r?   r   r   r   r   r   r    )r!   r"   r   r   r@   r   rA   r   r#   r$   r%   zeros)r&   r@   r   rA   r   r   r   r'   r    r)   r"      s$   	

	zMulticlassHingeLoss.__init__r*   r+   c                 C   sd   | j rt||| j| j t||| jdd\}}t||| j| j\}}|  j|7  _|  j	|7  _	d S )NF)r-   )
r   r   r@   r   r   r   r   rA   r   r   r.   r    r    r)   r/      s   zMulticlassHingeLoss.updatec                 C   r0   r1   r2   r3   r    r    r)   r4      r5   zMulticlassHingeLoss.compute)Fr?   NT)r6   r7   r8   r9   r   r:   r;   r   r   r<   r   r   r   r"   r   r/   r4   r=   r    r    r'   r)   r>   r   s4   
 8r>   c                   @   sZ   e Zd ZdZ					dded dee d	ed
eed  dee dedede	fddZ
dS )	HingeLossa  Computes 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
    :mod:`BinaryHingeLoss` and :mod:`MulticlassHingeLoss` for the specific details of
    each argument influence and examples.

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

        >>> target = torch.tensor([0, 1, 2])
        >>> preds = torch.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 = torch.tensor([0, 1, 2])
        >>> preds = torch.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])
    NFr?   Ttask)binary
multiclassr@   r   rA   rB   r   r   r   r   c                 K   sb   | t||d |dkrt|fi |S |dkr*t|ts J t|||fi |S td| )N)r   r   rF   rG   z[Expected argument `task` to either be `'binary'`, `'multiclass'` or `'multilabel'` but got )r/   dictr   
isinstancer<   r>   
ValueError)clsrE   r@   r   rA   r   r   r   r    r    r)   __new__   s   
zHingeLoss.__new__)NFr?   NT)r6   r7   r8   r9   r   r   r<   r:   r   r   rL   r    r    r    r)   rD      s0    
	rD   )typingr   r   r$   r   typing_extensionsr   ,torchmetrics.functional.classification.hinger   r   r   r	   r
   r   r   r   r   torchmetrics.metricr   r   r>   rD   r    r    r    r)   <module>   s   ,Pf