
    Ng)                        d Z ddlZddlmZ ddlmc mZ ddlmZm	Z	m
Z
 dedefdZd$dededefd	Z	 d%dedeej                 defdZ	 d&dedeej                 defdZd'defdZdefdZ	 	 d(de	ej                 de	ej                 de	ej                 de	ej                 dej        dededededededed e
ej        ej        ej        f         fd!Zej                            e          Z G d" d#ej                  ZdS ))z EfficientDet Focal, Huber/Smooth L1 loss fns w/ jit support

Based on loss fn in Google's automl EfficientDet repository (Apache 2.0 license).
https://github.com/google/automl/tree/master/efficientdet

Copyright 2020 Ross Wightman
    N)OptionalListTuplealphagammac           	      P   |dk    }t          j        | |                    | j                  d          }d| z  }t	          j        ||z  |z  |t	          j        t	          j        |                    z  z
            }||z  }	t	          j        |||	z  d|z
  |	z            }
|
|z  S )a  Compute the focal loss between `logits` and the golden `target` values.

    'Legacy focal loss matches the loss used in the official Tensorflow impl for initial
    model releases and some time after that. It eventually transitioned to the 'New' loss
    defined below.

    Focal loss = -(1-pt)^gamma * log(pt)
    where pt is the probability of being classified to the true class.

    Args:
        logits: A float32 tensor of size [batch, height_in, width_in, num_predictions].

        targets: A float32 tensor of size [batch, height_in, width_in, num_predictions].

        alpha: A float32 scalar multiplying alpha to the loss from positive examples
            and (1-alpha) to the loss from negative examples.

        gamma: A float32 scalar modulating loss from hard and easy examples.

         normalizer: A float32 scalar normalizes the total loss from all examples.

    Returns:
        loss: A float32 scalar representing normalized total loss.
          ?none	reductiong      )F binary_cross_entropy_with_logitstodtypetorchexplog1pwhere)logitstargetsr   r   
normalizerpositive_label_maskcross_entropy
neg_logits	modulatorlossweighted_losss              G/var/www/html/ai-engine/env/lib/python3.11/site-packages/effdet/loss.pyfocal_loss_legacyr      s    2 "S.6vwzz&,?W?WcijjjMJ	%'/J6UYWaMbMbAcAc9ccddI}$DK 3UT\C%KSWCWXXM:%%    {Gz?label_smoothingc                 "   |                                  }|                    | j                  }d|z
  }||z  |d|z
  z  z   }||z  |d|z
  z  z   }	d|z
  |z  }
|dk    r|d|z
  z  d|z  z   }t          j        | |d          }d|z  |	z  |
z  |z  S )a$  Compute the focal loss between `logits` and the golden `target` values.

    'New' is not the best descriptor, but this focal loss impl matches recent versions of
    the official Tensorflow impl of EfficientDet. It has support for label smoothing, however
    it is a bit slower, doesn't jit optimize well, and uses more memory.

    Focal loss = -(1-pt)^gamma * log(pt)
    where pt is the probability of being classified to the true class.
    Args:
        logits: A float32 tensor of size [batch, height_in, width_in, num_predictions].
        targets: A float32 tensor of size [batch, height_in, width_in, num_predictions].
        alpha: A float32 scalar multiplying alpha to the loss from positive examples
            and (1-alpha) to the loss from negative examples.
        gamma: A float32 scalar modulating loss from hard and easy examples.
        normalizer: Divide loss by this value.
        label_smoothing: Float in [0, 1]. If > `0` then smooth the labels.
    Returns:
        loss: A float32 scalar representing normalized total loss.
    r	                 ?r
   r      )sigmoidr   r   r   r   )r   r   r   r   r   r"   	pred_probonem_targetsp_talpha_factormodulating_factorces               r   new_focal_lossr.   2   s    *   Ijj&&G<LY<2	>#B
CCU?\R%Z%@@Lce+ R/12R/5II	
	+FGv	N	N	NB 
Nl*->>CCr    r	   Tdeltaweightssize_averagec                 (   | |z
  }|                                 }t          j        ||          }||z
  }d|                    d          z  ||z  z   }	||	                    |          }	|r|	                                S |	                                S )z
    )maxr%      )absr   clamppowmulmeansum)
inputtargetr/   r0   r1   errabs_err	quadraticlinearr   s
             r   
