
    FPhY>                         d dl Z d dlmZ d dlmc mZ d dlmZmZ d dl	m
Z
 ddlmZ  G d dej                        Z G d d	e      Zy)
    N)	FocalLossVarifocalLoss)bbox_iou   )HungarianMatcherc                        e Zd ZdZ	 	 	 	 	 	 	 d
 fd	ZddZddZ	 	 	 	 ddZed        Z	d Z
	 	 	 	 ddZdd	Z xZS )DETRLossa+  
    DETR (DEtection TRansformer) Loss class. This class calculates and returns the different loss components for the
    DETR object detection model. It computes classification loss, bounding box loss, GIoU loss, and optionally auxiliary
    losses.

    Attributes:
        nc (int): The number of classes.
        loss_gain (dict): Coefficients for different loss components.
        aux_loss (bool): Whether to compute auxiliary losses.
        use_fl (bool): Use FocalLoss or not.
        use_vfl (bool): Use VarifocalLoss or not.
        use_uni_match (bool): Whether to use a fixed layer to assign labels for the auxiliary branch.
        uni_match_ind (int): The fixed indices of a layer to use if `use_uni_match` is True.
        matcher (HungarianMatcher): Object to compute matching cost and indices.
        fl (FocalLoss or None): Focal Loss object if `use_fl` is True, otherwise None.
        vfl (VarifocalLoss or None): Varifocal Loss object if `use_vfl` is True, otherwise None.
        device (torch.device): Device on which tensors are stored.
    c                    t         |           |	ddddddd}|| _        t        dddd      | _        || _        || _        |r
t               nd| _        |r
t               nd| _
        || _        || _        d| _        y)	a  
        DETR loss function.

        Args:
            nc (int): The number of classes.
            loss_gain (dict): The coefficient of loss.
            aux_loss (bool): If 'aux_loss = True', loss at each decoder layer are to be used.
            use_vfl (bool): Use VarifocalLoss or not.
            use_uni_match (bool): Whether to use a fixed layer to assign labels for auxiliary branch.
            uni_match_ind (int): The fixed indices of a layer.
        Nr         g?)classbboxgiou	no_objectmaskdice)r   r   r   )	cost_gain)super__init__ncr   matcher	loss_gainaux_lossr   flr   vfluse_uni_matchuni_match_inddevice)	selfr   r   r   use_fluse_vflr   r   	__class__s	           hC:\Users\daisl\Desktop\realtime-object-detection\venv\Lib\site-packages\ultralytics/models/utils/loss.pyr   zDETRLoss.__init__!   s    & 	"#QUV`abI'AqRS2TU" !')+T&-=?4**    c                    d| }|j                   dd \  }}t        j                  ||| j                  dz   ft        j                  |j
                        }	|	j                  d|j                  d      d       |	dddf   }	|j                  ||d      |	z  }| j                  rU|r | j                  r| j                  |||	      }
n | j                  ||	j                               }
|
t        |d      |z  z  }
n: t        j                  d	      ||      j                  d      j!                         }
||
j#                         | j$                  d
   z  iS )z^Computes the classification loss based on predictions, target values, and ground truth scores.
loss_classNr   r   )dtyper   .none	reductionr   )shapetorchzerosr   int64r   scatter_	unsqueezeviewr   r   floatmaxnnBCEWithLogitsLossmeansumsqueezer   )r   pred_scorestargets	gt_scoresnum_gtspostfix
name_classbsnqone_hotloss_clss              r#   _get_loss_classzDETRLoss._get_loss_classC   s2    "'+
""2A&B++r2tww{35;;w~~^G--b115#ss(#NN2r1-7	7748888KGD77;@GQ",,H=r++f=k9UZZ[\]aacHH,,.1HHIIr$   c                 F   d| }d| }i }t        |      dk(  rJt        j                  d| j                        ||<   t        j                  d| j                        ||<   |S | j                  d   t        j                  ||d      z  t        |      z  ||<   d	t        ||d
d
      z
  ||<   ||   j                         t        |      z  ||<   | j                  d   ||   z  ||<   |j                         D ci c]  \  }}||j                          c}}S c c}}w )z~Calculates and returns the bounding box loss and GIoU loss for the predicted and ground truth bounding
        boxes.
        	loss_bbox	loss_giour           r   r   r8   r*   g      ?T)xywhGIoUr   )lenr-   tensorr   r   Fl1_lossr   r8   itemsr9   )	r   pred_bboxes	gt_bboxesr>   	name_bbox	name_gioulosskvs	            r#   _get_loss_bboxzDETRLoss._get_loss_bboxY   s   
  y)	y)	y>Q#ll2dkkBDO#ll2dkkBDOK..0199[)_d3eehkluhvvYidQU VVYy/--/#i.@Y..04	?BY+/::<8<41a199;<888s   >Dc
                    t        j                  |dnd|j                        }
