
    FPhd                     r   d dl Z d dlmZ d dlmc mZ d dlmZ d dlm	Z	m
Z
mZ d dlmZmZmZ ddlmZ ddlmZ  G d d	ej(                        Z G d
 dej(                        Z G d dej(                        Z G d dej(                        Z G d d      Z G d de      Z G d de      Z G d d      Zy)    N)	OKS_SIGMA)	crop_mask	xywh2xyxy	xyxy2xywh)TaskAlignedAssigner	dist2bboxmake_anchors   )bbox_iou)	bbox2distc                   4     e Zd ZdZ fdZedd       Z xZS )VarifocalLosszO
    Varifocal loss by Zhang et al.

    https://arxiv.org/abs/2008.13367.
    c                 "    t         |           y)z#Initialize the VarifocalLoss class.Nsuper__init__self	__class__s    aC:\Users\daisl\Desktop\realtime-object-detection\venv\Lib\site-packages\ultralytics/utils/loss.pyr   zVarifocalLoss.__init__           c                    || j                         j                  |      z  d|z
  z  ||z  z   }t        j                  j                  j                  d      5  t        j                  | j                         |j                         d      |z  j                  d      j                         }ddd       |S # 1 sw Y   S xY w)zComputes varfocal loss.r
   F)enablednone	reductionN)sigmoidpowtorchcudaampautocastF binary_cross_entropy_with_logitsfloatmeansum)
pred_scoregt_scorelabelalphagammaweightlosss          r   forwardzVarifocalLoss.forward   s     ++-11%88AIFTYIYYZZ^^$$U$366z7G7G7I8>>K[gmn DGCCE  4  4 s   AB88C)g      ?       @__name__
__module____qualname____doc__r   staticmethodr0   __classcell__r   s   @r   r   r      s!      r   r   c                   4     e Zd ZdZ fdZedd       Z xZS )	FocalLosszjWraps focal loss around existing loss_fcn(), i.e. criteria = FocalLoss(nn.BCEWithLogitsLoss(), gamma=1.5).c                 "    t         |           y)z3Initializer for FocalLoss class with no parameters.Nr   r   s    r   r   zFocalLoss.__init__'   r   r   c                    t        j                  | |d      }| j                         }||z  d|z
  d|z
  z  z   }d|z
  |z  }||z  }|dkD  r||z  d|z
  d|z
  z  z   }||z  }|j                  d      j	                         S )zRCalculates and updates confusion matrix for object detection/classification tasks.r   r   r
         ?r   )r$   r%   r   r'   r(   )	predr+   r-   r,   r/   	pred_probp_tmodulating_factoralpha_factors	            r   r0   zFocalLoss.forward+   s     11$P
 LLN	i1u9Y"?? 3Y50!!19 5=AI!e)+DDLL Dyy|!!r   )g      ?g      ?r2   r9   s   @r   r;   r;   $   s    t " "r   r;   c                   :     e Zd ZdZd fd	Zd Zed        Z xZS )BboxLossz>Criterion class for computing training losses during training.c                 >    t         |           || _        || _        y)zLInitialize the BboxLoss module with regularization maximum and DFL settings.N)r   r   reg_maxuse_dfl)r   rG   rH   r   s      r   r   zBboxLoss.__init__@   s    r   c                    |j                  d      |   j                  d      }t        ||   ||   dd      }	d|	z
  |z  j                         |z  }
| j                  rft	        ||| j
                        }| j                  ||   j                  d| j
                  dz         ||         |z  }|j                         |z  }|
