o
    *jT                     @   sh   d Z ddlmZmZmZ ddlZddlmZ ddlm  m	Z
 G dd dZdd ZG dd	 d	eZdS )
zx
Part of the implementation is borrowed and modified from LaMa, publicly available at
https://github.com/saic-mdal/lama
    )DictOptionalTupleNc                   @   s   e Zd ZdejdejdejdejfddZdejdejdejdejfddZ		ddejdejd
ejdejde	ej de
ejeeejf f fddZ		ddejdejd
ejdejde	ej de
ejeeejf f fddZdd Zd	S )BaseAdversarialLoss
real_batch
fake_batch	generatordiscriminatorc                 C      dS )a  
        Prepare for generator step
        :param real_batch: Tensor, a batch of real samples
        :param fake_batch: Tensor, a batch of samples produced by generator
        :param generator:
        :param discriminator:
        :return: None
        N selfr   r   r   r	   r   r   z/var/www/html/Deteccion_Ine/venv/lib/python3.10/site-packages/modelscope/models/cv/image_inpainting/modules/adversarial.pypre_generator_step       z&BaseAdversarialLoss.pre_generator_stepc                 C   r
   )a  
        Prepare for discriminator step
        :param real_batch: Tensor, a batch of real samples
        :param fake_batch: Tensor, a batch of samples produced by generator
        :param generator:
        :param discriminator:
        :return: None
        Nr   r   r   r   r   pre_discriminator_step   r   z*BaseAdversarialLoss.pre_discriminator_stepNdiscr_real_preddiscr_fake_predmaskreturnc                 C      t )a  
        Calculate generator loss
        :param real_batch: Tensor, a batch of real samples
        :param fake_batch: Tensor, a batch of samples produced by generator
        :param discr_real_pred: Tensor, discriminator output for real_batch
        :param discr_fake_pred: Tensor, discriminator output for fake_batch
        :param mask: Tensor, actual mask, which was at input of generator when making fake_batch
        :return: total generator loss along with some values that might be interesting to log
        NotImplementedErrorr   r   r   r   r   r   r   r   r   generator_loss&      z"BaseAdversarialLoss.generator_lossc                 C   r   )a+  
        Calculate discriminator loss and call .backward() on it
        :param real_batch: Tensor, a batch of real samples
        :param fake_batch: Tensor, a batch of samples produced by generator
        :param discr_real_pred: Tensor, discriminator output for real_batch
        :param discr_fake_pred: Tensor, discriminator output for fake_batch
        :param mask: Tensor, actual mask, which was at input of generator when making fake_batch
        :return: total discriminator loss along with some values that might be interesting to log
        r   r   r   r   r   discriminator_loss5   r   z&BaseAdversarialLoss.discriminator_lossc                 C   sp   |d usJ | j s||jdd  ksJ ||jdd  kr6| j r6| jdkr-t||}|S tj||| jd}|S )NZmaxpool)sizemode)allow_scale_maskshapemask_scale_modeFZadaptive_max_pool2dZinterpolate)r   r   r!   r   r   r   interpolate_maskD   s   
z$BaseAdversarialLoss.interpolate_maskN)__name__
__module____qualname__torchTensornnModuler   r   r   r   r   strr   r   r$   r   r   r   r   r      sH    



r   c                 C   sV   t  r$t jj|  |ddd }||jd djdddd  }nd}d|_	|S )	NT)ZoutputsZinputsZcreate_graphr         )dimF)
r)   Zis_grad_enabledZautogradZgradsumviewr!   Znormmeanrequires_grad)r   r   Z	grad_realgrad_penaltyr   r   r   
make_r1_gpP   s(   r7   c                   @   s   e Zd Z								dddZ		dd
ejdejdejdejdeejeeejf f f
ddZ	d
ejdejde
jde
jfddZ		dd
ejdejdejdejdeejeeejf f f
ddZd	S )NonSaturatingWithR1   r0   Fnearestr   Tc	           	      C   sL   || _ || _|s|rJ |s|rJ || _|| _|| _|| _|| _|| _d S r%   )gp_coefweightuse_unmasked_for_genuse_unmasked_for_discrmask_as_fake_targetr    r"   extra_mask_weight_for_gen)	r   r;   r<   r?   r    r"   r@   r=   r>   r   r   r   __init__a   s   	
zNonSaturatingWithR1.__init__Nr   r   r   r   r   c                 C   sr   t | }| jr| jdks| js/| ||jdd  }| js$|| }nd|| j  }|| }| | j t	 fS )Nr   r   r0   )
r#   softplusr?   r@   r=   r$   r!   r4   r<   dict)r   r   r   r   r   r   	fake_lossZpixel_weightsr   r   r   r   z   s   
z"NonSaturatingWithR1.generator_lossr   r	   c                 C   s
   d|_ d S )NT)r5   r   r   r   r   r      s   
z*NonSaturatingWithR1.pre_discriminator_stepc                 C   s   t | }t||| j }t |}| jr| jr7| ||jdd  }|| }| jr7|d| t |   }|| | }	t|	 |	 |d}
|		 |
fS )Nr   r0   )Zdiscr_real_outZdiscr_fake_outZdiscr_real_gp)
r#   rB   r7   r;   r>   r?   r$   r!   rC   r4   )r   r   r   r   r   r   Z	real_lossr6   rD   Zsum_discr_lossZmetricsr   r   r   r      s&   

z&NonSaturatingWithR1.discriminator_loss)r9   r0   FFr:   r   TTr%   )r&   r'   r(   rA   r)   r*   r   r   r-   r   r+   r,   r   r   r   r   r   r   r8   _   sB    


r8   )__doc__typingr   r   r   r)   Ztorch.nnr+   Ztorch.nn.functionalZ
functionalr#   r   r7   r8   r   r   r   r   <module>   s    D