a
    yf=                     @   st   d dl Z d dlmZ d dlm  mZ d dlmZmZ d dl	m
Z
 ddlmZ G dd dejZG dd	 d	eZdS )
    N)	FocalLossVarifocalLoss)bbox_iou   )HungarianMatcherc                       sh   e Zd ZdZd fdd	Zdd
dZdddZdddZedd Z	dd Z
dddZdddZ  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.
    P   NTFr   c                    s   t    |du r$ddddddd}|| _tddddd| _|| _|| _|rTt nd| _|rdt	 nd| _
|| _|| _d| _dS )	a  
        Initialize DETR loss function with customizable components and gains.

        Uses default loss_gain if not provided. Initializes HungarianMatcher with
        preset cost gains. Supports auxiliary losses and various loss types.

        Args:
            nc (int): Number of classes.
            loss_gain (dict): Coefficients for different loss components.
            aux_loss (bool): Use auxiliary losses from each decoder layer.
            use_fl (bool): Use FocalLoss.
            use_vfl (bool): Use VarifocalLoss.
            use_uni_match (bool): Use fixed layer for auxiliary branch label assignment.
            uni_match_ind (int): Index of fixed layer for uni_match.
        Nr         g?)classbboxgiouZ	no_objectmaskZdice)r   r   r   )Z	cost_gain)super__init__ncr   matcher	loss_gainaux_lossr   flr   vfluse_uni_matchuni_match_inddevice)selfr   r   r   Zuse_flZuse_vflr   r   	__class__ Y/var/www/html/django/DPS/env/lib/python3.9/site-packages/ultralytics/models/utils/loss.pyr   !   s    
zDETRLoss.__init__ c                 C   s   d| }|j dd \}}tj||| jd ftj|jd}	|	d|dd |	dddf }	|||d|	 }| j	r|r| j
r| 
|||	}
n| 	||	 }
|
t|d|  }
ntjdd	||d }
||
 | jd
  iS )z^Computes the classification loss based on predictions, target values, and ground truth scores.
loss_classNr
   r   )dtyper   .noneZ	reductionr   )shapetorchzerosr   Zint64r   Zscatter_Z	unsqueezeviewr   r   floatmaxnnZBCEWithLogitsLossmeansumsqueezer   )r   pred_scorestargets	gt_scoresZnum_gtspostfixZ
name_classbsnqZone_hotZloss_clsr   r   r   _get_loss_classB   s    
 
zDETRLoss._get_loss_classc                 C   s   d| }d| }i }t |dkrPtjd| jd||< tjd| jd||< |S | jd tj||dd t | ||< d	t||d
d
d ||< ||  t | ||< | jd ||  ||< dd |	 D S )zTComputes bounding box and GIoU losses for predicted and ground truth bounding boxes.	loss_bbox	loss_giour           r   r   r-   r$   g      ?T)xywhZGIoUr   c                 S   s   i | ]\}}||  qS r   )r.   ).0kvr   r   r   
<dictcomp>h       z+DETRLoss._get_loss_bbox.<locals>.<dictcomp>)
lenr&   tensorr   r   FZl1_lossr   r-   items)r   pred_bboxes	gt_bboxesr2   Z	name_bboxZ	name_gioulossr   r   r   _get_loss_bboxX   s    

&zDETRLoss._get_loss_bboxc
                 C   s,  t j|durdnd|jd}
|du r`| jr`| j|| j || j ||||durV|| j nd|	d}tt||D ]\}\}}|dur|| nd}| j|||||||	||d	}|
d  |d|  7  < |
d	  |d
|  7  < |
d  |d|  7  < qnd| |
d d| |
d	 d| |
d i}
|
S )zGet auxiliary losses.Nr	      r9   masksgt_mask)rJ   rK   r2   match_indicesr   r    r   r6   r
   r7   Zloss_class_auxZloss_bbox_auxZloss_giou_aux)	r&   r'   r   r   r   r   	enumeratezip	_get_loss)r   rD   r/   rE   gt_cls	gt_groupsrL   r2   rJ   rK   rF   iZ