huber_lossrA   W   s     &.CggiiGG///Iy Fq!!!EFN2Dxx   yy{{xxzzr    qq?betac                 @   |dk     rt          j        | |z
            }nPt          j        | |z
            }t          j        ||k     d|                    d          z  |z  |d|z  z
            }|||z  }|r|                                S |                                S )z\
    very similar to the smooth_l1_loss from pytorch, but with the extra beta parameter
    gh㈵>r%   r4   )r   r5   r   r7   r9   r:   )r;   r<   rC   r0   r1   r   r=   s          r   smooth_l1_lossrE   h   s    
 d{{ y((i''{3:sSWWQZZ'7$'>cDj@PQQ yy{{xxzzr    皙?c                 J    |dz  }|dk    }t          | |||d          }||z  S )zComputes box regression loss.g      @r$   F)r0   r/   r1   )rA   )box_outputsbox_targetsnum_positivesr/   r   maskbox_losss          r   	_box_lossrM      s<    
 $J#D+{D\abbbHj  r    num_classesc                     | dk                         d          }t          j        | j        |fz   | j        t          j                  }|                    d|                      d          |z  d          |z  S )Nr   )devicer   r&   )	unsqueezer   zerosshaperQ   float32scatter)xrN   	x_non_negonehots       r   one_hotrZ      sf    a""2&&I[K>1!(%-XXXF>>"akk"oo	91==	IIr    r$   Fcls_outputsrH   cls_targetsrI   rJ   box_loss_weightlegacy_focalreturnc                    |                                 dz                                   }t          |           }g }g }t          |          D ]T}||         }||         }t	          ||          }|j        \  }}}}}|                    |||d          }| |                             dddd                                          }|rt          |||||          }nt          ||||||
          }|                    |||d|          }||d	k    
                    d          z  }|                    |                                            |                    t          ||                             dddd                                          |||
                     Vt          j         t          j        |d          d          }t          j         t          j        |d          d          }||	|z  z   }|||fS )aa  Computes total detection loss.
    Computes total detection loss including box and class loss from all levels.
    Args:
        cls_outputs: a List with values representing logits in [batch_size, height, width, num_anchors].
            at each feature level (index)

        box_outputs: a List with values representing box regression targets in
            [batch_size, height, width, num_anchors * 4] at each feature level (index)

        cls_targets: groundtruth class targets.

        box_targets: groundtrusth box targets.

        num_positives: num positive grountruth anchors

    Returns:
        total_loss: an integer tensor representing total loss reducing from class and box losses from all levels.

        cls_loss: an integer tensor representing total class loss.

        box_loss: an integer tensor representing total box regression loss.
    r	   rP   r   r4      r&   )r   r   r   )r   r   r   r"   )r/   )dim)r:   floatlenrangerZ   rT   viewpermuter   r.   rR   appendrM   r   stack)r[   rH   r\   rI   rJ   rN   r   r   r/   r]   r"   r^   num_positives_sumlevels
cls_losses
box_losseslcls_targets_at_levelbox_targets_at_levelcls_targets_at_level_ohbsheightwidth_cls_outputs_at_levelcls_lossrL   
total_losss                               r   loss_fnrz      sD   L '**,,s299;;FJJ6]]  *1~*1~ #**>"L"L"9"?FE1a"9">">r65RT"U"U*1~55aAqAAGGII 	i($&=55FH H HHH &$&=55FXgi i iH ==VUBDD3r9DDRHHH(,,..))))N""1aA..4466 	   	 	 	 	 yZR888bAAAHyZR888bAAAHOh66Jx))r    c                        e Zd ZdgZ fdZdeej                 deej                 deej                 deej                 dej        deej        ej        ej        f         fd	Z	 xZ
S )
DetectionLossrN   c                 $   t          t          |                                            || _        |j        | _        |j        | _        |j        | _        |j        | _        |j        | _        |j	        | _	        |j
        | _
        |j        | _        d S )N)superr|   __init__configrN   r   r   r/   r]   r"   r^   jit_lossuse_jit)selfr   	__class__s     r   r   zDetectionLoss.__init__   sz    mT""++---!-\
\
\
%5%5"/r    r[   rH   r\   rI   rJ   r_   c                     t           }t          j                                        s| j        rt
          } ||||||| j        | j        | j        | j	        | j
        | j        | j                  S )N)rN   r   r   r/   r]   r"   r^   )rz   r   jitis_scriptingr   loss_jitrN   r   r   r/   r]   r"   r^   )r   r[   rH   r\   rI   rJ   l_fns          r   forwardzDetectionLoss.forward   s|     y%%'' 	DL 	 Dtk;(
$*TXT^ 0$BVeievx x x 	xr    )__name__
__module____qualname____constants__r   r   r   Tensorr   r   __classcell__)r   s   @r   r|   r|      s        "OM
' 
' 
' 
' 
'xel+x el+x el+	x
 el+x !<x -2%,el2Z,[x x x x x x x xr    r|   )r!   )r	   NT)rB   NT)rF   )r$   F)__doc__r   torch.nnnntorch.nn.functional
functionalr   typingr   r   r   rd   r   r.   r   boolrA   rE   rM   intrZ   rz   r   scriptr   Moduler|    r    r   <module>r      s                    ( ( ( ( ( ( ( ( ( ( &e  &E  &  &  &  &F"D "D5 "D "D]b "D "D "D "DL hl #3;EL3I`d   $ ko "6>u|6Lcg   .! !e ! ! ! !JC J J J J$ "$"K* K*%,'K*%,'K* %,'K* %,'	K*
 |K* K* K* K* K* K* K* K* 5<u|;<K* K* K* K*\ 9G$$!x !x !x !x !xBI !x !x !x !x !xr    