U
    ¯Ê¹j*9  ã                   @   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   Zscatter_)ÚxÚnum_classesÚon_valueÚ	off_value© r   úN/var/www/html/bwave/python/venv/lib/python3.8/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   ÚlamZ	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ÚrandintZclip)Ú	img_shaper   ÚmarginÚcountÚratioÚimg_hÚimg_wÚcut_hÚcut_wZmargin_yZmargin_xÚcyZcxÚylÚyhÚxlÚxhr   r   r   Ú	rand_bbox   s    r.   c                 C   s¼   t |ƒdkst‚| 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   )ÚlenÚAssertionErrorr   r   r    r   )r!   Zminmaxr#   r%   r&   r'   r(   r*   r,   ÚyuÚxur   r   r   Úrand_bbox_minmax6   s    **r3   Tc           
      C   s~   |dk	r t | ||d�\}}}}nt| ||d�\}}}}|sB|dk	rn|| ||  }	d|	t| d | d  ƒ  }||||f|fS )z0 Generate bbox and apply lambda correction.
    N)r#   r   r   r   )r3   r.   Úfloat)
r!   r   Úratio_minmaxÚcorrect_lamr#   r*   r1   r,   r2   Z	bbox_arear   r   r   Úcutmix_bbox_and_lamM   s    r7   c                	   @   sJ   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 k	r4t| jƒdks.t‚d| _|| _|| _|| _|	| _|| _	|| _
d| _d S )Nr   r   T)Úmixup_alphaÚcutmix_alphaÚcutmix_minmaxr/   r0   Úmix_probÚswitch_probÚlabel_smoothingr   Úmoder6   Úmixup_enabled)
Úselfr=   r>   r?   ZprobrA   rC   r6   rB   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r¢t jj| j| j|d�}n<| jdkrÒt j|td�}t jj| j| j|d�}ndsÞtdƒ‚t  t j 	|¡| jk | t j¡|¡}||fS )N©Údtyper   r   FúROne of mixup_alpha > 0., cutmix_alpha > 0., cutmix_minmax not None should be true.)r   ÚonesÚfloat32ÚzerosÚboolrD   r=   r>   r   ÚrandrA   ÚwhereÚbetar0   r@   Úastype)rE   Ú
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rl| jdkrltj ¡ | jk }|rXtj | j| j¡ntj | j| j¡}nL| jdkrŠtj | j| j¡}n.| jdkr¬d}tj | j| j¡}nds¸t	dƒ‚t
|ƒ}||fS )Nr   Fr   TrI   )rD   r   r   rN   r@   r=   r>   rA   rP   r0   r4   )rE   r   rS   rT   r   r   r   Ú_params_per_batch�   s     ÿ

zMixup._params_per_batchc                 C   sò   t |ƒ}|  |¡\}}| ¡ }t|ƒD ]°}|| d }|| }|dkr&|| r¶t|| j|| j| jd�\\}	}
}}}|| d d …|	|
…||…f || d d …|	|
…||…f< |||< q&|| | || d|   ||< q&tj	||j
|jd� d¡S )Nr   r   ©r5   r6   ©r   rH   )r/   rU   ÚcloneÚranger7   Úshaper?   r6   r	   Útensorr   rH   Ú	unsqueeze©rE   r   rR   Ú	lam_batchrS   Zx_origÚiÚjr   r*   r+   r,   r-   r   r   r   Ú	_mix_elemŸ   s$       ÿ8
"zMixup._mix_elemc                 C   sl  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   rW   r   rX   )r/   rU   rY   rZ   r7   r[   r?   r6   r   Úconcatenater	   r\   r   rH   r]   r^   r   r   r   Ú	_mix_pair°   s*       ÿ88
 "zMixup._mix_pairc           	      C   sª   |   ¡ \}}|dkrdS |r‚t|j|| j| jd�\\}}}}}| d¡d d …d d …||…||…f |d d …d d …||…||…f< n$| d¡ d| ¡}| |¡ |¡ |S )Nr   rW   r   )rV   r7   r[   r?   r6   r   Zmul_Zadd_)	rE   r   r   rS   r*   r+   r,   r-   Z	x_flippedr   r   r   Ú
_mix_batchÄ   s       ÿDzMixup._mix_batchc                 C   sh   t |ƒd dkstdƒ‚| jdkr.|  |¡}n | jdkrD|  |¡}n
|  |¡}t|| j|| jƒ}||fS )Nr   r   ú)Batch size should be even when using thisÚelemÚpair)	r/   r0   rC   rb   rd   re   r   r   rB   )rE   r   r   r   r   r   r   Ú__call__Ñ   s    