aux_bboxesZ
aux_scoresZ	aux_masksZloss_r   r   r   _get_loss_aux   s@    	zDETRLoss._get_loss_auxc                 C   sL   t dd t| D }t dd | D }t dd | D }||f|fS )z[Returns batch indices, source indices, and destination indices from provided match indices.c                 S   s    g | ]\}\}}t ||qS r   )r&   Z	full_like)r;   rR   src_r   r   r   
<listcomp>   r?   z'DETRLoss._get_index.<locals>.<listcomp>c                 S   s   g | ]\}}|qS r   r   )r;   rT   rU   r   r   r   rV      r?   c                 S   s   g | ]\}}|qS r   r   )r;   rU   dstr   r   r   rV      r?   )r&   catrM   )rL   Z	batch_idxZsrc_idxZdst_idxr   r   r   
_get_index   s    zDETRLoss._get_indexc                    sD   t  fddt||D }t  fddt||D }||fS )z[Assigns predicted bounding boxes to ground truth bounding boxes based on the match indices.c                    s@   g | ]8\}\}}t |d kr$|| ntjd |jd  jdqS r   r"   r9   r@   r&   r'   r%   r   )r;   trR   rU   r   r   r   rV      s   
z1DETRLoss._get_assigned_bboxes.<locals>.<listcomp>c                    s@   g | ]8\}\}}t |d kr$|| ntjd |jd  jdqS rZ   r[   )r;   r\   rU   jr]   r   r   rV      s   
)r&   rX   rN   )r   rD   rE   rL   Zpred_assignedZgt_assignedr   r]   r   _get_assigned_bboxes   s    

zDETRLoss._get_assigned_bboxesc
              	   C   s   |	du r | j |||||||d}	| |	\}
}||
 ||  }}|jdd \}}tj||f| j|j|jd}|| ||
< tj||g|jd}t	|rt
| |ddd||
< i }|| |||t	|| || ||| |S )	zGet losses.NrI   r
   )r   r!   r9   T)r:   r"   )r   rY   r%   r&   fullr   r   r!   r'   r@   r   detachr.   updater5   rG   )r   rD   r/   rE   rP   rQ   rJ   rK   r2   rL   idxgt_idxr3   r4   r0   r1   rF   r   r   r   rO      s     zDETRLoss._get_lossc                 K   s   |j | _ |dd}|d |d |d   }}}	| j|d |d |||	||d}
| jr|
| |dd |dd |||	|| |
S )a  
        Calculate loss for predicted bounding boxes and scores.

        Args:
            pred_bboxes (torch.Tensor): Predicted bounding boxes, shape [l, b, query, 4].
            pred_scores (torch.Tensor): Predicted class scores, shape [l, b, query, num_classes].
            batch (dict): Batch information containing:
                cls (torch.Tensor): Ground truth classes, shape [num_gts].
                bboxes (torch.Tensor): Ground truth bounding boxes, shape [num_gts, 4].
                gt_groups (List[int]): Number of ground truths for each image in the batch.
            postfix (str): Postfix for loss names.
            **kwargs (Any): Additional arguments, may include 'match_indices'.

        Returns:
            (dict): Computed losses, including main and auxiliary (if enabled).

        Note:
            Uses last elements of pred_bboxes and pred_scores for main loss, and the rest for auxiliary losses if
            self.aux_loss is True.
        rL   NclsZbboxesrQ   r"   r2   rL   )r   getrO   r   rb   rS   )r   rD   r/   batchr2   kwargsrL   rP   rE   rQ   
total_lossr   r   r   forward   s    zDETRLoss.forward)r   NTTFFr   )r   )r   )Nr   NN)NNr   N)r   )__name__
__module____qualname____doc__r   r5   rG   rS   staticmethodrY   r_   rO   rk   __classcell__r   r   r   r   r      s&    !

8    
8
    
$r   c                       s.   e Zd ZdZd fdd	Zedd Z  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.
    Nc                    s   |\}}t  |||}|dur~|d |d  }	}
t|d t|	ksJJ  |	|
|d }t  j|||d|d}|| n| fdd| D  |S )	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.
        N
dn_pos_idxdn_num_grouprQ   _dnrf   c                    s$   i | ]}| d t jd jdqS )ru   r8   r9   )r&   rA   r   )r;   r<   r]   r   r   r>   J  r?   z/RTDETRDetectionLoss.forward.<locals>.<dictcomp>)r   rk   r@   get_dn_match_indicesrb   keys)r   predsrh   Z	dn_bboxesZ	dn_scoresZdn_metarD   r/   rj   rs   rt   rL   Zdn_lossr   r]   r   rk   ,  s    zRTDETRDetectionLoss.forwardc                 C   s   g }t dg|dd d}t|D ]\}}|dkrt j|t jd||  }||}t| | t|ksxJ ddt| |  dt| d || | |f q*|t j	dgt jd	t j	dgt jd	f q*|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&   Z	as_tensorZcumsum_rM   Zarangelongrepeatr@   appendr'   )rs   rt   rQ   Zdn_match_indicesZ
idx_groupsrR   Znum_gtrd   r   r   r   rv   N  s    
,z(RTDETRDetectionLoss.get_dn_match_indices)NNN)rl   rm   rn   ro   rk   rp   rv   rq   r   r   r   r   rr   $  s   "rr   )r&   Ztorch.nnr+   Ztorch.nn.functionalZ
functionalrB   Zultralytics.utils.lossr   r   Zultralytics.utils.metricsr   opsr   Moduler   rr   r   r   r   r   <module>   s     