o
    oi                     @   sp   d dl 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mZ d dlmZmZmZ G dd deZdS )	    )AnyDictListOptionalTupleUnion)random_generator)MixAugmentationBaseV2)DataKeyDType)Tensorstackzerosc                       s  e Zd ZdZ					ddeeeeeef f  de	dede	d	ee
eeeef   d
df fddZ	ddedeeef deeeef  d
efddZ	ddedeeef deeeef  d
efddZ	ddedeeef deeeef  d
efddZ  ZS )RandomMixUpV2a
  Apply MixUp augmentation to a batch of tensor images.

    .. image:: _static/img/RandomMixUpV2.png

    Implementation for `mixup: BEYOND EMPIRICAL RISK MINIMIZATION` :cite:`zhang2018mixup`.

    The function returns (inputs, labels), in which the inputs is the tensor that contains the mixup images
    while the labels is a :math:`(B, 3)` tensor that contains (label_batch, label_permuted_batch, lambda) for
    each image.

    The implementation is on top of the following repository:
    `https://github.com/hongyi-zhang/mixup/blob/master/cifar/utils.py
    <https://github.com/hongyi-zhang/mixup/blob/master/cifar/utils.py>`_.

    The loss and accuracy are computed as:

    .. code-block:: python

        def loss_mixup(y, logits):
            criterion = F.cross_entropy
            loss_a = criterion(logits, y[:, 0].long(), reduction='none')
            loss_b = criterion(logits, y[:, 1].long(), reduction='none')
            return ((1 - y[:, 2]) * loss_a + y[:, 2] * loss_b).mean()

    .. code-block:: python

        def acc_mixup(y, logits):
            pred = torch.argmax(logits, dim=1).to(y.device)
            return (1 - y[:, 2]) * pred.eq(y[:, 0]).float() + y[:, 2] * pred.eq(y[:, 1]).float()

    Args:
        p: probability for applying an augmentation to a batch. This param controls the augmentation
                   probabilities batch-wisely.
        lambda_val: min-max value of mixup strength. Default is 0-1.
        same_on_batch: apply the same transformation across the batch.
            This flag will not maintain permutation order.
        keepdim: whether to keep the output shape the same as input (True) or broadcast it
                        to the batch form (False).

    Inputs:
        - Input image tensors, shape of :math:`(B, C, H, W)`.
        - Label: raw labels, shape of :math:`(B)`.

    Returns:
        Tuple[Tensor, Tensor]:
        - Adjusted image, shape of :math:`(B, C, H, W)`.
        - Raw labels, permuted labels and lambdas for each mix, shape of :math:`(B, 3)`.

    Note:
        This implementation would randomly mixup images in a batch. Ideally, the larger batch size would be preferred.

    Examples:
        >>> rng = torch.manual_seed(1)
        >>> input = torch.rand(2, 1, 3, 3)
        >>> label = torch.tensor([0, 1])
        >>> mixup = RandomMixUpV2(data_keys=["input", "class"])
        >>> mixup(input, label)
        [tensor([[[[0.7576, 0.2793, 0.4031],
                  [0.7347, 0.0293, 0.7999],
                  [0.3971, 0.7544, 0.5695]]],
        <BLANKLINE>
        <BLANKLINE>
                [[[0.4388, 0.6387, 0.5247],
                  [0.6826, 0.3051, 0.4635],
                  [0.4550, 0.5725, 0.4980]]]]), tensor([[0.0000, 0.0000, 0.1980],
                [1.0000, 1.0000, 0.4162]])]

    NF      ?
lambda_valsame_on_batchpkeepdim	data_keysreturnc                    s*   t  jd||||d tj||d| _d S )Nr   )r   p_batchr   r   r   )r   )super__init__rgMixupGenerator_param_generator)selfr   r   r   r   r   	__class__ U/home/ubuntu/.local/lib/python3.10/site-packages/kornia/augmentation/_2d/mix/mixup.pyr   `   s   zRandomMixUpV2.__init__inputparamsmaybe_flagsc                 C   sT   |j d|d |jd}|d dddd||j}|d|  ||  }|S )Nr   mixup_pairsdimindexmixup_lambdas   )index_selecttodeviceview	expand_as)r   r"   r#   r$   input_permutelaminputsr    r    r!   apply_transformk   s   "zRandomMixUpV2.apply_transformc                 C   st   t |j|jtt|d  d|j|jtt|d  dtt|f|jtt|d  dgd}|S )Ndtyper.   r5   r*   )	r   r-   r.   r   to_torchintitemr   len)r   r"   r#   r$   
out_labelsr    r    r!   apply_non_transform_classt   s     &z'RandomMixUpV2.apply_non_transform_classc              
   C   s   |j d|d |jd}t|j|jtt|d  d|j|jtt|d  d|d j|jtt|d  dgd}|S )Nr   r%   r&   r5   r6   r)   r*   )r,   r-   r.   r   r   r7   r8   r9   )r   r"   r#   r$   labels_permuter;   r    r    r!   apply_transform_class   s     $z#RandomMixUpV2.apply_transform_class)NFr   FN)N)__name__
__module____qualname____doc__r   r   r   r   floatboolr   strr8   r
   r   r   r   r4   r<   r>   __classcell__r    r    r   r!   r      sd    G





r   N)typingr   r   r   r   r   r   kornia.augmentationr   r    kornia.augmentation._2d.mix.baser	   kornia.constantsr
   r   kornia.corer   r   r   r   r    r    r    r!   <module>   s    