|fS t        j                  d      j                  |j                        }|
|fS )z	IoU loss.FT)xywhCIoUr>   r
   g        )r(   	unsqueezer   rH   r   rG   _df_lossviewr    tensortodevice)r   	pred_distpred_bboxesanchor_pointstarget_bboxestarget_scorestarget_scores_sumfg_maskr.   iouloss_ioutarget_ltrbloss_dfls                r   r0   zBboxLoss.forwardF   s    ""2&w/99"={7+]7-C%VZ[3Y&(--/2CC <<#M=$,,OK}}Yw%7%<%<RPQAQ%RT_`gThilrrH||~(99H !! ||C(++I,<,<=H!!r   c                 p   |j                         }|dz   }||z
  }d|z
  }t        j                  | |j                  d      d      j                  |j                        |z  t        j                  | |j                  d      d      j                  |j                        |z  z   j                  dd      S )z(Return sum of left and right DFL losses.r
   rJ   r   r   Tkeepdim)longr$   cross_entropyrO   shaper'   )rS   targettltrwlwrs         r   rN   zBboxLoss._df_lossV   s     [[]!V&[V	2772;&INNrxxX[]]	2772;&INNrxxX[]]^_c_cdfpt_c_u	vr   )F)	r3   r4   r5   r6   r   r0   r7   rN   r8   r9   s   @r   rE   rE   =   s&    H"  v vr   rE   c                   *     e Zd ZdZd fdZd Z xZS )KeypointLoss.Criterion class for computing training losses.c                 0    t         |           || _        y)z"Initialize the KeypointLoss class.N)r   r   sigmas)r   rm   r   s     r   r   zKeypointLoss.__init__e   s    r   c                 L   |d   |d   z
  dz  |d   |d   z
  dz  z   }|j                   d   t        j                  |dk7  d      dz   z  }|d| j                  z  dz  z  |dz   z  dz  }|j	                  dd      dt        j
                  |       z
  |z  z  j                         S )	z_Calculates keypoint loss factor and Euclidean distance loss for predicted and actual keypoints..r      .r
   r
   r   dimg&.>rJ   )rc   r    r(   rm   rO   expr'   )r   	pred_kptsgt_kptskpt_maskareadkpt_loss_factores           r   r0   zKeypointLoss.forwardj   s    v0Q6)F:KgV\o:]bc9cc"..+uyyQA/NQU/UVT[[Q&&$+6:$$R+EIIqbM0AX/MNTTVVr   )returnN)r3   r4   r5   r6   r   r0   r8   r9   s   @r   rj   rj   b   s    8
Wr   rj   c                   (    e Zd ZdZd Zd Zd Zd Zy)v8DetectionLossrk   c                    t        |j                               j                  }|j                  }|j                  d   }t        j                  d      | _        || _        |j                  | _	        |j                  | _
        |j                  | _        |j                  | _        || _        |j                  dkD  | _        t        d| j                  dd      | _        t!        |j                  dz
  | j                  	      j#                  |      | _        t'        j(                  |j                  t&        j*                  |
      | _        y)zdInitializes v8DetectionLoss with the model, defining model-related properties and BCE loss function.rJ   r   r   r
   
         ?g      @)topknum_classesr,   beta)rH   )dtyperR   N)next
parametersrR   argsmodelnnBCEWithLogitsLossbcehypstridencnorG   rH   r   assignerrE   rQ   	bbox_lossr    aranger&   proj)r   r   rR   hms        r   r   zv8DetectionLoss.__init__v   s    e&&()00JJKKO''&9hh$$$$yyyy1}+PSZ]^!!))a-FII&QLL%++fM	r   c                    |j                   d   dk(  r%t        j                  |dd| j                        }|S |dddf   }|j	                  d      \  }}|j                  t        j                        }t        j                  ||j                         d| j                        }t        |      D ]*  }||k(  }	|	j                         }
|
s||	ddf   ||d|
f<   , t        |d	ddf   j                  |            |d	ddf<   |S )
zXPreprocesses the target counts and matches with the input batch size to output a tensor.r      rR   NTreturn_counts)r   r
   .)rc   r    zerosrR   uniquerQ   int32maxranger(   r   mul_)r   targets
