o
    i*  ã                   @  sp   d dl mZ d dlZd dlZd dlmZ d dlmZ d dlm	Z	 d dl
mZ G dd„ deƒZG d	d
„ d
eƒZdS )é    )ÚannotationsN)Ú_Loss)Úget_act_layer)ÚLossReduction)ÚStrEnumc                   @  s   e Zd ZdZdZdZdS )ÚAdversarialCriterionsZbceZhingeÚleast_squaresN)Ú__name__Ú
__module__Ú__qualname__ÚBCEÚHINGEÚLEAST_SQUARE© r   r   ú_/home/dell461/cl/sdc2/last_ska_mid/HISourceFinder-master-l/src/monai/losses/adversarial_loss.pyr      s    r   c                      sV   e Zd ZdZejejdfd‡ fdd„Zddd„Z	ddd„Z
ddd„Zd dd„Z‡  ZS )!ÚPatchAdversarialLossa-  
    Calculates an adversarial loss on a Patch Discriminator or a Multi-scale Patch Discriminator.
    Warning: due to the possibility of using different criterions, the output of the discrimination
    mustn't be passed to a final activation layer. That is taken care of internally within the loss.

    Args:
        reduction: {``"none"``, ``"mean"``, ``"sum"``}
            Specifies the reduction to apply to the output. Defaults to ``"mean"``.

            - ``"none"``: no reduction will be applied.
            - ``"mean"``: the sum of the output will be divided by the number of elements in the output.
            - ``"sum"``: the output will be summed.

        criterion: which criterion (hinge, least_squares or bce) you want to use on the discriminators outputs.
            Depending on the criterion, a different activation layer will be used. Make sure you don't run the outputs
            through an activation layer prior to calling the loss.
        no_activation_leastsq: if True, the activation layer in the case of least-squares is removed.
    FÚ	reductionúLossReduction | strÚ	criterionÚstrÚno_activation_leastsqÚboolÚreturnÚNonec                   sÐ   t ƒ jt|ƒd | ¡ ttƒvrtdd t¡ ƒ‚d| _d| _	|  |tj
kr5tdƒ| _tjj|d| _n+|tjkrCtdƒ| _d| _	n|tjkr`|rNd | _n
td	d
difd| _tjj|d| _|| _|| _d S )N)r   zGUnrecognised criterion entered for Adversarial Loss. Must be one in: %sz, g      ð?g        ÚSIGMOIDZTANHg      ð¿Ú	LEAKYRELUÚnegative_slopegš™™™™™©?)Úname)ÚsuperÚ__init__r   ÚlowerÚlistr   Ú
ValueErrorÚjoinÚ
real_labelÚ
fake_labelr   r   Ú
activationÚtorchÚnnÚBCELossÚloss_fctr   r   ÚMSELossr   r   )Úselfr   r   r   ©Ú	__class__r   r   r   2   s.   ÿÿ





zPatchAdversarialLoss.__init__Úinputútorch.TensorÚtarget_is_realc                 C  sJ   |r| j n| j}t d¡ |¡ | ¡ ¡ |d j¡}| d¡ | 	|¡S )aŸ  
        Gets the ground truth tensor for the discriminator depending on whether the input is real or fake.

        Args:
            input: input tensor from the discriminator (output of discriminator, or output of one of the multi-scale
            discriminator). This is used to match the shape.
            target_is_real: whether the input is real or wannabe-real (1s) or fake (0s).
        Returns:
        é   r   F)
r$   r%   r'   ÚtensorÚfill_ÚtypeÚtoÚdeviceÚrequires_grad_Ú	expand_as)r,   r/   r1   Zfilling_labelZlabel_tensorr   r   r   Úget_target_tensorT   s   
&

z&PatchAdversarialLoss.get_target_tensorc                 C  s8   t  d¡ |d  ¡ ¡ |d j¡}| d¡ | |¡S )z—
        Gets a zero tensor.

        Args:
            input: tensor which shape you want the zeros tensor to correspond to.
        Returns:
        r   F)r'   r3   r5   r6   r7   r8   r9   )r,   r/   Zzero_label_tensorr   r   r   Úget_zero_tensorc   s   $	

z$PatchAdversarialLoss.get_zero_tensorútorch.Tensor | listÚfor_discriminatorú!torch.Tensor | list[torch.Tensor]c                 C  s$  |s|sd}t  d¡ t|tƒs|g}g }t|ƒD ]\}}| jtjkr-| |  	||¡¡ q| |  
|¡¡ qg }t|ƒD ]-\}}| jdurJ|  |¡}| jtjkr\|s\|  | || ¡}	n|  ||| ¡}	| |	¡ q<|dur| jtjkr~t t |¡¡}
|
S | jtjkrŽt t |¡¡}
|
S |}
|
S )aL  

        Args:
            input: output of Multi-Scale Patch Discriminator or Patch Discriminator; being a list of tensors
                or a tensor; they shouldn't have gone through an activation layer.
            target_is_real: whereas the input corresponds to discriminator output for real or fake images
            for_discriminator: whereas this is being calculated for discriminator or generator loss. In the last
                case, target_is_real is set to True, as the generator wants the input to be dimmed as real.
        Returns: if reduction is None, returns a list with the loss tensors of each discriminator if multi-scale
            discriminator is active, or the loss tensor if there is just one discriminator. Otherwise, it returns the
            summed or mean loss over the tensor and discriminator/s.

        Tz‘Variable target_is_real has been set to False, but for_discriminator is setto False. To optimise a generator, target_is_real must be set to True.N)ÚwarningsÚwarnÚ
isinstancer!   Ú	enumerater   r   r   Úappendr:   r;   r&   Ú_forward_singler   r   ÚMEANr'   ÚmeanÚstackÚSUMÚsum)r,   r/   r1   r=   Útarget_Ú_Zdisc_outZ	loss_listZdisc_indZloss_Úlossr   r   r   Úforwardp   s:   ÿ


üÿzPatchAdversarialLoss.forwardÚtargetc                 C  sZ   | j tjks| j tjkr|  ||¡}|S | j tjkr+t |d |  |¡¡}t 	|¡ }|S )Nr2   )
r   r   r   r   r*   r   r'   Úminr;   rF   )r,   r/   rN   rM   Úminvalr   r   r   rD   ¦   s   ýz$PatchAdversarialLoss._forward_single)r   r   r   r   r   r   r   r   )r/   r0   r1   r   r   r0   )r/   r0   r   r0   )r/   r<   r1   r   r=   r   r   r>   )r/   r0   rN   r0   r   r0   )r	   r
   r   Ú__doc__r   rE   r   r   r   r:   r;   rM   rD   Ú__classcell__r   r   r-   r   r      s    ü
"

6r   )Ú
__future__r   r?   r'   Útorch.nn.modules.lossr   Úmonai.networks.layers.utilsr   Úmonai.utilsr   Úmonai.utils.enumsr   r   r   r   r   r   r   Ú<module>   s   