
    h                    6   S SK Jr  S SKJr  S SKrS SKJr  S SKJs  Jr	  S SK
Jr  S SKJrJrJr  S SKJrJrJrJrJr  S SKJr  SS	KJrJr  SS
KJr   " S S\R:                  5      r " S S\R:                  5      r " S S\R:                  5      r  " S S\R:                  5      r! " S S\!5      r" " S S\R:                  5      r# " S S5      r$ " S S\$5      r% " S S\$5      r& " S S5      r' " S S \$5      r( " S! S"5      r) " S# S$5      r* " S% S&\*5      r+g)'    )annotations)AnyN)	OKS_SIGMA)	crop_mask	xywh2xyxy	xyxy2xywh)RotatedTaskAlignedAssignerTaskAlignedAssigner	dist2bbox	dist2rboxmake_anchors)autocast   )bbox_iouprobiou)	bbox2distc                  >   ^  \ rS rSrSrSSU 4S jjjrSS jrSrU =r$ )	VarifocalLoss   a  
Varifocal loss by Zhang et al.

Implements the Varifocal Loss function for addressing class imbalance in object detection by focusing on
hard-to-classify examples and balancing positive/negative samples.

Attributes:
    gamma (float): The focusing parameter that controls how much the loss focuses on hard-to-classify examples.
    alpha (float): The balancing factor used to address class imbalance.

References:
    https://arxiv.org/abs/2008.13367
c                :   > [         TU ]  5         Xl        X l        g)zJInitialize the VarifocalLoss class with focusing and balancing parameters.N)super__init__gammaalphaselfr   r   	__class__s      P/home/james-whalen/.local/lib/python3.13/site-packages/ultralytics/utils/loss.pyr   VarifocalLoss.__init__#   s    

    c                t   U R                   UR                  5       R                  U R                  5      -  SU-
  -  X#-  -   n[	        SS9   [
        R                  " UR                  5       UR                  5       SS9U-  R                  S5      R                  5       nSSS5        U$ ! , (       d  f       W$ = f)z<Compute varifocal loss between predictions and ground truth.r   F)enablednone	reductionN)
r   sigmoidpowr   r   F binary_cross_entropy_with_logitsfloatmeansum)r   
pred_scoregt_scorelabelweightlosss         r   forwardVarifocalLoss.forward)   s    j00266tzzBBa%iPS[Scce$33J4D4D4FHXdjkntta  %  %$ s   AB((
B7r   r   )       @g      ?r   r*   r   r*   )r-   torch.Tensorr.   r7   r/   r7   returnr7   	__name__
__module____qualname____firstlineno____doc__r   r2   __static_attributes____classcell__r   s   @r   r   r      s     	 	r    r   c                  >   ^  \ rS rSrSrSSU 4S jjjrSS jrSrU =r$ )		FocalLoss5   a  
Wraps focal loss around existing loss_fcn(), i.e. criteria = FocalLoss(nn.BCEWithLogitsLoss(), gamma=1.5).

Implements the Focal Loss function for addressing class imbalance by down-weighting easy examples and focusing
on hard negatives during training.

Attributes:
    gamma (float): The focusing parameter that controls how much the loss focuses on hard-to-classify examples.
    alpha (torch.Tensor): The balancing factor used to address class imbalance.