batch_sizescale_tensorouti_countsjmatchesns              r   
preprocesszv8DetectionLoss.preprocess   s    ==q ++j!Qt{{CC 
 1At4IAvYYU[[Y1F++j&**,$++NC:&q&KKM!(!"!5C2A2J	 '
 &c#qs(m&8&8&FGCQqSM
r   c                    | j                   rh|j                  \  }}}|j                  ||d|dz        j                  d      j	                  | j
                  j                  |j                              }t        ||d      S )zUDecode predicted object bounding box coordinates from anchor points and distribution.      F)rK   )	rH   rc   rO   softmaxmatmulr   typer   r   )r   rU   rS   bacs         r   bbox_decodezv8DetectionLoss.bbox_decode   sk    <<ooGAq!!q!QQ7??BII$))..YbYhYhJijI M>>r   c           
      <   t        j                  d| j                        }t        |t              r|d   n|}t        j
                  |D cg c]/  }|j                  |d   j                  d   | j                  d      1 c}d      j                  | j                  dz  | j                  fd      \  }}|j                  ddd      j                         }|j                  ddd      j                         }|j                  }|j                  d   }	t        j                  |d   j                  dd | j                  |	      | j                   d   z  }
t#        || j                   d
      \  }}t        j
                  |d   j                  dd      |d   j                  dd      |d   fd      }| j%                  |j'                  | j                        |	|
g d         }|j                  dd      \  }}|j)                  dd      j+                  d      }| j-                  ||      }| j/                  |j1                         j3                         |j1                         |z  j5                  |j                        ||z  |||      \  }}}}}t7        |j)                         d      }| j9                  ||j'                  |            j)                         |z  |d<   |j)                         r%||z  }| j;                  |||||||      \  |d<   |d<   |dxx   | j<                  j>                  z  cc<   |dxx   | j<                  j@                  z  cc<   |dxx   | j<                  jB                  z  cc<   |j)                         |	z  |j1                         fS c c}w )zLCalculate the sum of the loss for box, cls and dfl multiplied by batch size.r   r   r
   r   rJ   rp   r   NrR   r   r   	batch_idxclsbboxesr
   r   r
   r   r   r
   r   Tr_   )"r    r   rR   
