
    .h                    6   d dl mZ d dlmZ 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mZmZ d dlmZ dd	lmZ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e!      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' G d d e$      Z( G d! d"      Z) G d# d$      Z* G d% d&e*      Z+y)'    )annotations)AnyN)	OKS_SIGMA)	crop_mask	xywh2xyxy	xyxy2xywh)RotatedTaskAlignedAssignerTaskAlignedAssigner	dist2bbox	dist2rboxmake_anchors)autocast   )bbox_iouprobiou)	bbox2distc                  .     e Zd ZdZdd fdZddZ xZS )VarifocalLossa  
    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         |           || _        || _        y)zJInitialize the VarifocalLoss class with focusing and balancing parameters.N)super__init__gammaalphaselfr   r   	__class__s      T/var/www/html/ai-service/venv/lib/python3.12/site-packages/ultralytics/utils/loss.pyr   zVarifocalLoss.__init__#   s    

    c                v   | j                   |j                         j                  | j                        z  d|z
  z  ||z  z   }t	        d      5  t        j                  |j                         |j                         d      |z  j                  d      j                         }ddd       |S # 1 sw Y   S xY w)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   forwardzVarifocalLoss.forward)   s    j00266tzzBBa%iPS[^cScce$ 	33J4D4D4FHXdjkntta 	 	 s   AB..B8)       @g      ?r   r(   r   r(   )r+   torch.Tensorr,   r3   r-   r3   returnr3   __name__
__module____qualname____doc__r   r0   __classcell__r   s   @r   r   r      s    	r   r   c                  .     e Zd ZdZdd fdZddZ xZS )	FocalLossa  
    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         |           || _        t        j                  |      | _        y)zBInitialize FocalLoss class with focusing and balancing parameters.N)r   r   r   torchtensorr   r   s      r   r   zFocalLoss.__init__A   s%    