zMixup.__call__)	r   r   Nr   r9   r:   Tr;   r<   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__rF   rU   rV   rb   rd   re   ri   r   r   r   r   r8   Z   s           ÿ
r8   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   sh  t |ƒ}|r|d n|}t |ƒ|ks(t‚|  |¡\}}t|ƒD ]þ}|| d }	|| }
|| d }|
dk�r|| rä|s€| ¡ }t|j|
| j| jd�\\}}}}}
||	 d d d …||…||…f |d d …||…||…f< |
||< n:| 	t
j¡|
 ||	 d  	t
j¡d|
   }t
j||d� ||  t | 	t
j¡¡7  < q>|�rXt
 |t
 |¡f¡}t |¡ d¡S )Nr   r   r   r   rW   ©Úout)r/   r0   rU   rZ   Úcopyr7   r[   r?   r6   rQ   r   rK   Úrintr	   Ú
from_numpyÚuint8rc   rJ   r\   r]   )rE   Úoutputr:   ÚhalfrR   Znum_elemr_   rS   r`   ra   r   Úmixedr*   r+   r,   r-   r   r   r   Ú_mix_elem_collateã   s4    
   ÿ8
, z"FastCollateMixup._mix_elem_collatec              	   C   sè  t |ƒ}|  |d ¡\}}t|d ƒD �]–}|| d }|| }|| d }	|| d }
d|  krldksrn t‚|dk �r‚|| �rt|j|| j| jd�\\}}}}}|	d d …||…||…f  ¡ }|
d d …||…||…f |	d d …||…||…f< ||
d d …||…||…f< |||< nh|	 	t
j¡| |
 	t
j¡d|   }|
 	t
j¡| |	 	t
j¡d|   }
|}	t
j|
|
d� t
j|	|	d� ||  t |	 	t
j¡¡7  < ||  t |
 	t
j¡¡7  < q&t
 ||d d d… f¡}t |¡ d¡S )Nr   r   r   r   rW   ro   r   )r/   rU   rZ   r0   r7   r[   r?   r6   rq   rQ   r   rK   rr   r	   rs   rt   rc   r\   r]   )rE   ru   r:   rR   r_   rS   r`   ra   r   Zmixed_iZmixed_jr*   r+   r,   r-   Zpatch_iZ
mixed_tempr   r   r   Ú_mix_pair_collateü   s:    

   ÿ0
$$ z"FastCollateMixup._mix_pair_collatec              	   C   s
  t |ƒ}|  ¡ \}}|r:t|j|| j| jd�\\}}}}	}t|ƒD ]Â}
||
 d }||
 d }|dkræ|r¬| ¡ }|| d d d …||…||	…f |d d …||…||	…f< n:| t	j
¡| || d  t	j
¡d|   }t	j||d� ||
  t | t	j¡¡7  < qB|S )NrW   r   r   r   ro   )r/   rV   r7   r[   r?   r6   rZ   rq   rQ   r   rK   rr   r	   rs   rt   )rE   ru   r:   rR   r   rS   r*   r+   r,   r-   r`   ra   rw   r   r   r   Ú_mix_batch_collate  s(       ÿ:, z#FastCollateMixup._mix_batch_collateNc                 C   sÜ   t |ƒ}|d dkstdƒ‚d| jk}|r2|d }tj|f|d d j˜tjd�}| jdksf| jdkrx| j|||d�}n$| jdkr�|  ||¡}n|  	||¡}tj
d	d
„ |D ƒtjd�}t|| j|| jƒ}|d |… }||fS )Nr   r   rf   rv   rG   rg   )rv   rh   c                 S   s   g | ]}|d  ‘qS )r   r   )Ú.0Úbr   r   r   Ú
<listcomp>8  s     z-FastCollateMixup.__call__.<locals>.<listcomp>)r/   r0   rC   r	   rL   r[   rt   rx   ry   rz   r\   Zint64r   r   rB   )rE   r:   Ú_rR   rv   ru   r   r   r   r   r   ri   +  s    
 
zFastCollateMixup.__call__)F)N)rj   rk   rl   rm   rx   ry   rz   ri   r   r   r   r   rn   Ý   s
   
rn   )r   r   )r   r   )r   N)N)NTN)rm   Únumpyr   r	   r   r   r.   r3   r7   r8   rn   r   r   r   r   Ú<module>   s   




 