o
    oi(+                     @   s   d dl Z d dlmZmZmZmZmZmZmZ d dl	Z	ddl
mZmZ ddl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 ee Zeeeeef f ZG d	d
 d
eZdS )    N)AnyDictListOptionalTupleUnioncast   )DeviceTensor   )AugmentationSequentialColorJitterImageSequentialRandomAffineRandomErasingRandomGaussianNoiseRandomHorizontalFlipRandomRotation90)_AugmentationBase)	ParamItemc                       s  e Zd ZdZdddddddd	d
ddddeeef dededededededee	e
eef f dee	e
eef f dedee dee deddf fddZdee	e
eef f dee	e
eef f d ede
eeef d!f fd"d#Zd$eddfd%d&Zd'edede
eef fd(d)Zd'eded*e	defd+d,Zd-ed.ed*e	defd/d0Z			d4d'ed1eee  dee d$ee def
 fd2d3Z  ZS )5!AdaptiveDiscriminatorAugmentationaQ	  Implementation of Adaptive Discriminator Augmentation for GANs training as introduced in :cite:`Karras2020ada`.

    adjust a global probability p over all augmentations list to select a subset of images to augment
    based on an exponential moving average of the Discriminator's accuracy labeling real samples.


    Args:
        *args: a list of kornia augmentation modules, set to a default list if not specified.

        initial_p: initial global probability `p` for applying the augmentations

        adjustment_speed: float
            step size for updating the global probability `p`

        max_p: maximum allowed value for `p`

        target_real_acc: target Discriminator accuracy to guide `p` adjustments


        ema_lambda: EMA smoothing factor. The real accuracy EMA is what's used to determine the `p` update

        update_every: `p` update frequency (in steps)

        erasing_scale: scale range used for `RandomErasing` if default augmentations are used

        erasing_ratio: aspect ratio range used for `RandomErasing` if default augmentations are used

        erasing_fill_value: fill value used in `RandomErasing`

        same_on_batch: apply the same transformation across the batch

        data_keys: input types to apply augmentations on


        **kwargs: Additional keyword arguments passed to `AugmentationSequential`


    Examples:
        >>> from kornia.augmentation.presets.ada import AdaptiveDiscriminatorAugmentation
        >>> original = torch.randn(2, 3, 16, 16)
        >>> ada = AdaptiveDiscriminatorAugmentation()
        >>> augmented = ada(original)

    This example demonstrates using default augmentations with AdaptiveDiscriminatorAugmentation in a GAN training loop.


        >>> import kornia.augmentation as K
        >>> from kornia.augmentation.presets.ada import AdaptiveDiscriminatorAugmentation
        >>> originals = torch.randn(2, 3, 5, 6)
        >>> aug_list = [
        ...     K.RandomRotation90(times=(0, 3), p=1),
        ...     K.RandomAffine(degrees=10, translate=(.1, .1), scale=(.9, 1.1), p=1),
        ...     K.ColorJitter(brightness=.2, contrast=.2, saturation=.2, hue=.1, p=1),
        ... ]

        >>> ada = AdaptiveDiscriminatorAugmentation(*aug_list)
        >>> augmented = ada(original)

    This example demonstrates using custom augmentations with AdaptiveDiscriminatorAugmentation.
    gh㈵>g{Gz?g?g333333?gGz?   )g{Gz?gQ?)g333333?gffffff
@g        NF)	initial_padjustment_speedmax_ptarget_real_acc
ema_lambdaupdate_everyerasing_scaleerasing_ratioerasing_fill_value	data_keyssame_on_batchargsr   r   r   r   r   r   r   r    r!   r"   r#   kwargsreturnc                   s\  |s	|  |||	}t j||
d ur|
ndg|d| |dkr(td| dd|  kr2dks;n td| dd|  krEdksNn td	| d|dk rZtd
| dd|  krddksmn td| dd|  krwdksn td| d||krtjd| d| ddd |}|| _|| _|| _|| _	|| _
|| _d| _d| _d S )Ninput)r"   r#   r   zInvalid `adjustment_speed` (u   ) — must be greater than 0   zInvalid `target_real_acc` (u   ) — must be in [0, 1]zInvalid `ema_lambda` (zInvalid `update_every` (u   ) — must be at least 1zInvalid `max_p` (zInvalid `initial_p` (z`initial_p` (z) is greater than `max_p` (z#), resetting `initial_p` to `max_p`r   )
stacklevelg      ?)default_ada_transfromssuper__init__
ValueErrorwarningswarnpr   r   r   r   r   real_acc_ema
_num_calls)selfr   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   	__class__ S/home/ubuntu/.local/lib/python3.10/site-packages/kornia/augmentation/presets/ada.pyr,   g   sL   
z*AdaptiveDiscriminatorAugmentation.__init__scaleratiovalue.c                 C   sL   t ddtdddt|||ddtdd	d
ddtddddddtdddfS )Nr(   )r0   )r   r	   g      ?)timesr0   ?)r8   r9   r:   r0   
   )皙?r>   )r<   g?)degrees	translater8   r0   g?r>   )