\\%(
r   c                   t        j                  ||d      }|j                         }||z  d|z
  d|z
  z  z   }d|z
  | j                  z  }||z  }| j                  dkD  j                         r`| j                  j                  |j                  |j                        | _        || j                  z  d|z
  d| j                  z
  z  z   }||z  }|j                  d      j                         S )zACalculate focal loss with modulating factors for class imbalance.r!   r"   r         ?r   devicedtype)r&   r'   r$   r   r   anytorD   rE   r)   r*   )r   predr-   r/   	pred_probp_tmodulating_factoralpha_factors           r   r0   zFocalLoss.forwardG   s    11$P
 LLN	i1u9Y"?? 3Y4::5!!JJN!dkkLDJ 4::-Uq4::~0NNLL Dyy|!!r   )g      ?g      ?r2   )rH   r3   r-   r3   r4   r3   r5   r;   s   @r   r=   r=   5   s    	)"r   r=   c                  .     e Zd ZdZdd fdZddZ xZS )DFLossz<Criterion class for computing Distribution Focal Loss (DFL).c                0    t         |           || _        y)z6Initialize the DFL module with regularization maximum.N)r   r   reg_maxr   rP   r   s     r   r   zDFLoss.__init__\   s    r   c                   |j                  d| j                  dz
  dz
        }|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 )	zZReturn sum of left and right DFL losses from https://ieeexplore.ieee.org/document/9792391.r   r   g{Gz?r!   r"   Tkeepdim)clamp_rP   longr&   cross_entropyviewshaper)   )r   	pred_disttargettltrwlwrs          r   __call__zDFLoss.__call__a   s    q$,,"2T"9:[[]!V&[VOOIrwwr{fEJJ288TWYYooiGLLRXXVY[[\
$r4$
 	!r      )rP   intr4   None)r[   r3   r\   r3   r4   r3   r6   r7   r8   r9   r   ra   r:   r;   s   @r   rN   rN   Y   s    F

!r   rN   c                  N     e Zd ZdZdd fdZ	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddZ xZS )BboxLosszACriterion class for computing training losses for bounding boxes.c                \    t         |           |dkD  rt        |      | _        yd| _        y)zLInitialize the BboxLoss module with regularization maximum and DFL settings.r   N)r   r   rN   dfl_lossrQ   s     r   r   zBboxLoss.__init__q   s%    +2Q;wDr   c                   |j                  d      |   j                  d      }t        ||   ||   dd      }	d|	z
  |z  j                         |z  }
| j                  rzt	        ||| j                  j
                  dz
        }| j                  ||   j                  d| j                  j
                        ||         |z  }|j                         |z  }|
|fS t        j                  d      j                  |j                        }|
|fS )z.Compute IoU and DFL losses for bounding boxes.rS   FT)xywhCIoUrB   r           )r*   	unsqueezer   rj   r   rP   rY   r?   r@   rG   rD   r   r[   pred_bboxesanchor_pointstarget_bboxestarget_scorestarget_scores_sumfg_maskr.   iouloss_ioutarget_ltrbloss_dfls                r   r0   zBboxLoss.forwardv   s    ""2&w/99"={7+]7-C%VZ[3Y&(--/2CC ==#M=$--BWBWZ[B[\K}}Yw%7%<%<RAVAV%WYdelYmnqwwH||~(99H !! ||C(++I,<,<=H!!r   rb   rP   rd   r[   r3   rq   r3   rr   r3   rs   r3   rt   r3   ru   r3   rv   r3   r4   !tuple[torch.Tensor, torch.Tensor]r5   r;   s   @r   rh   rh   n   s_    KA
"" "" $	"
 $" $" (" " 
+"r   rh   c                  L     e Zd ZdZd fdZ	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddZ xZS )RotatedBboxLosszICriterion class for computing training losses for rotated bounding boxes.c                $    t         |   |       y)zSInitialize the RotatedBboxLoss module with regularization maximum and DFL settings.N)r   r   rQ   s     r   r   zRotatedBboxLoss.__init__   s    !r   c           	     .   |j                  d      |   j                  d      }t        ||   ||         }	d|	z
  |z  j                         |z  }
| j                  rt	        |t        |dddf         | j                  j                  dz
        }| j                  ||   j                  d| j                  j                        ||         |z  }|j                         |z  }|
|fS t        j                  d      j                  |j                        }|
|fS )z6Compute IoU and DFL losses for rotated bounding boxes.rS   rB   .N   r   rn   )r*   ro   r   rj   r   r   rP   rY   r?   r@   rG   rD   rp   s                r   r0   zRotatedBboxLoss.forward   s    ""2&w/99"=k'*M',BC3Y&(--/2CC ==#M9]3PRQRPR7=S3TVZVcVcVkVknoVopK}}Yw%7%<%<RAVAV%WYdelYmnqwwH||~(99H !! ||C(++I,<,<=H!!r   r{   r|   r5   r;   s   @r   r   r      s^    S""" "" $	"
 $" $" (" " 
+"r   r   c                  @     e Zd ZdZd fdZ	 	 	 	 	 	 	 	 	 	 ddZ xZS )KeypointLossz.Criterion class for computing keypoint losses.c                0    t         |           || _        y)z7Initialize the KeypointLoss class with keypoint sigmas.N)r   r   sigmas)r   r   r   s     r   r   zKeypointLoss.__init__   s    r   c                   |d   |d   z
  j                  d      |d   |d   z
  j                  d      z   }|j                  d   t        j                  |dk7  d      dz   z  }|d| j                  z  j                  d      |dz   z  dz  z  }|j                  dd      dt        j                  |       z
  |z  z  j                         S )	zICalculate keypoint loss factor and Euclidean distance loss for keypoints..r      .r   r   r   dimg&.>rS   )r%   rZ   r?   r*   r   rY   expr)   )r   	pred_kptsgt_kptskpt_maskareadkpt_loss_factores           r   r0   z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   r3   r4   re   )
r   r3   r   r3   r   r3   r   r3   r4   r3   r5   r;   s   @r   r   r      s>    8
W%W0<WHTW\hW	Wr   r   c                  2    e Zd ZdZdddZd	dZd
dZddZy)v8DetectionLosszJCriterion class for computing training losses for YOLOv8 object detection.c                   t        |j                               j                  }|j                  }|j                  d   }t        j                  d      | _        || _        |j                  | _	        |j                  | _
        |j                  |j                  dz  z   | _        |j                  | _        || _        |j                  dkD  | _        t        || j                  dd      | _        t!        |j                        j#                  |      | _        t'        j(                  |j                  t&        j*                  |	      | _        y
)zVInitialize v8DetectionLoss with model parameters and task-aligned assignment settings.rS   r!   r"   r   r         ?      @topknum_classesr   beta)rE   rD   N)next
parametersrD   argsmodelnnBCEWithLogitsLossbcehypstridencrP   nouse_dflr
   assignerrh   rG   	bbox_lossr?   aranger(   proj)r   r   tal_topkrD   hms         r   r   zv8DetectionLoss.__init__   s    e&&()00JJKKO''&9hh$$$$Q&yyyy1}+twwVY`cd!!)),//7LL%++fM	r   c                "   |j                   \  }}|dk(  r(t        j                  |d|dz
  | j                        }|S |dddf   }|j	                  d      \  }}	|	j                  t        j                        }	t        j                  ||	j                         |dz
  | j                        }t        |      D ]*  }