isinstancetuplecatrO   rc   r   splitrG   r   permute
contiguousr   rP   r   r	   r   rQ   r(   gt_r   r   detachr   r   r   r   r   r   boxr   dfl)r   predsbatchr/   featsxipred_distripred_scoresr   r   imgszrU   stride_tensorr   	gt_labels	gt_bboxesmask_gtrT   r   rV   rW   rY   rX   s                          r   __call__zv8DetectionLoss.__call__   s<   {{1T[[1&ue4a%#(99`e-f`eZ\bggeAhnnQ6GRT.U`e-fhi#j#p#p\\Atww'$, [ "))!Q2==?!))!Q2==?!! &&q)
U1X^^AB/5QTXT_T_`aTbb'3E4;;'L$} ))U;/44R;U5\=N=NrST=UW\]eWfgijk//'**T[["9:TYZfTg/h&}}VQ7	9--4-044Q7 &&}kB6:mm ((*[-?-?-AM-Q,W,WXaXgXg,hM)9i7J3=-!   1 1 3Q7 ((;(8(8(?@DDFIZZQ ;;=]*M#~~k;Wdfs.? JDGT!W 	Q488<<Q488<<Q488<<xxzJ&55Q .gs   4NN)r3   r4   r5   r6   r   r   r   r    r   r   r~   r~   s   s    8N("?,6r   r~   c                       e Zd ZdZ fdZd Zedej                  dej                  dej                  dej                  dej                  d	ej                  fd
       Z	dej                  dej                  dej                  dej                  dej                  dej                  dej                  dej                  de
d	ej                  fdZ xZS )v8SegmentationLossrk   c                 Z    t         |   |       |j                  j                  | _        y)zSInitializes the v8SegmentationLoss class, taking a de-paralleled model as argument.N)r   r   r   overlap_maskoverlap)r   r   r   s     r   r   zv8SegmentationLoss.__init__   s!    zz..r   c                 	   t        j                  d| j                        }t        |      dk(  r|n|d   \  }}}|j                  \  }}}	}
t        j
                  |D cg c]/  }|j                  |d   j                  d   | j                  d      1 c}d      j                  | j                  dz  | j                  fd      \  }}|j                  ddd      j                         }|j                  ddd      j                         }|j                  ddd      j                         }|j                  }t        j                  |d   j                  dd | j                  |	      | j                  d   z  }t!        || j                  d
      \  }}	 |d   j                  dd      }t        j
                  ||d   j                  dd      |d   fd      }| j#                  |j%                  | j                        ||g d         }|j                  dd      \  }}|j'                  dd      j)                  d      }| j/                  ||      }| j1                  |j3                         j5                         |j3                         |z  j7                  |j                        ||z  |||      \  }}}}}t9        |j'                         d      }| j;                  ||j%                  |            j'                         |z  |d<   |j'                         r| j=                  |||||z  |||      \  |d<   |d<   |d   j%                  | j                        j?                         }tA        |j                  dd       |	|
fk7  r tC        jD                  |d   |	|
fd      d   }| jG                  ||||||||| jH                  	      |d<   n2|dxx   |dz  j'                         |dz  j'                         z   z  cc<   |dxx   | jJ                  jL                  z  cc<   |dxx   | jJ                  jL                  z  cc<   |dxx   | jJ                  jN                  z  cc<   |dxx   | jJ                  jP                  z  cc<   |j'                         |z  |j3                         fS c c}w # t*        $ r}t-        d      |d}~ww xY w)z1Calculate and return the loss for the YOLO model.r   r   r   r
   r   rJ   rp   Nr   r   r   r   r   r   r   r   Tr_   u  ERROR ❌ segment dataset incorrectly formatted or not a segment dataset.
This error can occur when incorrectly training a 'segment' model on a 'detect' dataset, i.e. 'yolo train model=yolov8n-seg.pt data=coco128.yaml'.
Verify your dataset is a correctly formatted 'segment' dataset using 'data=coco128-seg.yaml' as an example.
See https://docs.ultralytics.com/tasks/segment/ for help.masksnearest)mode))r    r   rR   lenrc   r   rO   r   r   rG   r   r   r   r   rP   r   r	   r   rQ   r(   r   RuntimeError	TypeErrorr   r   r   r   r   r   r   r   r&   r   r$   interpolatecalculate_segmentation_lossr   r   r   r   r   )r   r   r   r/   r   
pred_masksprotor   r   mask_hmask_wr   r   r   r   r   rU   r   r   r   r   r   r   r{   rT   rV   rW   rY   target_gt_idxrX   r   s                                  r   r   zv8SegmentationLoss.__call__   se   {{1T[[1,/J!O5q z5(-%
Avv#(99`e-f`eZ\bggeAhnnQ6GRT.U`e-fhi#j#p#p\\Atww'$, [ "))!Q2==?!))!Q2==?''1a0;;=
!!U1X^^AB/5QTXT_T_`aTbb'3E4;;'L$}	pk*//A6IiiE%L,=,=b!,DeHo VXYZGoogjj&=zX]^jXkolG#*==#; IymmAtm488;G &&}kBBF-- ((*[-?-?-AM-Q,W,WXaXgXg,hM)9iCJ?=--   1 1 3Q7 ((;(8(8(?@DDFIZZQ;;=#~~k;WdgtWt.;=NPW YDGT!W 'N%%dkk288:EU[[%&66*::eDkFF3C)TUVW66w}Vcenpu7A5$,,XDG
 G	(JN+?+?+AAAGQ488<<Q488<<Q488<<Q488<<xxzJ&55y .g&  	p h i op	p	ps   4R"B-R' '	S0R<<Sgt_maskr?   r   xyxyrx   r|   c                     t        j                  d||      }t        j                  || d      }t	        ||      j                  d      |z  j                         S )aX  
        Compute the instance segmentation loss for a single image.

        Args:
            gt_mask (torch.Tensor): Ground truth mask of shape (n, H, W), where n is the number of objects.
            pred (torch.Tensor): Predicted mask coefficients of shape (n, 32).
            proto (torch.Tensor): Prototype masks of shape (32, H, W).
            xyxy (torch.Tensor): Ground truth bounding boxes in xyxy format, normalized to [0, 1], of shape (n, 4).
            area (torch.Tensor): Area of each ground truth bounding box of shape (n,).

        Returns:
            (torch.Tensor): The calculated mask loss for a single image.

        Notes:
            The function uses the equation pred_mask = torch.einsum('in,nhw->ihw', pred, proto) to produce the
            predicted masks from the prototype masks and predicted mask coefficients.
        zin,nhw->ihwr   r   )r
   rp   rr   )r    einsumr$   r%   r   r'   r(   )r   r?   r   r   rx   	pred_maskr/   s          r   single_mask_lossz#v8SegmentationLoss.single_mask_loss  sT    ( LLe<	11)WPVW$%**v*6=BBDDr   rY   r   r   rV   r   r   r   r   c
                    |j                   \  }
}
}}d}||g d   z  }t        |      dddf   j                  d      }|t        j                  ||||g|j
                        z  }t        t        |||||||            D ]  \  }}|\  }}}}}}}|j                         rm||   }|	r*||dz   j                  ddd      k(  }|j                         }n||j                  d      |k(     |   }|| j                  |||   |||   ||         z  }||dz  j                         |dz  j                         z   z  } ||j                         z  S )	aF  
        Calculate the loss for instance segmentation.

        Args:
            fg_mask (torch.Tensor): A binary tensor of shape (BS, N_anchors) indicating which anchors are positive.
            masks (torch.Tensor): Ground truth masks of shape (BS, H, W) if `overlap` is False, otherwise (BS, ?, H, W).
            target_gt_idx (torch.Tensor): Indexes of ground truth objects for each anchor of shape (BS, N_anchors).
            target_bboxes (torch.Tensor): Ground truth bounding boxes for each anchor of shape (BS, N_anchors, 4).
            batch_idx (torch.Tensor): Batch indices of shape (N_labels_in_batch, 1).
            proto (torch.Tensor): Prototype masks of shape (BS, 32, H, W).
            pred_masks (torch.Tensor): Predicted masks for each anchor of shape (BS, N_anchors, 32).
            imgsz (torch.Tensor): Size of the input image as a tensor of shape (2), i.e., (H, W).
            overlap (bool): Whether the masks in `masks` tensor overlap.

        Returns:
            (torch.Tensor): The calculated loss for instance segmentation.

        Notes:
            The batch loss can be computed for improved speed at higher memory usage.
            For example, pred_mask can be computed as follows:
                pred_mask = torch.einsum('in,nhw->ihw', pred, proto)  # (i, 32) @ (32, 160, 160) -> (i, 160, 160)
        r   r   .rp   Nr   r
   rJ   )rc   r   prodr    rP   rR   	enumeratezipanyrO   r&   r   r(   )r   rY   r   r   rV   r   r   r   r   r   r   r   r   r/   target_bboxes_normalizedmareamxyxyr   single_i	fg_mask_itarget_gt_idx_ipred_masks_iproto_imxyxy_imarea_imasks_imask_idxr   s                               r   r   z.v8SegmentationLoss.calculate_segmentation_loss6  s   D  %{{1ff $153F#F  23CG<AA!D )5<<QW8Xafamam+nn$S-UTY[`bg%hiKAx[cXIgwQX}}*95%(Q,)<)<RA)FFG%mmoG#INN2$6!$;<XFG--g|I7NPWY`ajYk.5i.@B B
 )Z!^,@,@,BBB j" gkkm##r   )r3   r4   r5   r6   r   r   r7   r    Tensorr   boolr   r8   r9   s   @r   r   r      s    8/