brightnesscontrast
saturationhuer0   )stdr0   )r   r   r   r   r   r   )r3   r8   r9   r:   r6   r6   r7   r*      s   

z8AdaptiveDiscriminatorAugmentation.default_ada_transfromsreal_accc                 C   s~   |  j d7  _ | j | jk rdS d| _ | j| j d| j |  | _| j| jk r2td| j| j | _dS t| j| j | j	| _dS )ar  Updates internal params `p` once every `update_every` calls based on discriminator accuracy.

        the update is based on an exponential moving average of `real_acc`
        `p` is updated by adding or subtracting `adjustment_speed` from it and clamp it at [0, `max_p`]

        Args:
            real_acc: the Discriminator's accuracy labeling real samples.
        r(   Nr   )
r2   r   r   r1   r   maxr0   r   minr   )r3   rF   r6   r6   r7   update   s   	z(AdaptiveDiscriminatorAugmentation.updateinputsc                 C   sJ   t |tr|d }|| d}|| j}||fS |d}|j}||fS )Nr   )
isinstancedictsizedevice)r3   rJ   r"   key
batch_sizerN   r6   r6   r7   _get_inputs_metadata   s   


z6AdaptiveDiscriminatorAugmentation._get_inputs_metadatap_tensorc                    s&   t  tr fdd|D S   S )Nc                    s   i | ]	}| |  qS r6   r6   ).0rO   rJ   rR   r6   r7   
<dictcomp>   s    zDAdaptiveDiscriminatorAugmentation._sample_inputs.<locals>.<dictcomp>)rK   rL   )r3   rJ   r"   rR   r6   rT   r7   _sample_inputs   s   
z0AdaptiveDiscriminatorAugmentation._sample_inputsoriginal	augmentedc                 C   s   t |tr%t |tr%i }| D ]}||  }|| ||< |||< q|S t |tr9t |tr9| }|||< |S tdt| dt| d)NzCoriginal inputs and augmented inputs aren't of the same type (type(z), type(z)))rK   rL   keyscloner   	TypeErrortype)r3   rW   rX   rR   mergedrO   merged_tensorr6   r6   r7   _merge_inputs   s$   
	z/AdaptiveDiscriminatorAugmentation._merge_inputsparamsc           
         s   |dur	|  | | jdkr|S |du r$| jdur!dd | jD ndg}| j||d\}}ttj|f| jtj|d }|	 sD|S | j
|||d}ttt j|||d	}	| ||	|S )
a  Apply augmentations to a subset of input tensors with global probability `p`.

        This method applies the augmentation pipeline to a subset of input samples, randomly selected
        via a Bernoulli distribution with probability `p`

        if `real_acc` is provided, the internal probability `p` is updated via the `update` method.
        Non-augmented samples retain their original values, and the output matches the input structure.

        `real_acc` is the Discriminator's accuracy on real images; for example,
        `(real_logits > 0).float().mean().item()` if using logits andn assuming real labels are positive.
        Nr   c                 S   s   g | ]}|j qS r6   )name)rS   kr6   r6   r7   
<listcomp>  s    z=AdaptiveDiscriminatorAugmentation.forward.<locals>.<listcomp>r'   )r"   )dtyperN   )r"   rR   )r`   r"   )rI   r0   r"   rQ   torch	bernoullifullfloat32boolanyrV   r   _inputs_typer+   forwardr_   )
r3   rJ   r`   r"   rF   rP   rN   rR   selected_inputsaugmented_inputsr4   r6   r7   rl      s0   


"	z)AdaptiveDiscriminatorAugmentation.forward)NNN)__name__
__module____qualname____doc__r   r   r   floatintr   r   r   _data_keys_typeri   r   r,   r*   rI   rk   r
   rQ   rV   r_   r   r   rl   __classcell__r6   r6   r4   r7   r   )   s    @
	
@


r   )r.   typingr   r   r   r   r   r   r   re   corer
   r    r   r   r   r   r   r   r   r   baser   container.paramsr   strru   rk   r   r6   r6   r6   r7   <module>   s   $(