||
k(  }|j                         x}s||ddf   ||
d|f<   , t        |ddd	f   j                  |            |ddd	f<   |S )
zJPreprocess targets by converting to tensor format and scaling coordinates.r   r   rD   NTreturn_countsrE   .   )rZ   r?   zerosrD   uniquerG   int32maxranger*   r   mul_)r   targets
batch_sizescale_tensornlneouti_countsjmatchesns                r   
preprocesszv8DetectionLoss.preprocess   s   B7++j!R!VDKKHC 
 1At4IAvYYU[[Y1F++j&**,Qt{{SC:& 6q&%1%!(!"!5C2A2J6 &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.r      F)rl   )	r   rZ   rY   softmaxmatmulr   typerE   r   )r   rr   r[   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%                  ||	|
g d         }|j                  dd      \  }}|j'                  dd      j)                  d      }| j+                  ||      }| j-                  |j/                         j1                         |j/                         |z  j3                  |j                        ||z  |||      \  }}}}}t5        |j'                         d      }| j7                  ||j9                  |            j'                         |z  |d<   |j'                         r#| j;                  |||||z  |||      \  |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<   ||	z  |j/                         fS c c}w )LCalculate the sum of the loss for box, cls and dfl multiplied by batch size.r   r   r   r   rS   r   r   NrC   r   	batch_idxclsbboxesr   r   r   r   r   r   r   TrT   rn   )"r?   r   rD   
isinstancetuplecatrY   rZ   r   splitrP   r   permute
contiguousrE   r@   r   r   r   r*   gt_r   r   detachr$   r   r   r   rG   r   r   boxr   dfl)r   predsbatchr/   featsxipred_distripred_scoresrE   r   imgszrr   stride_tensorr   	gt_labels	gt_bboxesmask_gtrq   r   rs   rt   rv   ru   s                          r   ra   zv8DetectionLoss.__call__   s!   {{1T[[1&ue4a%#(99`e-fZ\bggeAhnnQ6GRT.U-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//':E,DW/X&}}VQ7	9--4-044S9 &&}kB 7;mm ((*!M177	HM)7
3=-!   1 1 3Q7 ((;(8(8(?@DDFIZZQ ;;=#~~-! DGT!W 	Q488<<Q488<<Q488<<j $++-//o .gs   4M0N)
   )r   rd   r   r3   r   rd   r   r3   r4   r3   )rr   r3   r[   r3   r4   r3   r   r   r   zdict[str, torch.Tensor]r4   r}   )r6   r7   r8   r9   r   r   r   ra    r   r   r   r      s    TN("?;0r   r   c                       e Zd ZdZ fdZddZe	 	 	 	 	 	 	 	 	 	 	 	 dd       Z	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddZ xZ	S )	v8SegmentationLosszFCriterion class for computing training losses for YOLOv8 segmentation.c                Z    t         |   |       |j                  j                  | _        y)zWInitialize the v8SegmentationLoss class with model parameters and mask overlap setting.N)r   r   r   overlap_maskoverlapr   r   r   s     r   r   zv8SegmentationLoss.__init__6  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#                  |||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| 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<   ||z  |j1                         fS c c}w # t(        $ r}t+        d      |d}~ww xY w)zFCalculate and return the combined loss for detection and segmentation.r   r   r   r   r   rS   r   NrC   r   r   r   r   r   r   r   TrT   rn   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))r?   r   rD   lenrZ   r   rY   r   r   rP   r   r   r   rE   r@   r   r   r   r*   r   RuntimeError	TypeErrorr   r   r   r$   r   r   r   rG   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   rE   r   rr   r   r   r   r   r   r   r   rq   rs   rt   rv   target_gt_idxru   r   s                                  r   ra   zv8SegmentationLoss.__call__;  sE   {{1T[[1,/J!O5q z5(-%
Avv#(99`e-fZ\bggeAhnnQ6GRT.U-fhi#j#p#p\\Atww'$
 [
 "))!Q2==?!))!Q2==?''1a0;;=
!!U1X^^AB/5QTXT_T_`aTbb'3E4;;'L$}	k*//A6IiiE%L,=,=b!,DeHo VXYZGoogzlH[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[[%&66*::eDkFF3C)TUVW66}iPZ\acgcocoDG G	(JN+?+?+AAAGQ488<<Q488<<Q488<<Q488<<j $++-//Y .g(  	_ 	s   4Q;BR   	R	R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   r   r   )r?   einsumr&   r'   r   r)   r*   )gt_maskrH   r  xyxyr   	pred_maskr/   s          r   single_mask_lossz#v8SegmentationLoss.single_mask_loss  sT    * LLe<	11)WPVW$%**v*6=BBDDr   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   .r   Nr   r   rS   )rZ   r   prodr?   r@   rD   	enumerateziprF   rY   r(   r  r*   )r   rv   r   r  rs   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_loss  s   D  %{{1ff $153F#F  23CG<AA!D )5<<QW8Xafamam+nn$S-UTY[`bg%hi 	CKAx[cXIgwQX}}*95%(Q,)<)<RA)FFG%mmoG#INN2$6!$;<XFG--\)4gwy?QSZ[dSe  )Z!^,@,@,BBB!	C$ gkkm##r   r   )r  r3   rH   r3   r  r3   r  r3   r   r3   r4   r3   )rv   r3   r   r3   r  r3   rs   r3   r   r3   r  r3   r  r3   r   r3   r   boolr4   r3   )
r6   r7   r8   r9   r   ra   staticmethodr  r  r:   r;   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                  d     e Zd ZdZ fdZddZedd       Z	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddZ xZ	S )	
v8PoseLosszICriterion class for computing training losses for YOLOv8 pose estimation.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)zQInitialize v8PoseLoss with model parameters and keypoint-specific loss functions.rS      r   r   r   )r   N)r   r   r   	kpt_shaper   r   bce_poser?   
from_numpyr   rG   rD   onesr   keypoint_loss)r   r   is_posenkptr   r   s        r   r   zv8PoseLoss.__init__  s    R22,,...RG+~~a @G!!),//<UZZX\eiepepMqtxMx)8r   c           
     	   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%                  |||