A6F E%,, Eell E5<< E_d_k_k E$||E05E E.?$?$ ||?$ ||	?$
 ||?$ <<?$ ||?$ LL?$ ||?$ ?$ 
?$r   r   c                   >     e Zd ZdZ fdZd Zed        Zd Z xZ	S )
v8PoseLossrk   c                    t         |   |       |j                  d   j                  | _        t	        j
                         | _        | j                  ddgk(  }| j                  d   }|r2t        j                  t              j                  | j                        n#t        j                  || j                        |z  }t        |      | _        y)zaInitializes v8PoseLoss with model, sets keypoint variables and declares a keypoint loss instance.rJ      r   r   r   )rm   N)r   r   r   	kpt_shaper   r   bce_poser    
from_numpyr   rQ   rR   onesrj   keypoint_loss)r   r   is_posenkptrm   r   s        r   r   zv8PoseLoss.__init__{  s    R22,,...RG+~~a @G!!),//<UZZX\eiepepMqtxMx)8r   c           
      b	   t        j                  d| j                        }t        |d   t              r|n|d   \  }}t        j
                  |D cg c]/  }|j                  |d   j                  d   | j                  d      1 c}d      j                  | j                  dz  | j                  fd      \  }}|j                  ddd      j                         }|j                  ddd      j                         }|j                  ddd      j                         }|j                  }	t        j                  |d   j                  dd | j                  |		      | j                   d   z  }
