o
    پi>                     @   sh   d Z ddlZddlZdddZdddZdd	d
ZdddZdddZG dd dZ	G dd de	Z
dS )aY   Mixup and Cutmix

Papers:
mixup: Beyond Empirical Risk Minimization (https://arxiv.org/abs/1710.09412)

CutMix: Regularization Strategy to Train Strong Classifiers with Localizable Features (https://arxiv.org/abs/1905.04899)

Code Reference:
CutMix: https://github.com/clovaai/CutMix-PyTorch

Hacked together by / Copyright 2019, Ross Wightman
    N      ?        c                 C   s8   |   dd} tj|  d |f|| jdd| |S )N   r   )device)longviewtorchfullsizer   scatter_)xnum_classeson_value	off_value r   C/home/ubuntu/.local/lib/python3.10/site-packages/timm/data/mixup.pyone_hot   s   (r   c                 C   sN   || }d| | }t | |||d}t | d|||d}|| |d|   S )Nr   )r   r   r   )r   flip)targetr   lam	smoothingr   r   y1y2r   r   r   mixup_target   s
   r   c                 C   s   t d| }| dd \}}t|| t|| }}t|| t|| }	}
t jjd|	 ||	 |d}t jjd|
 ||
 |d}t ||d  d|}t ||d  d|}t ||d  d|}t ||d  d|}||||fS )a   Standard CutMix bounding-box
    Generates a random square bbox based on lambda value. This impl includes
    support for enforcing a border margin as percent of bbox dimensions.

    Args:
        img_shape (tuple): Image shape as tuple
        lam (float): Cutmix lambda value
        margin (float): Percentage of bbox dimension to enforce as margin (reduce amount of box outside image)
        count (int): Number of bbox to generate
    r   Nr   r      )npsqrtintrandomrandintclip)	img_shaper   margincountratioimg_himg_wcut_hcut_wmargin_ymargin_xcycxylyhxlxhr   r   r   	rand_bbox   s   r4   c                 C   s   t |dksJ | dd \}}tjjt||d  t||d  |d}tjjt||d  t||d  |d}tjjd|| |d}tjjd|| |d}|| }	|| }
||	||
fS )a   Min-Max CutMix bounding-box
    Inspired by Darknet cutmix impl, generates a random rectangular bbox
    based on min/max percent values applied to each dimension of the input image.

    Typical defaults for minmax are usually in the  .2-.3 for min and .8-.9 range for max.

    Args:
        img_shape (tuple): Image shape as tuple
        minmax (tuple or list): Min and max bbox ratios (as percent of image size)
        count (int): Number of bbox to generate
    r   r   Nr   r   r   )lenr   r!   r"   r    )r$   minmaxr&   r(   r)   r*   r+   r0   r2   yuxur   r   r   rand_bbox_minmax6   s   **r9   Tc           
      C   s~   |durt | ||d\}}}}nt| ||d\}}}}|s!|dur7|| ||  }	d|	t| d | d    }||||f|fS )z0 Generate bbox and apply lambda correction.
    N)r&   r   r   r   )r9   r4   float)
r$   r   ratio_minmaxcorrect_lamr&   r0   r7   r2   r8   	bbox_arear   r   r   cutmix_bbox_and_lamM   s   r>   c                   @   sN   e Zd ZdZ			dd
dZdd Zdd Zdd Zdd Zdd Z	dd Z
dS )Mixupas   Mixup/Cutmix that applies different params to each element or whole batch

    Args:
        mixup_alpha (float): mixup alpha value, mixup is active if > 0.
        cutmix_alpha (float): cutmix alpha value, cutmix is active if > 0.
        cutmix_minmax (List[float]): cutmix min/max image ratio, cutmix is active and uses this vs alpha if not None.
        prob (float): probability of applying mixup or cutmix per batch or element
        switch_prob (float): probability of switching to cutmix instead of mixup when both are active
        mode (str): how to apply mixup/cutmix params (per 'batch', 'pair' (pair of elements), 'elem' (element)
        correct_lam (bool): apply lambda correction when cutmix bbox clipped by image borders
        label_smoothing (float): apply label smoothing to the mixed target tensor
        num_classes (int): number of classes for target
    r   r   N      ?batchT皙?  c
           
      C   sb   || _ || _|| _| jd urt| jdksJ d| _|| _|| _|| _|	| _|| _|| _	d| _
d S )Nr   r   T)mixup_alphacutmix_alphacutmix_minmaxr5   mix_probswitch_problabel_smoothingr   moder<   mixup_enabled)
selfrD   rE   rF   probrH   rJ   r<   rI   r   r   r   r   __init__h   s   