c                d   > [         TU ]  5         Xl        [        R                  " U5      U l        g)zBInitialize FocalLoss class with focusing and balancing parameters.N)r   r   r   torchtensorr   r   s      r   r   FocalLoss.__init__A   s#    
\\%(
r    c                   [         R                  " XSS9nUR                  5       nX$-  SU-
  SU-
  -  -   nSU-
  U R                  -  nX6-  nU R                  S:  R                  5       (       a[  U R                  R                  UR                  UR                  S9U l        X R                  -  SU-
  SU R                  -
  -  -   nX7-  nUR                  S5      R                  5       $ )zACalculate focal loss with modulating factors for class imbalance.r#   r$   r         ?r   devicedtype)r(   r)   r&   r   r   anytorL   rM   r+   r,   )r   predr/   r1   	pred_probp_tmodulating_factoralpha_factors           r   r2   FocalLoss.forwardG   s    11$P
 LLN	1u9Y"?? 3Y4::5!JJN!!dkkLDJ ::-Uq4::~0NNL Dyy|!!r    r4   )g      ?g      ?r6   )rP   r7   r/   r7   r8   r7   r9   rA   s   @r   rC   rC   5   s    	) )" "r    rC   c                  >   ^  \ rS rSrSrSSU 4S jjjrSS jrSrU =r$ )	DFLossY   z<Criterion class for computing Distribution Focal Loss (DFL).c                .   > [         TU ]  5         Xl        g)z6Initialize the DFL module with regularization maximum.N)r   r   reg_maxr   rZ   r   s     r   r   DFLoss.__init__\   s    r    c                   UR                  SU R                  S-
  S-
  5      nUR                  5       nUS-   nXB-
  nSU-
  n[        R                  " XR                  S5      SS9R                  UR                  5      U-  [        R                  " XR                  S5      SS9R                  UR                  5      U-  -   R                  SSS9$ )	zZReturn sum of left and right DFL losses from https://ieeexplore.ieee.org/document/9792391.r   r   g{Gz?r#   r$   Tkeepdim)clamp_rZ   longr(   cross_entropyviewshaper+   )r   	pred_disttargettltrwlwrs          r   __call__DFLoss.__call__a   s    q$,,"2T"9:[[]!V[VOOIwwr{fEJJ288TWYYooiGLLRXXVY[[\
$r4$
 	!r    )rZ      )rZ   intr8   None)rf   r7   rg   r7   r8   r7   	r:   r;   r<   r=   r>   r   rl   r?   r@   rA   s   @r   rW   rW   Y   s    F 

! 
!r    rW   c                  ^   ^  \ rS rSrSrSSU 4S jjjr                SS jrSrU =r$ )	BboxLossn   zACriterion class for computing training losses for bounding boxes.c                ^   > [         TU ]  5         US:  a  [        U5      U l        gSU l        g)zLInitialize the BboxLoss module with regularization maximum and DFL settings.r   N)r   r   rW   dfl_lossr[   s     r   r   BboxLoss.__init__q   s%    +2Q;wDr    c                   UR                  S5      U   R                  S5      n[        X'   XG   SSS9n	SU	-
  U-  R                  5       U-  n
U R                  (       av  [	        X4U R                  R
                  S-
  5      nU R                  X   R                  SU R                  R
                  5      X   5      U-  nUR                  5       U-  nX4$ [        R                  " S5      R                  UR                  5      nX4$ )z.Compute IoU and DFL losses for bounding boxes.r^   FT)xywhCIoUrJ   r           )r,   	unsqueezer   rw   r   rZ   rd   rF   rG   rO   rL   r   rf   pred_bboxesanchor_pointstarget_bboxestarget_scorestarget_scores_sumfg_maskr0   iouloss_ioutarget_ltrbloss_dfls                r   r2   BboxLoss.forwardv   s     ""2&w/99"={+]-C%VZ[3Y&(--/2CC ==#M$--BWBWZ[B[\K}}Y%7%<%<RAVAV%WYdYmnqwwH||~(99H !! ||C(++I,<,<=H!!r    )rw   rn   rZ   rp   rf   r7   r   r7   r   r7   r   r7   r   r7   r   r7   r   r7   r8   !tuple[torch.Tensor, torch.Tensor]r9   rA   s   @r   rt   rt   n   sj    KA A
"" "" $	"
 $" $" (" " 
+" "r    rt   c                  Z   ^  \ rS rSrSrSU 4S jjr                SS jrSrU =r$ )RotatedBboxLoss   zICriterion class for computing training losses for rotated bounding boxes.c                $   > [         TU ]  U5        g)zSInitialize the RotatedBboxLoss module with regularization maximum and DFL settings.N)r   r   r[   s     r   r   RotatedBboxLoss.__init__   s    !r    c           	     .   UR                  S5      U   R                  S5      n[        X'   XG   5      n	SU	-
  U-  R                  5       U-  n
U R                  (       a  [	        U[        USSS24   5      U R                  R                  S-
  5      nU R                  X   R                  SU R                  R                  5      X   5      U-  nUR                  5       U-  nX4$ [        R                  " S5      R                  UR                  5      nX4$ )z6Compute IoU and DFL losses for rotated bounding boxes.r^   rJ   .N   r   r|   )r,   r}   r   rw   r   r   rZ   rd   rF   rG   rO   rL   r~   s                r   r2   RotatedBboxLoss.forward   s    ""2&w/99"=k*M,BC3Y&(--/2CC ==#M9]3PRQRPR7=S3TVZVcVcVkVknoVopK}}Y%7%<%<RAVAV%WYdYmnqwwH||~(99H !! ||C(++I,<,<=H!!r     r   r   r9   rA   s   @r   r   r      sc    S""" "" $	"
 $" $" (" " 
+" "r    r   c                  N   ^  \ rS rSrSrSU 4S jjr          SS jrSrU =r$ )KeypointLoss   z.Criterion class for computing keypoint losses.c                .   > [         TU ]  5         Xl        g)z7Initialize the KeypointLoss class with keypoint sigmas.N)r   r   sigmas)r   r   r   s     r   r   KeypointLoss.__init__   s    r    c                   US   US   -
  R                  S5      US   US   -
  R                  S5      -   nUR                  S   [        R                  " US:g  SS9S-   -  nUSU R                  -  R                  S5      US-   -  S-  -  nUR                  SS5      S[        R                  " U* 5      -
  U-  -  R                  5       $ )	zICalculate keypoint loss factor and Euclidean distance loss for keypoints..r      .r   r   r   dimg&.>r^   )r'   re   rF   r,   r   rd   expr+   )r   	pred_kptsgt_kptskpt_maskareadkpt_loss_factores           r   r2   KeypointLoss.forward   s     v055a8If<MPWX^P_<_;d;def;gg"..+uyyQA/NQU/UV!dkk/&&q)TD[9A=>$$R+EIIqbM0AX/MNTTVVr    r   )r   r7   r8   rq   )
r   r7   r   r7   r   r7   r   r7   r8   r7   r9   rA   s   @r   r   r      sD    8
W%W0<WHTW\hW	W Wr    r   c                  D    \ rS rSrSrS	S
S jjrSS jrSS jrSS jrSr	g)v8DetectionLoss   zJCriterion class for computing training losses for YOLOv8 object detection.c                   [        UR                  5       5      R                  nUR                  nUR                  S   n[
        R                  " SS9U l        X@l        UR                  U l	        UR                  U l
        UR                  UR                  S-  -   U l        UR                  U l        X0l        UR                  S:  U l        [        X R                  SSS9U l        [!        UR                  5      R#                  U5      U l        [&        R(                  " UR                  [&        R*                  US	9U l        g
)zVInitialize v8DetectionLoss with model parameters and task-aligned assignment settings.r^   r#   r$   r   r         ?      @topknum_classesr   beta)rM   rL   N)next
parametersrL   argsmodelnnBCEWithLogitsLossbcehypstridencrZ   nouse_dflr
   assignerrt   rO   	bbox_lossrF   aranger*   proj)r   r   tal_topkrL   hms         r   r   v8DetectionLoss.__init__   s    e&&()00JJKKO''&9hh$$$$Q&yyyy1}+wwVY`cd!!)),//7LL%++fM	r    c                   UR                   u  pEUS:X  a&  [        R                  " USUS-
  U R                  S9nU$ USS2S4   nUR	                  SS9u  pU	R                  [        R                  S9n	[        R                  " X)R                  5       US-
  U R                  S9n[        U5       H.  n
Xz:H  nUR                  5       =n(       d  M   XSS24   XjSU24'   M0     [        USSS	24   R                  U5      5      USSS	24'   U$ )
zJPreprocess targets by converting to tensor format and scaling coordinates.r   r   rL   NTreturn_countsrM   .   )re   rF   zerosrL   uniquerO   int32maxranger,   r   mul_)r   targets
batch_sizescale_tensornlneouti_countsjmatchesns                r   
preprocessv8DetectionLoss.preprocess   s    7++j!R!VDKKHC 
 1At4IAYYU[[Y1F++j**,Qt{{SC:&&%1%!(!"!5C2A2J ' &c#qs(m&8&8&FGCQqSM
r    c                   U R                   (       af  UR                  u  p4nUR                  X4SUS-  5      R                  S5      R	                  U R
                  R                  UR                  5      5      n[        X!SS9$ )zUDecode predicted object bounding box coordinates from anchor points and distribution.r      F)rz   )	r   re   rd   softmaxmatmulr   typerM   r   )r   r   rf   bacs         r   bbox_decodev8DetectionLoss.bbox_decode   se    <<ooGA!!qQQ7??BII$))..YbYhYhJijI >>r    c           
        [         R                  " SU R                  S9n[        U[        5      (       a  US   OUn[         R
                  " U Vs/ s H/  oUR                  US   R                  S   U R                  S5      PM1     snS5      R                  U R                  S-  U R                  4S5      u  pgUR                  SSS5      R                  5       nUR                  SSS5      R                  5       nUR                  nUR                  S   n	[         R                  " US   R                  SS U R                  US	9U R                   S   -  n
[#        X@R                   S
5      u  p[         R
                  " US   R                  SS5      US   R                  SS5      US   4S5      nU R%                  XU
/ SQ   S9nUR                  SS5      u  pUR'                  SSS9R)                  S5      nU R+                  X5      nU R-                  UR/                  5       R1                  5       UR/                  5       U-  R3                  UR                  5      X-  UUU5      u  nnnnn[5        UR'                  5       S5      nU R7                  UUR9                  U5      5      R'                  5       U-  US'   UR'                  5       (       a#  U R;                  UUUUU-  UUU5      u  US'   US'   US==   U R<                  R>                  -  ss'   US==   U R<                  R@                  -  ss'   US==   U R<                  RB                  -  ss'   X9-  UR/                  5       4$ s  snf )LCalculate the sum of the loss for box, cls and dfl multiplied by batch size.r   r   r   r   r^   r   r   NrK   r   	batch_idxclsbboxesr   r   r   r   r   r   r   Tr_   r|   )"rF   r   rL   
isinstancetuplecatrd   re   r   splitrZ   r   permute
contiguousrM   rG   r   r   r   r,   gt_r   r   detachr&   r   r   r   rO   r   r   boxr   dfl)r   predsbatchr1   featsxipred_distripred_scoresrM   r   imgszr   stride_tensorr   	gt_labels	gt_bboxesmask_gtr   r   r   r   r   r   s                          r   rl   v8DetectionLoss.__call__   s   {{1T[[1&ue44a%#(99`e-f`eZ\ggeAhnnQ6GRT.U`e-fhi#j#p#p\\Atww'$
  "))!Q2==?!))!Q2==?!! &&q)
U1X^^AB/5QTXT_T_`aTbb'3E;;'L$ ))U;/44R;U5\=N=NrST=UW\]eWfgijk//'E,DW/X&}}VQ7	--4-044S9 &&}B 7;mm ((*!M177	H)7
3=-!   1 1 3Q7 ((;(8(8(?@DDFIZZQ ;;==#~~-! DGT!W 	Q488<<Q488<<Q488<< $++-//o .gs   6M,)r   r   r   rL   r   r   r   r   rZ   r   r   N)
   )r   rp   r   r7   r   rp   r   r7   r8   r7   )r   r7   rf   r7   r8   r7   r   r   r  zdict[str, torch.Tensor]r8   r   )
r:   r;   r<   r=   r>   r   r   r   rl   r?   r   r    r   r   r      s    TN("?;0r    r   c                     ^  \ rS rSrSrU 4S jrSS jr\            S	S j5       r                    S
S jr	Sr
U =r$ )v8SegmentationLossi3  zFCriterion class for computing training losses for YOLOv8 segmentation.c                Z   > [         TU ]  U5        UR                  R                  U l        g)zWInitialize the v8SegmentationLoss class with model parameters and mask overlap setting.N)r   r   r   overlap_maskoverlapr   r   r   s     r   r   v8SegmentationLoss.__init__6  s!    zz..r    c                $	   [         R                  " SU R                  S9n[        U5      S:X  a  UOUS   u  pEnUR                  u  pxp[         R
                  " U Vs/ s H/  oR                  US   R                  S   U R                  S5      PM1     snS5      R                  U R                  S-  U R                  4S5      u  pUR                  SSS5      R                  5       nUR                  SSS5      R                  5       nUR                  SSS5      R                  5       nUR                  n[         R                  " US   R                  SS U R                  US	9U R                  S   -  n[!        X@R                  S
5      u  nn US   R                  SS5      n[         R
                  " UUS   R                  SS5      US   4S5      nU R#                  UX/ SQ   S9nUR                  SS5      u  nnUR%                  SSS9R'                  S5      nU R-                  UU5      nU R/                  UR1                  5       R3                  5       UR1                  5       U-  R5                  UR                  5      UU-  UUU5      u  nnnnn[7        UR%                  5       S5      nU R9                  UUR;                  U5      5      R%                  5       U-  US'   UR%                  5       (       a  U R=                  UUUUU-  UUU5      u  US'   US'   US   R;                  U R                  5      R?                  5       n[A        UR                  SS 5      X4:w  a  [B        RD                  " US   X4SS9S   nU RG                  UUUUUXeXRH                  5	      US'   O2US==   US-  R%                  5       US-  R%                  5       -   -  ss'   US==   U RJ                  RL                  -  ss'   US==   U RJ                  RL                  -  ss'   US==   U RJ                  RN                  -  ss'   US==   U RJ                  RP                  -  ss'   X7-  UR1                  5       4$ s  snf ! [(         a  n[+        S5      UeSnAff = f)zFCalculate and return the combined loss for detection and segmentation.r   r   r   r   r   r^   r   NrK   r   r   r   r   r   r   r   Tr_   r|   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=yolo11n-seg.pt data=coco8.yaml'.
Verify your dataset is a correctly formatted 'segment' dataset using 'data=coco8-seg.yaml' as an example.
See https://docs.ultralytics.com/datasets/segment/ for help.masksnearest)mode))rF   r   rL   lenre   r   rd   r   r   rZ   r   r   r   rM   rG   r   r   r   r,   r   RuntimeError	TypeErrorr   r   r   r&   r   r   r   rO   r   r*   r   r(   interpolatecalculate_segmentation_lossr  r   r   r   r   )r   r   r  r1   r  
pred_masksprotor   r   mask_hmask_wr  r  r  rM   r  r   r  r   r   r  r	  r
  r   r   r   r   r   target_gt_idxr   r  s                                  r   rl   v8SegmentationLoss.__call__;  s3   {{1T[[1,/J!O5q 5(-%
v#(99`e-f`eZ\ggeAhnnQ6GRT.U`e-fhi#j#p#p\\Atww'$
 
 "))!Q2==?!))!Q2==?''1a0;;=
!!U1X^^AB/5QTXT_T_`aTbb'3E;;'L$}	k*//A6IiiE%L,=,=b!,DeHo VXYZGoogzlH[o\G#*==#; IymmAtm488=G &&}kBBF-- ((*!M177	HM)C
?=--   1 1 3Q7 ((;(8(8(?@DDFIZZQ;;==#~~-! DGT!W 'N%%dkk288:EU[[%&6*::eDkF3C)TUVW66}i\acocoDG G	(JN+?+?+AAAGQ488<<Q488<<Q488<<Q488<< $++-//Y .g(  	_ 	s   6Q/BQ4 4
R>R

Rc                    [         R                  " SX5      n[        R                  " XPSS9n[	        Xc5      R                  SS9U-  R                  5       $ )a  
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   r   r   )rF   einsumr(   r)   r   r+   r,   )gt_maskrP   r!  xyxyr   	pred_maskr1   s          r   single_mask_loss#v8SegmentationLoss.single_mask_loss  sN    * LL<	11)PVW$%**v*6=BBDDr    c
                   UR                   u    pnSnXH/ SQ   -  n[        U5      SSS24   R                  S5      nU[        R                  " XX/UR
                  S9-  n[        [        XXvUX5      5       H  u  nnUu  nnnnnnnUR                  5       (       aq  UU   nU	(       a*  UUS-   R                  SSS5      :H  nUR                  5       nOX%R                  S5      U:H     U   nXR                  UUU   UUU   UU   5      -  nM  XS-  R                  5       US-  R                  5       -   -  nM     XR                  5       -  $ )	a  
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   .r   Nr   r   r^   )re   r   prodrF   rG   rL   	enumerateziprN   rd   r*   r+  r,   )r   r   r  r$  r   r   r!  r   r  r  r   r"  r#  r1   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  .v8SegmentationLoss.calculate_segmentation_loss  sj   D  %{{1f $13F#F  23CG<AA!D )5<<8Xafamam+nn$STY[`%hiKAx[cXIgwQX}}*95%(Q,)<)<RA)FFG%mmoG#NN2$6!$;<XFG--\)4gwy?QSZ[dSe  )Z!^,@,@,BBB! j$ kkm##r    )r  r  )r(  r7   rP   r7   r!  r7   r)  r7   r   r7   r8   r7   )r   r7   r  r7   r$  r7   r   r7   r   r7   r!  r7   r   r7   r  r7   r  boolr8   r7   )r:   r;   r<   r=   r>   r   rl   staticmethodr+  r  r?   r@   rA   s   @r   r  r  3  s    P/
Q0f EE%1E:FENZEbnE	E E0@$@$ @$ $	@$
 $@$  @$ @$ !@$ @$ @$ 
@$ @$r    r  c                  t   ^  \ rS rSrSrU 4S jrSS jr\S	S j5       r                S
S jr	Sr
U =r$ )
v8PoseLossi  zICriterion class for computing training losses for YOLOv8 pose estimation.c                  > [         TU ]  U5        UR                  S   R                  U l        [        R
                  " 5       U l        U R                  SS/:H  nU R                  S   nU(       a3  [        R                  " [        5      R                  U R                  5      O [        R                  " X0R                  S9U-  n[        US9U l        g)zQInitialize v8PoseLoss with model parameters and keypoint-specific loss functions.r^      r   r   r   r   N)r   r   r   	kpt_shaper   r   bce_poserF   
from_numpyr   rO   rL   onesr   keypoint_loss)r   r   is_posenkptr   r   s        r   r   v8PoseLoss.__init__  s    R22,,...RG+~~a @G!!),//<UZZX\epepMqtxMx)8r    c           
     	   [         R                  " SU R                  S9n[        US   [        5      (       a  UOUS   u  pE[         R
                  " U Vs/ s H/  ofR                  US   R                  S   U R                  S5      PM1     snS5      R                  U R                  S-  U R                  4S5      u  pxUR                  SSS5      R                  5       nUR                  SSS5      R                  5       nUR                  SSS5      R                  5       nUR                  n	[         R                  " US   R                  SS U R                  U	S	9U R                   S   -  n
[#        X@R                   S
5      u  pUR                  S   nUS   R                  SS5      n[         R
                  " XS   R                  SS5      US   4S5      nU R%                  XU
/ SQ   S9nUR                  SS5      u  nnUR'                  SSS9R)                  S5      nU R+                  X5      nU R-                  XR                  " US/U R.                  Q76 5      nU R1                  UR3                  5       R5                  5       UR3                  5       U-  R7                  UR                  5      X-  UUU5      u  nnnnn[9        UR'                  5       S5      nU R;                  UUR=                  U	5      5      R'                  5       U-  US'   UR'                  5       (       a  UU-  nU R?                  UUUUUUU5      u  US'   US'   US   R=                  U R                  5      RA                  5       RC                  5       nUS==   U
S   -  ss'   US==   U
S   -  ss'   U RE                  UUUXUU5      u  US'   US'   US==   U RF                  RH                  -  ss'   US==   U RF                  RJ                  -  ss'   US==   U RF                  RL                  -  ss'   US==   U RF                  RN                  -  ss'   US==   U RF                  RP                  -  ss'   X=-  UR3                  5       4$ s  snf )z;Calculate the total loss and detach it for pose estimation.r   r   r   r   r^   r   r   NrK   r   r   r   r   r   r   r   Tr_   r|   r   	keypointsr   r   ))rF   r   rL   r   listr   rd   re   r   r   rZ   r   r   r   rM   rG   r   r   r   r,   r   r   kpts_decoderD  r   r   r&   r   r   r   rO   r   r*   clonecalculate_keypoints_lossr   r   posekobjr   r   )r   r   r  r1   r  r   r  r  r  rM   r  r   r  r   r   r   r  r	  r
  r   r   r   r   r   r$  r   rM  s                              r   rl   v8PoseLoss.__call__  s   {{1T[[1$.uQx$>$>5E!H#(99`e-f`eZ\ggeAhnnQ6GRT.U`e-fhi#j#p#p\\Atww'$
 
 "))!Q2==?!))!Q2==?%%aA.99;	!!U1X^^AB/5QTXT_T_`aTbb'3E;;'L$ !&&q)
+&++B2	))Ye(9(9"a(@%/RTUV//'E,DW/X&}}VQ7	9--4-044S9 &&}B$$]NN:r4cTXTbTb4cd	BF-- ((*!M177	H)C
?=--   1 1 3Q7 ((;(8(8(?@DDFIZZQ ;;==]*M#~~[-Whjq DGT!W k*--dkk:@@BHHJIfq)fq)#<<	9]\e DGT!W 	Q488<<Q488== Q488== Q488<<Q488<< $++-//y .gs   6Q>c                    UR                  5       nUSSS24==   S-  ss'   US==   U SS2S/4   S-
  -  ss'   US==   U SS2S	/4   S-
  -  ss'   U$ )
z0Decode predicted keypoints to image coordinates..Nr   r5   r   r   r   r   r   )rP  )r   r   ys      r   rO  v8PoseLoss.kpts_decode9  sg     OO	#rr'
c
	&	]1qc6*S00		&	]1qc6*S00	r    c           
        UR                  5       n[        U5      n[        R                  " USS9S   R	                  5       n	[        R
                  " XUR                  S   UR                  S   4UR                  S9n
[        U5       H  nX4U:H     nXUSUR                  S   24'   M!     UR                  S5      R                  S5      nU
R                  SUR                  SSUR                  S   UR                  S   5      5      nUS	SS24==   UR                  SSSS5      -  ss'   SnSnUR                  5       (       a  X   n[        Xa   5      SS2SS24   R                  SSS
9nXq   nUR                  S   S:X  a  US   S:g  O[        R                   " US   S5      nU R#                  UUUU5      nUR                  S   S:X  a#  U R%                  US   UR'                  5       5      nUU4$ )a  
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:
    kpts_loss (torch.Tensor): The keypoints loss.
    kpts_obj_loss (torch.Tensor): The keypoints object loss.
Tr   r   r   r   Nr   r^   .r_   r   ).r   r   )flattenr  rF   r   r   r   re   rL   r   r}   gatherexpandrd   rN   r   r.  	full_likerH  rE  r*   )r   r  r$  rM  r   r  r   r   r   max_kptsbatched_keypointsr   keypoints_itarget_gt_idx_expandedselected_keypoints	kpts_losskpts_obj_lossgt_kptr   pred_kptr   s                        r   rQ  #v8PoseLoss.calculate_keypoints_lossB  s    < %%'	Z
 <<	>qAEEG "KK9??1#5yq7IJS\ScSc
 z"A#N3K;Fa!7;#4#4Q#7!778 #
 "/!8!8!<!F!Fr!J /55%,,RY__Q5GYZI[\

 	37#}'9'9!RA'FF#	99;;'.F]121ab59>>q$>OD 'H.4ll2.>!.Cvf~*Y_`fYgimInH**8VXtLI~~b!Q& $hv.>@P Q-''r    )rE  rH  rD  r  )r   r7   r   r7   r8   r7   )r  r7   r$  r7   rM  r7   r   r7   r  r7   r   r7   r   r7   r8   r   )r:   r;   r<   r=   r>   r   rl   r?  rO  rQ  r?   r@   rA   s   @r   rA  rA    s    S9@0D  G(G( $G(  	G(
  G( $G( $G(  G( 
+G( G(r    rA  c                  "    \ rS rSrSrSS jrSrg)v8ClassificationLossi  zACriterion class for computing training losses for classification.c                    [        U[        [        45      (       a  US   OUn[        R                  " XS   SS9nX3R                  5       4$ )zDCompute the classification loss between predictions and true labels.r   r   r+   r$   )r   rN  r   r(   rc   r   )r   r   r  r1   s       r   rl   v8ClassificationLoss.__call__  s@    &utUm<<a%uElfE[[]""r    r   Nr  )r:   r;   r<   r=   r>   rl   r?   r   r    r   rh  rh    s
    K#r    rh  c                  Z   ^  \ rS rSrSrU 4S jrSS jrS	S jr        S
S jrSr	U =r
$ )	v8OBBLossi  zdCalculates losses for object detection, classification, and box distribution in rotated YOLO models.c                   > [         TU ]  U5        [        SU R                  SSS9U l        [        U R                  5      R                  U R                  5      U l	        g)z^Initialize v8OBBLoss with model, assigner, and rotated bbox loss; model must be de-paralleled.r  r   r   r   N)
r   r   r	   r   r   r   rZ   rO   rL   r   r  s     r   r   v8OBBLoss.__init__  sG    2WZade(699$++Fr    c                    UR                   S   S:X  a#  [        R                  " USSU R                  S9nU$ USS2S4   nUR	                  SS9u  pgUR                  [        R                  S9n[        R                  " X'R                  5       SU R                  S9n[        U5       Hc  nXX:H  n	U	R                  5       =n
(       d  M   XSS24   nUS	SS
24   R                  U5        [        R                  " XSS24   U/SS9XHSU
24'   Me     U$ )z7Preprocess targets for oriented bounding box detection.r      r   NTr   r   r   .r   r   r^   r   )re   rF   r   rL   r   rO   r   r   r   r,   r   r   )r   r   r   r   r   r   r   r   r   r   r   r   s               r   r   v8OBBLoss.preprocess  s   ==q ++j!Qt{{CC 
 1At4IAYYU[[Y1F++j**,$++NC:&&%1%$ab[1F37O((6!&GQqSL,A6+JPR!SC2A2J ' 
r    c           
        [         R                  " SU R                  S9n[        US   [        5      (       a  UOUS   u  pEUR
                  S   n[         R                  " U Vs/ s H/  owR                  US   R
                  S   U R                  S5      PM1     snS5      R                  U R                  S-  U R                  4S5      u  pU	R                  SSS5      R                  5       n	UR                  SSS5      R                  5       nUR                  SSS5      R                  5       nU	R                  n
[         R                  " US   R
                  SS U R                  U
S	9U R                   S   -  n[#        X@R                   S
5      u  p US   R                  SS5      n[         R                  " XS   R                  SS5      US   R                  SS5      4S5      nUSS2S4   US   R%                  5       -  USS2S4   US   R%                  5       -  nnUUS:  US:  -     nU R'                  XU/ SQ   S9nUR                  SS5      u  nnUR)                  SSS9R+                  S5      nU R1                  XU5      nUR3                  5       R5                  5       nUSSS24==   U-  ss'   U R7                  U	R5                  5       R9                  5       UR;                  UR                  5      X-  UUU5      u  nnnnn[=        UR)                  5       S5      nU R?                  U	URA                  U
5      5      R)                  5       U-  US'   UR)                  5       (       a2  USSS24==   U-  ss'   U RC                  UUUUUUU5      u  US'   US'   OUS==   US-  R)                  5       -  ss'   US==   U RD                  RF                  -  ss'   US==   U RD                  RH                  -  ss'   US==   U RD                  RJ                  -  ss'   X6-  UR5                  5       4$ s  snf ! [,         a  n[/        S5      UeSnAff = f)zBCalculate and return the loss for oriented bounding box detection.r   r   r   r   r^   r   r   NrK   r   r   r   r   r   r   r   )r   r   Tr_   r|   uh  ERROR ❌ OBB dataset incorrectly formatted or not a OBB dataset.
This error can occur when incorrectly training a 'OBB' model on a 'detect' dataset, i.e. 'yolo train model=yolo11n-obb.pt data=coco8.yaml'.
Verify your dataset is a correctly formatted 'OBB' dataset using 'data=dota8.yaml' as an example.
See https://docs.ultralytics.com/datasets/obb/ for help..)&rF   r   rL   r   rN  re   r   rd   r   r   rZ   r   r   r   rM   rG   r   r   itemr   r,   r   r  r  r   rP  r   r   r&   r   r   r   rO   r   r   r   r   r   )r   r   r  r1   r  
pred_angler   r  r  r  rM   r  r   r  r   r   rwrhr  r	  r
  r   r   bboxes_for_assignerr   r   r   r   r   s                                r   rl   v8OBBLoss.__call__  s   {{1T[[1%/a$%?%?EU1X%%a(
#(99`e-f`eZ\ggeAhnnQ6GRT.U`e-fhi#j#p#p\\Atww'$
 
 "))!Q2==?!))!Q2==?''1a0;;=
!!U1X^^AB/5QTXT_T_`aTbb'3E;;'L$	k*//A6Iii%L,=,=b!,DeHoFZFZ[]_`Fa bdefGQT]U1X]]_4gadmeAhmmo6UBrQw2734GooglH[o\G#*==#; IymmAtm488=G &&}:N)//188:C!G$5$6:mm ((*$$Y__5)7
3=-!   1 1 3Q7 ((;(8(8(?@DDFIZZQ ;;==#rr'"m3"#~~[-Whjq DGT!W G
Q++--GQ488<<Q488<<Q488<< $++-//C .g,  	[ 	s   $6P9C%P> >
QQQc                2   U R                   (       af  UR                  u  pEnUR                  XESUS-  5      R                  S5      R	                  U R
                  R                  UR                  5      5      n[        R                  " [        X#U5      U4SS9$ )ay  
Decode predicted object bounding box coordinates from anchor points and distribution.

Args:
    anchor_points (torch.Tensor): Anchor points, (h*w, 2).
    pred_dist (torch.Tensor): Predicted rotated distance, (bs, h*w, 4).
    pred_angle (torch.Tensor): Predicted angle, (bs, h*w, 1).

Returns:
    (torch.Tensor): Predicted rotated bounding boxes with angles, (bs, h*w, 5).
r   r   r^   r   )r   re   rd   r   r   r   r   rM   rF   r   r   )r   r   rf   rt  r   r   r   s          r   r   v8OBBLoss.bbox_decode  sv     <<ooGA!!qQQ7??BII$))..YbYhYhJijIyy)I=I:V\^__r    )r   r   r  r  )r   r7   rf   r7   rt  r7   r8   r7   )r:   r;   r<   r=   r>   r   r   rl   r   r?   r@   rA   s   @r   rl  rl    sH    nG"F0P`)`6B`P\`	` `r    rl  c                  (    \ rS rSrSrS rSS jrSrg)E2EDetectLossi  zGCriterion class for computing training losses for end-to-end detection.c                @    [        USS9U l        [        USS9U l        g)zcInitialize E2EDetectLoss with one-to-many and one-to-one detection losses using the provided model.r  )r   r   N)r   one2manyone2oner   r   s     r   r   E2EDetectLoss.__init__  s    ';&uq9r    c                    [        U[        5      (       a  US   OUnUS   nU R                  X25      nUS   nU R                  XR5      nUS   US   -   US   US   -   4$ )r   r   r~  r  r   )r   r   r~  r  )r   r   r  r~  loss_one2manyr  loss_one2ones          r   rl   E2EDetectLoss.__call__  sq    &ue44a%$h6	"||G3Q,q/1=3ClSTo3UUUr    )r~  r  Nr  )r:   r;   r<   r=   r>   r   rl   r?   r   r    r   r|  r|    s    Q:
Vr    r|  c                  2    \ rS rSrSrS rSS jrS	S jrSrg)
TVPDetectLossi  zOCriterion class for computing training losses for text-visual prompt detection.c                    [        U5      U l        U R                  R                  U l        U R                  R                  U l        U R                  R                  U l        g)z^Initialize TVPDetectLoss with task-prompt and visual-prompt criteria using the provided model.N)r   vp_criterionr   ori_ncr   ori_norZ   ori_reg_maxr  s     r   r   TVPDetectLoss.__init__!  sI    +E2''**''**,,44r    c                   [        U[        5      (       a  US   OUnU R                  U R                  R                  :X  d   eU R                  S-  U R
                  -   US   R                  S   :X  a;  [        R                  " SU R                  R                  SS9nXDR                  5       4$ U R                  U5      nU R                  XR5      nUS   S   nXvS   4$ )z4Calculate the loss for text-visual prompt detection.r   r   r   r   TrL   requires_grad)r   r   r  r  rZ   r  re   rF   r   rL   r   _get_vp_features)r   r   r  r  r1   vp_featsvp_lossbox_losss           r   rl   TVPDetectLoss.__call__)  s    &ue44a%4#4#4#<#<<<<a$++-q1BB;;q):):)A)AQUVD&&((/##H41:a=##r    c           
        US   R                   S   U R                  S-  -
  U R                  -
  nX R                  l        X R                  R
                  S-  -   U R                  l        X R                  R                  l        U Vs/ s H,  o3R                  U R                  S-  U R                  U4SS9PM.     sn VVVs/ s H  u  pEn[        R                  " XF4SS9PM     snnn$ s  snf s  snnnf )z5Extract visual-prompt features from the model output.r   r   r   r   )re   r  r  r  r   rZ   r   r   r   r   rF   r   )r   r  vncr  r   r   cls_vps          r   r  TVPDetectLoss._get_vp_features7  s    AhnnQ$"2"2Q"66D""%6%6%>%>%BB14"". hm"mglac88T-=-=-A4;;PS,TZ[8#\gl"m
"m IIsm+"m
 	
"m
s   3C*#C/)r  r  r  r  Nr  )r  list[torch.Tensor]r8   r  )	r:   r;   r<   r=   r>   r   rl   r  r?   r   r    r   r  r    s    Y5$
r    r  c                  6   ^  \ rS rSrSrU 4S jrSS jrSrU =r$ )TVPSegmentLossiE  zRCriterion class for computing training losses for text-visual prompt segmentation.c                D   > [         TU ]  U5        [        U5      U l        g)z_Initialize TVPSegmentLoss with task-prompt and visual-prompt criteria using the provided model.N)r   r   r  r  r  s     r   r   TVPSegmentLoss.__init__H  s    .u5r    c                   [        U5      S:X  a  UOUS   u  p4nU R                  U R                  R                  :X  d   eU R                  S-  U R                  -   US   R
                  S   :X  a;  [        R                  " SU R                  R                  SS9nXfR                  5       4$ U R                  U5      nU R                  XtU4U5      nUS   S   n	XS   4$ )z7Calculate the loss for text-visual prompt segmentation.r   r   r   r   Tr  r   )r  r  r  rZ   r  re   rF   r   rL   r   r  )
r   r   r  r  r   r!  r1   r  r  cls_losss
             r   rl   TVPSegmentLoss.__call__M  s    ,/J!O5q 54#4#4#<#<<<<a$++-q1BB;;q):):)A)AQUVD&&((/##X5$A5I1:a=##r    )r  r  rr   rA   s   @r   r  r  E  s    \6
$ $r    r  ),
__future__r   typingr   rF   torch.nnr   torch.nn.functional
functionalr(   ultralytics.utils.metricsr   ultralytics.utils.opsr   r   r   ultralytics.utils.talr	   r
   r   r   r   ultralytics.utils.torch_utilsr   metricsr   r   talr   Moduler   rC   rW   rt   r   r   r   r  rA  rh  rl  r|  r  r  r   r    r   <module>r     s    #      / A A u u 2 & BII B!"		 !"H!RYY !*"ryy "D"h "BW299 W&l0 l0^t$ t$n_( _(D# #s` s`lV V$$
 $
N$] $r    