t#        || j                   d
      \  }}|j                  d   }|d   j                  dd      }t        j
                  ||d   j                  dd      |d   fd      }| j%                  |j'                  | j                        ||
g d         }|j                  dd      \  }}|j)                  dd      j+                  d      }| j-                  ||      }| j/                  | |j                  |dg| j0                         }| j3                  |j5                         j7                         |j5                         |z  j9                  |j                        ||z  |||      \  }}}}}t;        |j)                         d      }| j=                  ||j'                  |	            j)                         |z  |d<   |j)                         r||z  }| j?                  |||||||      \  |d<   |d<   |d   j'                  | j                        jA                         jC                         }|dxx   |
d   z  cc<   |dxx   |
d   z  cc<   | jE                  |||||||      \  |d<   |d<   |dxx   | jF                  jH                  z  cc<   |dxx   | jF                  jJ                  z  cc<   |dxx   | jF                  jL                  z  cc<   |dxx   | jF                  jN                  z  cc<   |dxx   | jF                  jP                  z  cc<   |j)                         |z  |j5                         fS c c}w )z'Calculate the total loss and detach it.r   r   r   r
   rJ   rp   r   Nr   r   r   r   r   r   r   r   Tr_   r   	keypointsro   rq   ))r    r   rR   r   listr   rO   rc   r   r   rG   r   r   r   r   rP   r   r	   r   rQ   r(   r   r   kpts_decoder  r   r   r   r   r   r   r   r&   clonecalculate_keypoints_lossr   r   posekobjr   r   )r   r   r   r/   r   ru   r   r   r   r   r   rU   r   r   r   r   r   r   r   rT   r   rV   rW   rY   r   rX   r  s                              r   r   zv8PoseLoss.__call__  s>   {{1T[[1$.uQx$>5E!Hy#(99`e-f`eZ\bggeAhnnQ6GRT.U`e-fhi#j#p#p\\Atww'$, [ "))!Q2==?!))!Q2==?%%aA.99;	!!U1X^^AB/5QTXT_T_`aTbb'3E4;;'L$} !&&q)
+&++B2	))Ye(9(9"a(@%/RTUV//'**T[["9:TYZfTg/h&}}VQ7	9--4-044Q7 &&}kB$$]NINN:r4cTXTbTb4cd	BF-- ((*[-?-?-AM-Q,W,WXaXgXg,hM)9iCJ?=--   1 1 3Q7 ((;(8(8(?@DDFIZZQ ;;=]*M#~~k;Wdfs.? JDGT!Wk*--dkk:@@BHHJIfq)fq)#<<WmU^`i=JM[d fDGT!W 	Q488<<Q488== Q488== Q488<<Q488<<xxzJ&55i .gs   4R,c                     |j                         }|dddfxx   dz  cc<   |dxx   | dddgf   dz
  z  cc<   |dxx   | ddd	gf   dz
  z  cc<   |S )
z1Decodes predicted keypoints to image coordinates..Nrp   r1   ro   r   r   rq   r
   )r  )rU   ru   ys      r   r  zv8PoseLoss.kpts_decode  sg     OO	#rr'
c
	&	]1qc6*S00		&	]1qc6*S00	r   c           
         |j                         }t        |      }t        j                  |d      d   j	                         }	t        j
                  ||	|j                  d   |j                  d   f|j                        }