g d         }|j                  dd      \  }}|j'                  dd      j)                  d      }| j+                  ||      }| j-                  | |j                  |dg| j.                         }| j1                  |j3                         j5                         |j3                         |z  j7                  |j                        ||z  |||      \  }}}}}t9        |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<   ||z  |j3                         fS c c}w )z;Calculate the total loss and detach it for pose estimation.r   r   r   r   rS   r   r   NrC   r   r   r   r   r   r   r   TrT   rn   r   	keypointsr   r   ))r?   r   rD   r   listr   rY   rZ   r   r   rP   r   r   r   rE   r@   r   r   r   r*   r   r   kpts_decoder%  r   r   r$   r   r   r   rG   r   r(   clonecalculate_keypoints_lossr   r   posekobjr   r   )r   r   r   r/   r   r   r   r   r   rE   r   rr   r   r   r   r   r   r   r   rq   r   rs   rt   rv   r  ru   r-  s                              r   ra   zv8PoseLoss.__call__  s!   {{1T[[1$.uQx$>5E!Hy#(99`e-fZ\bggeAhnnQ6GRT.U-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//':E,DW/X&}}VQ7	9--4-044S9 &&}kB$$]NINN:r4cTXTbTb4cd	BF-- ((*!M177	HM)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)#<<	9m]\e DGT!W 	Q488<<Q488== Q488== Q488<<Q488<<j $++-//y .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 )
z0Decode predicted keypoints to image coordinates..Nr   r1   r   r   r   r   r   )r0  )rr   r   ys      r   r/  zv8PoseLoss.kpts_decode9  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               }|d	ddfxx   |j                  dddd      z  cc<   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 )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   rS   .rT   r   ).r   r   )flattenr   r?   r   r   r   rZ   rD   r   ro   gatherexpandrY   rF   r   r  	full_liker)  r&  r(   )r   r   r  r-  r   r   rs   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   r1  z#v8PoseLoss.calculate_keypoints_lossB  s   < %%'	Z
 <<	>qAEEG "KK9??1#5yq7IJS\ScSc
 z" 	GA#IN3K;Fa!7;#4#4Q#7!778	G
 "/!8!8!<!F!Fr!J /55%,,RY__Q5GYZI[\

 	37#}'9'9!RA'FF#	99;'.F]5121ab59>>q$>OD 'H.4ll2.>!.Cvf~*Y_`fYgimInH**8VXtLI~~b!Q& $hv.>@P Q-''r   r   )rr   r3   r   r3   r4   r3   )r   r3   r  r3   r-  r3   r   r3   r   r3   rs   r3   r   r3   r4   r}   )