zMixup.__init__c              	   C   s  t j|t jd}t j|td}| jr~| jdkr?| jdkr?t j	|| j
k }t |t jj| j| j|dt jj| j| j|d}n-| jdkrPt jj| j| j|d}n| jdkrht j|td}t jj| j| j|d}nJ dt t j	|| jk |t j|}||fS )Ndtyper   r   FROne of mixup_alpha > 0., cutmix_alpha > 0., cutmix_minmax not None should be true.)r   onesfloat32zerosboolrK   rD   rE   r!   randrH   wherebetarG   astype)rL   
batch_sizer   
use_cutmixlam_mixr   r   r   _params_per_elemy   s$   

$zMixup._params_per_elemc                 C   s   d}d}| j r^tj | jk r^| jdkr6| jdkr6tj | jk }|r,tj| j| jntj| j| j}n$| jdkrEtj| j| j}n| jdkrVd}tj| j| j}nJ dt	|}||fS )Nr   Fr   TrQ   )
rK   r   r!   rV   rG   rD   rE   rH   rX   r:   )rL   r   r[   r\   r   r   r   _params_per_batch   s    

zMixup._params_per_batchc                 C   s   t |}| |\}}| }t|D ]X}|| d }|| }|dkrk|| r[t|| j|| j| jd\\}	}
}}}|| d d |	|
||f || d d |	|
||f< |||< q|| | || d|   ||< qtj	||j
|jddS )Nr   r   r;   r<   r   rP   )r5   r]   cloneranger>   shaperF   r<   r	   tensorr   rP   	unsqueezerL   r   rZ   	lam_batchr[   x_origijr   r0   r1   r2   r3   r   r   r   	_mix_elem   s    8
 zMixup._mix_elemc                 C   sj  t |}| |d \}}| }t|d D ]}|| d }|| }|dkr|| r{t|| j|| j| jd\\}	}
}}}|| d d |	|
||f || d d |	|
||f< || d d |	|
||f || d d |	|
||f< |||< q|| | || d|   ||< || | || d|   ||< qt	||d d d f}t
j||j|jddS )Nr   r   r   r_   r   r`   )r5   r]   ra   rb   r>   rc   rF   r<   r   concatenater	   rd   r   rP   re   rf   r   r   r   	_mix_pair   s&   88
  zMixup._mix_pairc           	      C   s   |   \}}|dkrdS |rBt|j|| j| jd\\}}}}}|dd d d d ||||f |d d d d ||||f< |S |dd| }||| |S )Nr   r_   r   )r^   r>   rc   rF   r<   r   mul_add_)	rL   r   r   r[   r0   r1   r2   r3   	x_flippedr   r   r   
_mix_batch   s   BzMixup._mix_batchc                 C   sh   t |d dksJ d| jdkr| |}n| jdkr"| |}n| |}t|| j|| j}||fS )Nr   r   )Batch size should be even when using thiselempair)r5   rJ   rk   rm   rq   r   r   rI   )rL   r   r   r   r   r   r   __call__   s   


zMixup.__call__)	r   r   Nr   r@   rA   TrB   rC   )__name__
__module____qualname____doc__rN   r]   r^   rk   rm   rq   ru   r   r   r   r   r?   Z   s    
r?   c                   @   s4   e Zd ZdZdddZdd Zdd Zdd
dZd	S )FastCollateMixupz Fast Collate w/ Mixup/Cutmix that applies different params to each element or whole batch

    A Mixup impl that's performed while collating the batches.
    Fc              	   C   s  t |}|r
|d n|}t ||ksJ | |\}}t|d d tj}t|D ]}	||	 d }
||	 }||	 d }|dkr||	 r|sO|rK| n| }t|j	|| j
| jd\\}}}}}||
 d d d ||||f |d d ||||f< |||	< n9|r|tj| ||
 d tjd|   }tj||d n| | ||
 d  d|   }tj||d ||	  |rt|tjn| 7  < q)|rt|t|f}t|dS )Nr   r   r   r   r_   out)r5   r]   
isinstancer   ndarrayrb   copyra   r>   rc   rF   r<   rY   rS   rintr:   r	   round
from_numpyuint8byterl   rR   rd   re   )rL   outputrA   halfrZ   num_elemrg   r[   is_npri   rj   r   mixedr0   r1   r2   r3   r   r   r   _mix_elem_collate   s<   8
,$,z"FastCollateMixup._mix_elem_collatec              	   C   s  t |}| |d \}}t|d d tj}t|d D ]}|| d }|| }	|| d }
|| d }d|	  krAdksDJ  J |	dk r|| rt|j|	| j| j	d\\}}}}}	|ro|
d d ||||f 
 n|
d d ||||f  }|d d ||||f |
d d ||||f< ||d d ||||f< |	||< nc|r|
tj|	 |tjd|	   }|tj|	 |
tjd|	   }|}
tj||d tj|
|
d n,|
 |	 | d|	   }| |	 |
 d|	   }|}
tj||d tj|
|
d ||  |rt|
tjn|
 7  < ||  |r1t|tjn| 7  < qt||d d d f}t|dS )Nr   r   r   r   r_   r{   r   )r5   r]   r}   r   r~   rb   r>   rc   rF   r<   r   ra   rY   rS   r   r:   r	   r   r   r   r   rl   rd   re   )rL   r   rA   rZ   rg   r[   r   ri   rj   r   mixed_imixed_jr0   r1   r2   r3   patch_i
mixed_tempr   r   r   _mix_pair_collate  sH   
@0
$$,.z"FastCollateMixup._mix_pair_collatec              	   C   sn  t |}|  \}}t|d d tj}|r't|j|| j| jd\\}}}	}
}t	|D ]}|| d }|| d }|dkr|rf|rE|
 n| }|| d d d |||	|
f |d d |||	|
f< n9|r|tj| || d tjd|   }tj||d n| | || d  d|   }tj||d ||  |rt|tjn| 7  < q+|S )Nr   r_   r   r   r{   )r5   r^   r}   r   r~   r>   rc   rF   r<   rb   r   ra   rY   rS   r   r:   r	   r   r   r   r   )rL   r   rA   rZ   r   r[   r   r0   r1   r2   r3   ri   rj   r   r   r   r   _mix_batch_collate/  s0   :,$,z#FastCollateMixup._mix_batch_collateNc                 C   s   t |}|d dksJ dd| jv }|r|d }tj|g|d d jR tjd}| jdks4| jdkr=| j|||d}n| jdkrI| ||}n| ||}tj	d	d
 |D tj
d}t|| j|| j}|d | }||fS )Nr   r   rr   r   rO   rs   )r   rt   c                 S   s   g | ]}|d  qS )r   r   ).0br   r   r   
<listcomp>Y  s    z-FastCollateMixup.__call__.<locals>.<listcomp>)r5   rJ   r	   rT   rc   r   r   r   r   rd   int64r   r   rI   )rL   rA   _rZ   r   r   r   r   r   r   r   ru   L  s   
"
zFastCollateMixup.__call__)FN)rv   rw   rx   ry   r   r   r   ru   r   r   r   r   rz      s    
#)rz   )r   r   )r   Nr   )NTN)ry   numpyr   r	   r   r   r4   r9   r>   r?   rz   r   r   r   r   <module>   s    




 