t        |      D ]   }|||k(     }||
|d|j                  d   f<   " |j                  d      j                  d      }|
j                  d|j                  dd|j                  d   |j                  d               }||j                  dddd      z  }d}d}|j                         r||   }t        ||         ddddf   j                  dd	      }||   }|j                  d   d
k(  r|d   dk7  nt        j                   |d   d      }| j#                  ||||      }|j                  d   d
k(  r#| j%                  |d   |j'                               }||fS )aZ  
        Calculate the keypoints loss for the model.

        This function calculates the keypoints loss and keypoints object loss for a given batch. The keypoints loss is
        based on the difference between the predicted keypoints and ground truth keypoints. The keypoints object loss is
        a binary classification loss that classifies whether a keypoint is present or not.

        Args:
            masks (torch.Tensor): Binary mask tensor indicating object presence, shape (BS, N_anchors).
            target_gt_idx (torch.Tensor): Index tensor mapping anchors to ground truth objects, shape (BS, N_anchors).
            keypoints (torch.Tensor): Ground truth keypoints, shape (N_kpts_in_batch, N_kpts_per_object, kpts_dim).
            batch_idx (torch.Tensor): Batch index tensor for keypoints, shape (N_kpts_in_batch, 1).
            stride_tensor (torch.Tensor): Stride tensor for anchors, shape (N_anchors, 1).
            target_bboxes (torch.Tensor): Ground truth boxes in (x1, y1, x2, y2) format, shape (BS, N_anchors, 4).
            pred_kpts (torch.Tensor): Predicted keypoints, shape (BS, N_anchors, N_kpts_per_object, kpts_dim).

        Returns:
            (tuple): Returns a tuple containing:
                - kpts_loss (torch.Tensor): The keypoints loss.
                - kpts_obj_loss (torch.Tensor): The keypoints object loss.
        Tr   r
   rp   r   Nr   rJ   r_   r   ).rp   ro   )flattenr   r    r   r   r   rc   rR   r   rM   gatherexpandrO   r   r   r   	full_liker  r  r&   )r   r   r   r  r   r   rV   ru   r   max_kptsbatched_keypointsr   keypoints_itarget_gt_idx_expandedselected_keypoints	kpts_losskpts_obj_lossgt_kptrx   pred_kptrw   s                        r   r  z#v8PoseLoss.calculate_keypoints_loss  s   . %%'	Z
 <<	>qAEEG "KKXyq?QS\SbSbcdSe(f/8/?/?A
 z"A#IN3K:Ea!6+"3"3A"6!667 #
 "/!8!8!<!F!Fr!J /55%,,RY__Q5GYZI[\^ 	m00B1==	99;'.F]5121ab59>>q$>OD 'H.4ll2.>!.Cvf~*Y_`fYgimInH**8VXtLI~~b!Q& $hv.>@P Q-''r   )
r3   r4   r5   r6   r   r   r7   r  r  r8   r9   s   @r   r  r  x  s*    8986t  >(r   r  c                       e Zd ZdZd Zy)v8ClassificationLossrk   c                     t         j                  j                  j                  ||d   d      dz  }|j	                         }||fS )zDCompute the classification loss between predictions and true labels.r   r(   r   @   )r    r   
functionalrb   r   )r   r   r   r/   
loss_itemss        r   r   zv8ClassificationLoss.__call__  sD    xx""00ePU0VY[[[[]
Zr   N)r3   r4   r5   r6   r   r   r   r   r'  r'  	  s
    8 r   r'  )r    torch.nnr   torch.nn.functionalr*  r$   ultralytics.utils.metricsr   ultralytics.utils.opsr   r   r   ultralytics.utils.talr   r   r	   metricsr   talr   Moduler   r;   rE   rj   r~   r   r  r'  r   r   r   <module>r4     s        / A A N N  BII *"		 "2"vryy "vJW299 W"]6 ]6@b$ b$JN( N(b   r   