r6   r7   r8   r9   r   ra   r   r/  r1  r:   r;   s   @r   r"  r"    s    S9@0D  G(G( $G(  	G(
  G( $G( $G(  G( 
+G(r   r"  c                      e Zd ZdZddZy)v8ClassificationLosszACriterion class for computing training losses for classification.c                    t        |t        t        f      r|d   n|}t        j                  ||d   d      }||j                         fS )zDCompute the classification loss between predictions and true labels.r   r   r)   r"   )r   r.  r   r&   rX   r   )r   r   r   r/   s       r   ra   zv8ClassificationLoss.__call__  sA    &utUm<a%ueElfET[[]""r   Nr   )r6   r7   r8   r9   ra   r   r   r   rE  rE    s
    K#r   rE  c                  J     e Zd ZdZ fdZddZddZ	 	 	 	 	 	 	 	 ddZ xZS )		v8OBBLosszdCalculates losses for object detection, classification, and box distribution in rotated YOLO models.c                    t         |   |       t        d| j                  dd      | _        t        | j                        j                  | j                        | _	        y)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   rP   rG   rD   r   r   s     r   r   zv8OBBLoss.__init__  sG    2WZade(699$++Fr   c                2   |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 ]b  }||k(  }	|	j                         x}
s||	ddf   }|d	dd
f   j                  |       t        j                  ||	ddf   |gd      ||d|
f<   d |S )z7Preprocess targets for oriented bounding box detection.r      r   NTr   r   r   .r   r   rS   r   )rZ   r?   r   rD   r   rG   r   r   r   r*   r   r   )r   r   r   r   r   r   r   r   r   r   r   r   s               r   r   zv8OBBLoss.preprocess  s   ==q ++j!Qt{{CC 
 1At4IAvYYU[[Y1F++j&**,$++NC:& Tq&%1%$Wab[1F37O((6!&GGQqSL,A6+JPR!SC2A2JT 
r   c           
        t        j                  d| j                        }t        |d   t              r|n|d   \  }}|j
                  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
      \  }}	 |d   j                  dd      }t        j                  ||d   j                  dd      |d   j                  dd      fd      }|dddf   |d   j%                         z  |dddf   |d   j%                         z  }}||dk\  |dk\  z     }| j'                  |||g d         }|j                  dd      \  }}|j)                  dd      j+                  d      }| j1                  |||      }|j3                         j5                         }|dddfxx   |z  cc<   | j7                  |	j5                         j9                         |j;                  |j                        ||z  |||      \  }}}}}t=        |j)                         d      }| j?                  |	|jA                  |
            j)                         |z  |d<   |j)                         r2|dddfxx   |z  cc<   | jC                  |||||||      \  |d<   |d<   n|dxx   |dz  j)                         z  cc<   |dxx   | jD                  jF                  z  cc<   |dxx   | jD                  jH                  z  cc<   |dxx   | jD                  jJ                  z  cc<   ||z  |j5                         fS c c}w # t,        $ r}t/        d      |d}~ww xY w)zBCalculate and return the loss for oriented bounding box detection.r   r   r   r   rS   r   r   NrC   r   r   r   r   r   r   r   )r   r   TrT   rn   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..)&r?   r   rD   r   r.  rZ   r   rY   r   r   rP   r   r   r   rE   r@   r   r   itemr   r*   r   r   r  r   r0  r   r   r$   r   r   r   rG   r   r   r   r   r   )r   r   r   r/   r   