|O| j                  rC| j	                  || j
                     || j
                     |||||| j
                     nd|	      }t        t        ||            D ]d  \  }\  }}|||   nd}| j                  |||||||	||	      }|
dxx   |d|    z  cc<   |
d	xx   |d
|    z  cc<   |
dxx   |d|    z  cc<   f d| |
d   d| |
d	   d| |
d   i}
|
S )zGet auxiliary losses.Nr      rI   masksgt_mask)r\   r]   r>   match_indicesr   r&   r   rF   r   rG   loss_class_auxloss_bbox_auxloss_giou_aux)	r-   r.   r   r   r   r   	enumeratezip	_get_loss)r   rQ   r:   rR   gt_cls	gt_groupsr^   r>   r\   r]   rU   i
aux_bboxes
aux_scores	aux_masksloss_s                   r#   _get_loss_auxzDETRLoss._get_loss_aux   sp    {{ 11qASAST T%7%7 LLT5G5G)H)4T5G5G)H)2)/)2LQL]uT5G5G/Hcg18 ) :M ,5Sk5R+S'A'
J$)$5a4INN:#-#,#)#,)2+2+21> # @E Guz'344GGuy	233GGuy	233G ,T( WI&QG9%tAwG9%tAw0 r$   c                 h   t        j                  t        |       D cg c]  \  }\  }}t        j                  ||        c}}}      }t        j                  | D cg c]  \  }}|	 c}}      }t        j                  | D cg c]  \  }}|	 c}}      }||f|fS c c}}}w c c}}w c c}}w )z[Returns batch indices, source indices, and destination indices from provided match indices.)r-   catrb   	full_like)r^   rg   src_	batch_idxsrc_idxdstdst_idxs           r#   
_get_indexzDETRLoss._get_index   s     II)TaJbcJb;1hsAusA6Jbcd	))?Xc1S?@))?XaS?@7#W,, d??s   #B!B(
B.
c                    t        j                  t        ||      D cg c]J  \  }\  }}t        |      dkD  r||   n.t        j                  d|j
                  d   | j                        L c}}}      }t        j                  t        ||      D cg c]J  \  }\  }}t        |      dkD  r||   n.t        j                  d|j
                  d   | j                        L c}}}      }	||	fS c c}}}w c c}}}w )z[Assigns predicted bounding boxes to ground truth bounding boxes based on the match indices.r   r(   rI   )r-   rn   rc   rL   r.   r,   r   )
r   rQ   rR   r^   tIrq   pred_assignedJgt_assigneds
             r#   _get_assigned_bboxeszDETRLoss._get_assigned_bboxes   s    		 m<#><	6Aq FQJAaDEKK1772;t{{$SS<#> ? ii M:!<:	6Aq FQJAaDEKK1772;t{{$SS:!< = k))#>!<s   AC3AC:c
           
      v   |	| j                  |||||||      }	| j                  |	      \  }
}||
   ||   }}|j                  dd \  }}t        j                  ||f| j
                  |j                  |j                        }||   ||
<   t        j                  ||g|j                        }t        |      r.t        |j                         |d      j                  d      ||
<   i }|j                  | j                  |||t        |      |             |j                  | j                  |||             |S )	zGet losses.Nr[   r   )r   r'   rI   T)rJ   r(   )r   rv   r,   r-   fullr   r   r'   r.   rL   r   detachr9   updaterD   rX   )r   rQ   r:   rR   re   rf   r\   r]   r>   r^   idxgt_idxr@   rA   r;   r<   rU   s                    r#   rd   zDETRLoss._get_loss   s7      LL)4)2)/)2/418 ) :M oom4V!,S!19V3DY""2A&B**b"Xtww{7I7IQWQ]Q]^f~KKR1C1CD	y>%k&8&8&:IDQYYZ\]IcND((gy#i.ZabcD''YHI r$   c                    |j                   | _         |j                  dd      }|d   |d   |d   }	}}| j                  |d   |d   |||	||      }
| j                  r,|
j	                  | j                  |dd |dd |||	||             |
S )a  
        Args:
            pred_bboxes (torch.Tensor): [l, b, query, 4]
            pred_scores (torch.Tensor): [l, b, query, num_classes]
            batch (dict): A dict includes:
                gt_cls (torch.Tensor) with shape [num_gts, ],
                gt_bboxes (torch.Tensor): [num_gts, 4],
                gt_groups (List(int)): a list of batch size length includes the number of gts of each image.
            postfix (str): postfix of loss name.
        r^   Nclsbboxesrf   r(   r>   r^   )r   getrd   r   r   rl   )r   rQ   r:   batchr>   kwargsr^   re   rR   rf   