pred_angler   r   r   r   rE   r   rr   r   r   r   rwrhr   r   r   r   rq   bboxes_for_assignerr   rs   rt   rv   ru   s                                r   ra   zv8OBBLoss.__call__  s   {{1T[[1%/a$%?EU1Xz%%a(
#(99`e-fZ\bggeAhnnQ6GRT.U-fhi#j#p#p\\Atww'$
 [
 "))!Q2==?!))!Q2==?''1a0;;=
!!U1X^^AB/5QTXT_T_`aTbb'3E4;;'L$}	k*//A6IiiE%L,=,=b!,DeHoFZFZ[]_`Fa bdefGQT]U1X]]_4gadmeAhmmo6UBrQw2734GoogzlH[o\G#*==#; IymmAtm488=G &&}k:N)//188:C!G$5$6:mm ((*$$Y__5M)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<<j $++-//C .g,  	[ 	s   !4P>C,Q 	QQQc                2   | j                   rh|j                  \  }}}|j                  ||d|dz        j                  d      j	                  | j
                  j                  |j                              }t        j                  t        |||      |fd      S )a  
        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   rS   r   )r   rZ   rY   r   r   r   r   rE   r?   r   r   )r   rr   r[   rN  r   r   r   s          r   r   zv8OBBLoss.bbox_decode  s|     <<ooGAq!!q!QQ7??BII$))..YbYhYhJijIyy)Iz=I:V\^__r   r   r   )rr   r3   r[   r3   rN  r3   r4   r3   )	r6   r7   r8   r9   r   r   ra   r   r:   r;   s   @r   rH  rH    sB    nG"F0P`)`6B`P\`	`r   rH  c                      e Zd ZdZd ZddZy)E2EDetectLosszGCriterion class for computing training losses for end-to-end detection.c                L    t        |d      | _        t        |d      | _        y)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   zE2EDetectLoss.__init__  s    ';&uq9r   c                    t        |t              r|d   n|}|d   }| j                  ||      }|d   }| j                  ||      }|d   |d   z   |d   |d   z   fS )r   r   rV  rW  r   )r   r   rV  rW  )r   r   r   rV  loss_one2manyrW  loss_one2ones          r   ra   zE2EDetectLoss.__call__  sr    &ue4a%$h6	"||GU3Q,q/1=3ClSTo3UUUr   Nr   )r6   r7   r8   r9   r   ra   r   r   r   rT  rT    s    Q:
Vr   rT  c                  &    e Zd ZdZd ZddZddZy)TVPDetectLosszOCriterion class for computing training losses for text-visual prompt detection.c                    t        |      | _        | j                  j                  | _        | j                  j                  | _        | j                  j                  | _        y)z^Initialize TVPDetectLoss with task-prompt and visual-prompt criteria using the provided model.N)r   vp_criterionr   ori_ncr   ori_norP   ori_reg_maxrX  s     r   r   zTVPDetectLoss.__init__!  sI    +E2''**''**,,44r   c                   t        |t              r|d   n|}| j                  | j                  j                  k(  sJ | j                  dz  | j
                  z   |d   j                  d   k(  r>t        j                  d| j                  j                  d      }||j                         fS | j                  |      }| j                  ||      }|d   d   }||d   fS )z4Calculate the loss for text-visual prompt detection.r   r   r   r   TrD   requires_grad)r   r   rb  r_  rP   r`  rZ   r?   r   rD   r   _get_vp_features)r   r   r   r   r/   vp_featsvp_lossbox_losss           r   ra   zTVPDetectLoss.__call__)  s    &ue4a%4#4#4#<#<<<<a$++-q1BB;;q):):)A)AQUVD&&((/##He41:a=##r   c           	        |d   j                   d   | j                  dz  z
  | j                  z
  }|| j                  _        || j                  j
                  dz  z   | j                  _        || j                  j                  _        |D cg c]/  }|j                  | j                  dz  | j                  |fd      1 c}D cg c]  \  }}}t        j                  ||fd      ! c}}}S c c}w c c}}}w )z5Extract visual-prompt features from the model output.r   r   r   r   )rZ   rb  r`  r_  r   rP   r   r   r   r   r?   r   )r   r   vncr   r   r   cls_vps          r   rf  zTVPDetectLoss._get_vp_features7  s    AhnnQ$"2"2Q"66D""T%6%6%>%>%BB14"". hm"mac288T-=-=-A4;;PS,TZ[8#\"m
 
Q IIsFm+
 	
"m
s   4C/$C4Nr   )r   list[torch.Tensor]r4   rm  )r6   r7   r8   r9   r   ra   rf  r   r   r   r]  r]    s    Y5$
r   r]  c                  *     e Zd ZdZ fdZddZ xZS )TVPSegmentLosszRCriterion class for computing training losses for text-visual prompt segmentation.c                D    t         |   |       t        |      | _        y)z_Initialize TVPSegmentLoss with task-prompt and visual-prompt criteria using the provided model.N)r   r   r   r_  r   s     r   r   zTVPSegmentLoss.__init__H  s    .u5r   c                   t        |      dk(  r|n|d   \  }}}| j                  | j                  j                  k(  sJ | j                  dz  | j                  z   |d   j
                  d   k(  r>t        j                  d| j                  j                  d      }||j                         fS | j                  |      }| j                  |||f|      }|d   d   }	|	|d   fS )z7Calculate the loss for text-visual prompt segmentation.r   r   r   r   Trd  r   )r   rb  r_  rP   r`  rZ   r?   r   rD   r   rf  )
r   r   r   r   r  r  r/   rg  rh  cls_losss
             r   ra   zTVPSegmentLoss.__call__M  s    ,/J!O5q z54#4#4#<#<<<<a$++-q1BB;;q):):)A)AQUVD&&((/##Xz5$A5I1:a=##r   r   rf   r;   s   @r   ro  ro  E  s    \6
$r   ro  ),
__future__r   typingr   r?   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   r=   rN   rh   r   r   r   r   r"  rE  rH  rT  r]  ro  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   