total_losss              r#   forwardzDETRLoss.forward   s     "((

?D9',U|U8_eKFX9	^^KO$/O$-$*$-,32? $ A
 =="";s#3["5EyRXZcer#*,- r$   )P   NTTFFr   ) )Nr   NN)NNr   N)__name__
__module____qualname____doc__r   rD   rX   rl   staticmethodrv   r}   rd   r   __classcell__r"   s   @r#   r	   r	      sw    ( $  DJ,9r %)  "/b - -*   $$Lr$   r	   c                   4     e Zd ZdZd fd	Zed        Z xZS )RTDETRDetectionLossa#  
    Real-Time DeepTracker (RT-DETR) Detection Loss class that extends the DETRLoss.

    This class computes the detection loss for the RT-DETR model, which includes the standard detection loss as well as
    an additional denoising training loss when provided with denoising metadata.
    c           
         |\  }}t         |   |||      }|c|d   |d   }
}	t        |d         t        |	      k(  sJ | j                  |	|
|d         }t         |   |||d|      }|j	                  |       |S |j	                  |j                         D ci c]'  }| dt        j                  d| j                        ) c}       |S c c}w )aF  
        Forward pass to compute the detection loss.

        Args:
            preds (tuple): Predicted bounding boxes and scores.
            batch (dict): Batch data containing ground truth information.
            dn_bboxes (torch.Tensor, optional): Denoising bounding boxes. Default is None.
            dn_scores (torch.Tensor, optional): Denoising scores. Default is None.
            dn_meta (dict, optional): Metadata for denoising. Default is None.

        Returns:
            (dict): Dictionary containing the total loss and, if applicable, the denoising loss.
        
dn_pos_idxdn_num_grouprf   _dnr   rH   rI   )	r   r   rL   get_dn_match_indicesr   keysr-   rM   r   )r   predsr   	dn_bboxes	dn_scoresdn_metarQ   r:   r   r   r   r^   dn_lossrV   r"   s                 r#   r   zRTDETRDetectionLoss.forward  s     $) [W_[+uE
 '.|'<gn>UJu[)*c*o=== !55j,PUVaPbcM goiE5`monGg&
  XbXgXgXijXiST!Cy%,,r$++*NNXijk ks   ,Cc                 h   g }t        j                  dg|dd       j                  d      }t        |      D ]  \  }}|dkD  rt        j                  |t         j
                        ||   z   }|j                  |      }t        | |         t        |      k(  sJ d       dt        | |          dt        |       d |j                  | |   |f       |j                  t        j                  dgt         j
                  	      t        j                  dgt         j
                  	      f        |S )
a  
        Get the match indices for denoising.

        Args:
            dn_pos_idx (List[torch.Tensor]): List of tensors containing positive indices for denoising.
            dn_num_group (int): Number of denoising groups.
            gt_groups (List[int]): List of integers representing the number of ground truths for each image.

        Returns:
            (List[tuple]): List of tuples containing matched indices for denoising.
        r   Nr(   )endr'   zExpected the same length, zbut got z and z respectively.)r'   )
r-   	as_tensorcumsum_rb   arangelongrepeatrL   appendr.   )r   r   rf   dn_match_indices
idx_groupsrg   num_gtr   s           r#   r   z(RTDETRDetectionLoss.get_dn_match_indices>  s    __a%9)CR.%9:BB1E
"9-IAvz&

CjQRmS|4:a=)S[8V:VV83z!}-.eCK=O ''A(?@ ''aS

)KU[[Z[Y\didndnMo(pq .  r$   )NNN)r   r   r   r   r   r   r   r   r   s   @r#   r   r     s"     D    r$   r   )r-   torch.nnr5   torch.nn.functional
functionalrN   ultralytics.utils.lossr   r   ultralytics.utils.metricsr   opsr   Moduler	   r    r$   r#   <module>r      s=        ; . !Dryy DNB ( B r$   