Ë
    ëÓ^j˜v  ã                  ój  — d Z ddlmZ ddlmZ ddlZddlmc mZ	 ddlmZ ddl
mZ ddlmZmZmZ ddlmZ dd	lmZ dd
lmZmZ ddd„Zddd„Zddd„Z	 	 	 	 	 	 dd„Zej6                  j9                  e«      Z	 	 	 	 	 	 dd„Zej6                  j9                  e«      Z G d„ dej@                  «      Z!y)z2Loss functions and criterion for RF-DETR training.é    )Úannotations)ÚAnyN)Únn)Úcompute_l1_keypoint_loss)Úcalculate_uncertaintyÚ*get_uncertain_point_coords_with_randomnessÚpoint_sample)Úaccuracy)Úbox_ops)Úget_world_sizeÚis_dist_avail_and_initializedc                ó  — | j                  «       }t        j                  | |d¬«      }||z  d|z
  d|z
  z  z   }|d|z
  |z  z  }|dk\  r||z  d|z
  d|z
  z  z   }	|	|z  }|j                  d«      j	                  «       |z  S )aÁ  
    Loss used in RetinaNet for dense detection: https://arxiv.org/abs/1708.02002.

    Args:
        inputs: A float tensor of arbitrary shape.
                The predictions for each example.
        targets: A float tensor with the same shape as inputs. Stores the binary
                 classification label for each element in inputs
                (0 for the negative class and 1 for the positive class).
        alpha: (optional) Weighting factor in range (0,1) to balance
                positive vs negative examples. Default = -1 (no weighting).
        gamma: Exponent of the modulating factor (1 - p_t) to
               balance easy vs hard examples.

    Returns:
        Loss tensor
    Únone©Ú	reductioné   r   )ÚsigmoidÚFÚ binary_cross_entropy_with_logitsÚmeanÚsum)
ÚinputsÚtargetsÚ	num_boxesÚalphaÚgammaÚprobÚce_lossÚp_tÚlossÚalpha_ts
             úb/var/www/ramen.bs-engineer-server.com/venv/lib/python3.12/site-packages/rfdetr/models/criterion.pyÚsigmoid_focal_lossr#      s™   € ð$ �>‰>Ó€DÜ×0Ñ0°¸ÈFÔS€GØ
�‰.˜A ™H¨¨W©Ñ5Ñ
5€CØ�q˜3‘w 5Ñ(Ñ)€Dà�‚zØ˜'‘/ Q¨¡Y°1°w±;Ñ$?Ñ?ˆØ˜‰~ˆà�9‰9�Q‹<×ÑÓ 	Ñ)Ð)ó    c                óF  — | j                  «       }||dkD  j                  «       z  d|z
  ||z
  j                  «       j                  |«      z  |dk  j                  «       z  z   }t	        j
                  | |d¬«      }||z  }|j                  d«      j                  «       |z  S )Nç        r   r   r   )r   ÚfloatÚabsÚpowr   r   r   r   )	r   r   r   r   r   r   Úfocal_weightr   r    s	            r"   Úsigmoid_varifocal_lossr+   =   s    € Ø�>‰>Ó€Dà�7˜S‘=×'Ñ'Ó)Ñ)¨Q°©Y¸4À'¹>×:NÑ:NÓ:P×:TÑ:TÐUZÓ:[Ñ,[Ð_fÐjmÑ_m×^tÑ^tÓ^vÑ,vÑvð ô ×0Ñ0°¸ÈFÔS€GØ�\Ñ!€Dà�9‰9�Q‹<×ÑÓ 	Ñ)Ð)r$   c                óF  — | j                  «       }t        j                  | |d¬«      }|t        j                  ||z
  «      |z  z  }|dk\  r5||dkD  j                  «       z  d|z
  |dk  j                  «       z  z   }||z  }|j                  d«      j                  «       |z  S )Nr   r   r   r&   r   )r   r   r   Útorchr(   r'   r   r   )	r   r   r   r   r   r   r   r    r!   s	            r"   Úposition_supervised_lossr.   H   sœ   € Ø�>‰>Ó€DÜ×0Ñ0°¸ÈFÔS€GØ”e—i‘i ¨$¡Ó/°5Ñ8Ñ9€Dà�‚zØ˜7 S™=×/Ñ/Ó1Ñ1°Q¸±YÀ7ÈcÁ>×BXÑBXÓBZÑ4ZÑZˆØ˜‰~ˆà�9‰9�Q‹<×ÑÓ 	Ñ)Ð)r$   c                óú   — | j                  «       } | j                  d«      } d| |z  j                  d«      z  }| j                  d«      |j                  d«      z   }d|dz   |dz   z  z
  }|j                  «       |z  S )aŒ  Compute the DICE loss, similar to generalized IOU for masks.

    Args:
        inputs: A float tensor of arbitrary shape.
                The predictions for each example.
        targets: A float tensor with the same shape as inputs. Stores the binary
                 classification label for each element in inputs
                (0 for the negative class and 1 for the positive class).
    r   é   éÿÿÿÿ)r   Úflattenr   )r   r   Ú	num_masksÚ	numeratorÚdenominatorr    s         r"   Ú	dice_lossr6   T   sz   € ð �^‰^Ó€FØ�^‰^˜AÓ€FØ�V˜gÑ%×*Ñ*¨2Ó.Ñ.€IØ—*‘*˜R“. 7§;¡;¨r£?Ñ2€KØ�	˜A‘ +°¡/Ñ2Ñ2€DØ�8‰8‹:˜	Ñ!Ð!r$   c                óv   — t        j                  | |d¬«      }|j                  d«      j                  «       |z  S )aq  
    Args:
        inputs: A float tensor of arbitrary shape.
                The predictions for each example.
        targets: A float tensor with the same shape as inputs. Stores the binary
                 classification label for each element in inputs
                (0 for the negative class and 1 for the positive class).

    Returns:
        Loss tensor
    r   r   r   )r   r   r   r   )r   r   r3   r    s       r"   Úsigmoid_ce_lossr8   m   s4   € ô  ×-Ñ-¨f°gÈÔP€Dà�9‰9�Q‹<×ÑÓ 	Ñ)Ð)r$   c                  óú   ‡ — e Zd ZU dZdZded<   	 	 	 	 	 	 	 d	 	 	 dˆ fd„Zedd„«       Z	 	 	 	 	 	 dd„Z	dd„Z
 ej                  «       d	„ «       Zd
„ Zd„ Z	 	 	 	 	 	 	 	 	 	 dd„Zd„ Zd„ Zd„ Z	 d	 	 	 	 	 	 	 dd„Zˆ xZS )ÚSetCriteriona  This class computes the loss for Conditional DETR.

    The process happens in two steps:
    1) we compute Hungarian assignment between ground truth boxes and the outputs of the model.
    2) we supervise each pair of matched ground-truth / prediction (supervise class and box).
    TÚboolÚ!supports_loss_normalizer_overridec                óÒ   •— t         ‰| �  «        || _        || _        || _        || _        || _        || _        || _        || _	        |	| _
        |
| _        || _        |xs g | _        y)a4  Create the criterion.

        Parameters:
            num_classes: number of object categories, omitting the special no-object category
            matcher: module able to compute a matching between targets and proposals
            weight_dict: dict containing as key the names of the losses and as values their relative weight.
            losses: list of all the losses to be applied. See get_loss for list of available losses.
            focal_alpha: alpha in Focal Loss
            group_detr: Number of groups to speed detr training. Default is 1.
        N)ÚsuperÚ__init__Únum_classesÚmatcherÚweight_dictÚlossesÚfocal_alphaÚ
group_detrÚsum_group_lossesÚuse_varifocal_lossÚuse_position_supervised_lossÚia_bce_lossÚmask_point_sample_ratioÚnum_keypoints_per_class)Úselfr@   rA   rB   rD   rC   rE   rF   rG   rH   rI   rJ   rK   Ú	__class__s                €r"   r?   zSetCriterion.__init__“   sr   ø€ ô2 	‰ÑÔØ&ˆÔØˆŒØ&ˆÔØˆŒØ&ˆÔØ$ˆŒØ 0ˆÔØ"4ˆÔØ,HˆÔ)Ø&ˆÔØ'>ˆÔ$Ø'>Ò'DÀ"ˆÕ$r$   c                óˆ   — | j                  «       D ]%  }t        j                  |«      sŒ|j                  c S  t	        d«      ‚)a�  Return the device used by tensor outputs.

        Args:
            outputs: Model output dictionary. Top-level values are probed for tensors;
                nested structures (lists, nested dicts) are not traversed.

        Returns:
            Device of the first tensor value found in ``outputs``.

        Raises:
            ValueError: If no tensor output is present.
        zJSetCriterion requires at least one tensor output to infer the loss device.)Úvaluesr-   Ú	is_tensorÚdeviceÚ
ValueError)ÚoutputsÚvalues     r"   Ú_output_devicezSetCriterion._output_deviceº   s>   € ð —^‘^Ó%ò 	$ˆEÜ�‰˜uÕ%Ø—|‘|Ò#ð	$ô ÐeÓfÐfr$   c                ó|  — | j                   r| j                  nd}t        d„ |D «       «      }| j                  s||z  }t	        j
                  |t        j                  | j                  |«      ¬«      }t        «       rt        j                  j                  |«       t	        j                  |t        «       z  d¬«      S )aë  Compute the distributed target-box denominator for a target batch.

        The denominator is the total number of ground-truth boxes in the batch, multiplied by the active number of
        DETR groups (unless ``sum_group_losses`` collapses them), reduced across all distributed ranks, divided by the
        world size, and finally clamped to be at least ``1.0`` so divide-by-zero never occurs on empty batches.

        Args:
            outputs: Model output dictionary; used only to infer the device for the
                returned scalar tensor.
            targets: Per-image target dictionaries for the current batch. Each must
                contain a ``"labels"`` tensor whose length equals the number of
                ground-truth boxes for that image.

        Returns:
            Scalar tensor on the same device as the model outputs, holding the
            average box-count denominator used to normalize criterion losses.

        Note:
            When ``torch.distributed`` is initialized this method performs an
            in-place ``all_reduce`` collective on the returned tensor. Every rank
            must reach this call together or the program will deadlock.

        Note:
            ``group_detr`` is multiplied in only when ``self.training`` is ``True``.
            During evaluation (``self.training`` is ``False``) the denominator
            collapses to a single group, so train-time and eval-time normalizers
            cannot be compared directly.

        Examples:
            >>> import torch
            >>> from rfdetr.models.criterion import SetCriterion
            >>> criterion = SetCriterion.__new__(SetCriterion)
            >>> criterion.training = False
            >>> criterion.group_detr = 1
            >>> criterion.sum_group_losses = False
            >>> outputs = {"pred_logits": torch.zeros(1, 1, 1)}
            >>> targets = [{"labels": torch.tensor([0, 1, 2])}]
            >>> criterion.num_boxes_for_targets(outputs, targets).item()
            3.0
        r   c              3  ó8   K  — | ]  }t        |d    «      –— Œ y­w)ÚlabelsN)Úlen)Ú.0Úts     r"   ú	<genexpr>z5SetCriterion.num_boxes_for_targets.<locals>.<genexpr>û   s   è ø€ Ò:¨Qœ˜A˜h™K×(Ñ:ùs   ‚©ÚdtyperQ   g      ð?)Úmin)ÚtrainingrE   r   rF   r-   Ú	as_tensorr'   rU   r   ÚdistributedÚ
all_reduceÚclampr   )rL   rS   r   rE   r   Únum_boxes_tensors         r"   Únum_boxes_for_targetsz"SetCriterion.num_boxes_for_targetsÍ   s’   € ðZ )-¯ª�T—_’_¸1ˆ
ÜÑ:°'Ô:Ó:ˆ	Ø×$Ò$Ø! JÑ.ˆIÜ Ÿ?™?¨9¼E¿K¹KÐPT×PcÑPcÐdkÓPlÔmÐÜ(Ô*Ü×Ñ×(Ñ(Ð)9Ô:Ü�{‰{Ð+¬nÓ.>Ñ>ÀCÔHÐHr$   c           	     ó  — d|v sJ ‚|d   }| j                  |«      }t        j                  t        ||«      D ��	�
cg c]  \  }\  }	}
|d   |
   ‘Œ c}
}	}«      }| j                  �rú| j
                  }d}|d   |   }t        j                  t        ||«      D ��	�cg c]  \  }\  }	}|d   |   ‘Œ c}}	}d¬«      }t        j                  t        j                  t        j                  |j                  «       «      t        j                  |«      «      d   «      }|j                  «       j                  «       }|j                  «       }t        j                  |«      }||z  }|D �cg c]  }|‘Œ }}|j                  |«       |t        |«         j!                  |«      |j!                  d|z
  «      z  }t        j"                  |d	«      j                  «       }|j%                  |j&                  «      |t        |«      <   d|j%                  |j&                  «      z
  |t        |«      <   ||z  t)        j*                  |«      ||z   z  z
  }|j-                  «       |z  }�n\| j.                  �rÅ|d   |   }t        j                  t        ||«      D ��	�cg c]  \  }\  }	}|d   |   ‘Œ c}}	}d¬«      }t        j                  t        j                  t        j                  |j                  «       «      t        j                  |«      «      d   «      }|j                  «       j                  «       }|}t        j0                  |j2                  d   |j2                  d   | j4                  f|j&                  |j6                  ¬
«      }|D �cg c]  }|‘Œ }}|j                  |«       |j%                  |j&                  «      }||t        |«      <   ||j9                  |j2                  d   dd«      j;                  dd«      dz   z  }t=        |||| j
                  d¬«      |j2                  d   z  }�nŠ| j>                  �rr|d   |   }t        j                  t        ||«      D ��	�cg c]  \  }\  }	}|d   |   ‘Œ c}}	}d¬«      }t        j                  t        j                  t        j                  |j                  «       «      t        j                  |«      «      d   «      }|j                  «       j                  «       }t        j0                  |j2                  d   |j2                  d   | j4                  f|j&                  |j6                  ¬
«      }|D �cg c]  }|‘Œ }}|j                  |«       ||t        |«      <   tA        |||| j
                  d¬«      |j2                  d   z  }�nt        jB                  |j2                  dd | j4                  t        jD                  |j6                  ¬
«      }|||<   t        j0                  |j2                  d   |j2                  d   |j2                  d   dz   g|j&                  |jF                  |j6                  ¬«      }|jI                  d|jK                  d«      d«       |dd…dd…dd…f   }tM        |||| j
                  d¬«      |j2                  d   z  }d|i}|rdtO        ||   |«      d   z
  |d<   |S c c}
}	}w c c}}	}w c c}w c c}}	}w c c}w c c}}	}w c c}w )zˆClassification loss (Binary focal loss) targets dicts must contain the key "labels" containing a tensor of
        dim [nb_target_boxes]Úpred_logitsrX   r0   Ú
pred_boxesÚboxesr   ©Údimr   g{®Gáz„?r]   r1   Tg:Œ0âŽyE>)r   r   N)r^   ÚlayoutrQ   Úloss_ceéd   Úclass_error)(Ú_get_src_permutation_idxr-   ÚcatÚziprI   rD   Údiagr   Úbox_iouÚbox_cxcywh_to_xyxyÚdetachÚcloner   Ú
zeros_likeÚappendÚtupler)   rd   Útor^   r   Ú
logsigmoidr   rH   ÚzerosÚshaper@   rQ   ÚviewÚamaxr.   rG   r+   ÚfullÚint64rm   Úscatter_Ú	unsqueezer#   r
   ) rL   rS   r   Úindicesr   ÚlogÚ
src_logitsÚidxr[   Ú_ÚJÚtarget_classes_or   r   Ú	src_boxesÚiÚtarget_boxesÚiou_targetsÚpos_iousr   Úpos_weightsÚneg_weightsÚidÚpos_indrn   Úpos_ious_funcÚcls_iou_func_targetsÚnorm_cls_iou_func_targetsÚcls_iou_targetsÚtarget_classesÚtarget_classes_onehotrC   s                                    r"   Úloss_labelszSetCriterion.loss_labels  s¥  € ð  Ñ'Ð'Ð'Ø˜]Ñ+ˆ
à×+Ñ+¨GÓ4ˆÜ Ÿ9™9ÄcÈ'ÐSZÓF[×%\Ð%\¹¸¹F¸QÀ a¨¡k°!£nÔ%\Ó]Ðà×ÓØ×$Ñ$ˆEØˆEØ Ñ-¨cÑ2ˆIÜ Ÿ9™9ÄSÈÐRYÓEZ×%[Ð%[¹	¸¹6¸A¸q a¨¡j°£mÔ%[ÐabÔcˆLäŸ*™*Ü—‘Ü×.Ñ.¨y×/?Ñ/?Ó/AÓBÜ×.Ñ.¨|Ó<óð ñóˆKð #×(Ñ(Ó*×1Ñ1Ó3ˆHØ×%Ñ%Ó'ˆDä×*Ñ*¨:Ó6ˆKØ ™+ˆKà$'Ö(˜b’rÐ(ˆGÐ(Ø�N‰NÐ+Ô,à”U˜7“^Ñ$×(Ñ(¨Ó/°(·,±,¸qÀ5¹yÓ2IÑIˆAÜ—‘˜A˜tÓ$×+Ñ+Ó-ˆAà*+¯$©$¨{×/@Ñ/@Ó*AˆKœ˜g›Ñ'Ø*+¨a¯d©d°;×3DÑ3DÓ.EÑ*EˆKœ˜g›Ñ'ð " JÑ.´·±¸jÓ1IÈ[Ð[fÑMfÑ1gÑgˆGØ—k‘k“m iÑ/ŠGà×.Ó.Ø Ñ-¨cÑ2ˆIÜ Ÿ9™9ÄSÈÐRYÓEZ×%[Ð%[¹	¸¹6¸A¸q a¨¡j°£mÔ%[ÐabÔcˆLäŸ*™*Ü—‘Ü×.Ñ.¨y×/?Ñ/?Ó/AÓBÜ×.Ñ.¨|Ó<óð ñóˆKð #×(Ñ(Ó*×1Ñ1Ó3ˆHà$ˆMä#(§;¡;Ø×!Ñ! !Ñ$ j×&6Ñ&6°qÑ&9¸4×;KÑ;KÐLØ ×&Ñ&Ø!×(Ñ(ô$Ð ð %(Ö(˜b’rÐ(ˆGÐ(Ø�N‰NÐ+Ô,Ø)×,Ñ,Ð-A×-GÑ-GÓHˆMØ3@Ð ¤ w£Ñ0Ø(<Ø$×)Ñ)Ð*>×*DÑ*DÀQÑ*GÈÈQÓO×TÑTÐUVÐX\Ó]Ð`dÑdñ)Ð%ô )ØØ-ØØ×*Ñ*Øôð ×"Ñ" 1Ñ%ñ&ò ð ×$Ó$Ø Ñ-¨cÑ2ˆIÜ Ÿ9™9ÄSÈÐRYÓEZ×%[Ð%[¹	¸¹6¸A¸q a¨¡j°£mÔ%[ÐabÔcˆLäŸ*™*Ü—‘Ü×.Ñ.¨y×/?Ñ/?Ó/AÓBÜ×.Ñ.¨|Ó<óð ñóˆKð #×(Ñ(Ó*×1Ñ1Ó3ˆHä#Ÿk™kØ×!Ñ! !Ñ$ j×&6Ñ&6°qÑ&9¸4×;KÑ;KÐLØ ×&Ñ&Ø!×(Ñ(ôˆOð %(Ö(˜b’rÐ(ˆGÐ(Ø�N‰NÐ+Ô,Ø.6ˆOœE '›NÑ+ä&ØØ#ØØ×*Ñ*Øôð ×"Ñ" 1Ñ%ñ&ò ô #ŸZ™ZØ× Ñ   !Ð$Ø× Ñ Ü—k‘kØ!×(Ñ(ô	ˆNð #3ˆN˜3Ñä$)§K¡KØ×!Ñ! !Ñ$ j×&6Ñ&6°qÑ&9¸:×;KÑ;KÈAÑ;NÐQRÑ;RÐSØ ×&Ñ&Ø!×(Ñ(Ø!×(Ñ(ô	%Ð!ð "×*Ñ*¨1¨n×.FÑ.FÀrÓ.JÈAÔNà$9º!ºQÀÀÀ¸)Ñ$DÐ!ä"ØØ)ØØ×*Ñ*Øôð ×"Ñ" 1Ñ%ñ&ð ð ˜WÐ%ˆáà$'¬(°:¸c±?ÐDTÓ*UÐVWÑ*XÑ$XˆF�=Ñ!ØˆùôO &]ùô &\ùò )ùô &\ùò$ )ùô( &\ùò  )s)   ¼[Â[$Å(	[+Ê[0Î	[7Ñ'[<Õ	\c           	     óf  — |d   }|j                   }t        j                  |D �cg c]  }t        |d   «      ‘Œ c}|¬«      }|j	                  d«      |j
                  d   dz
  k7  j                  d«      }	t        j                  |	j                  «       |j                  «       «      }
d|
i}|S c c}w )zÝCompute the cardinality error, ie the absolute error in the number of predicted non-empty boxes This is not
        really a loss, it is intended for logging purposes only.

        It doesn't propagate gradients
        rh   rX   ©rQ   r1   r   Úcardinality_error)
rQ   r-   ra   rY   Úargmaxr   r   r   Úl1_lossr'   )rL   rS   r   r†   r   rh   rQ   ÚvÚtgt_lengthsÚ	card_predÚcard_errrC   s               r"   Úloss_cardinalityzSetCriterion.loss_cardinality“  s£   € ð ˜mÑ,ˆØ×#Ñ#ˆÜ—o‘oÀÖ&I¸A¤s¨1¨X©;Õ'7Ò&IÐRXÔYˆà ×'Ñ'¨Ó+¨{×/@Ñ/@ÀÑ/DÀqÑ/HÑH×MÑMÈaÓPˆ	Ü—9‘9˜YŸ_™_Ó.°×0AÑ0AÓ0CÓDˆØ% xÐ0ˆØˆùò 'Js   ¥B.c           	     ó   — d|v sJ ‚| j                  |«      }|d   |   }t        j                  t        ||«      D ���	cg c]  \  }\  }}	|d   |	   ‘Œ c}	}}d¬«      }
t	        j
                  ||
d¬«      }i }|j                  «       |z  |d<   dt        j                  t        j                  t        j                  |«      t        j                  |
«      «      «      z
  }|j                  «       |z  |d	<   |S c c}	}}w )
a'  Compute the losses related to the bounding boxes, the L1 regression loss and the GIoU loss targets dicts must
        contain the key "boxes" containing a tensor of dim [nb_target_boxes, 4] The target boxes are expected in format
        (center_x, center_y, w, h), normalized by the image size.ri   rj   r   rk   r   r   Ú	loss_bboxr   Ú	loss_giou)rq   r-   rr   rs   r   r¡   r   rt   r   Úgeneralized_box_iourv   )rL   rS   r   r†   r   r‰   r�   r[   rŠ   rŽ   r�   r¨   rC   r©   s                 r"   Ú
loss_boxeszSetCriterion.loss_boxes£  sô   € ð ˜wÑ&Ð&Ð&Ø×+Ñ+¨GÓ4ˆØ˜LÑ)¨#Ñ.ˆ	Ü—y‘yÄÀWÈgÓAV×!WÐ!W±I°A±v¸¸1 ! G¡*¨Q£-Ô!WÐ]^Ô_ˆä—I‘I˜i¨ÀÔHˆ	àˆØ'Ÿm™m›o°	Ñ9ˆˆ{ÑàœŸ
™
Ü×'Ñ'Ü×*Ñ*¨9Ó5Ü×*Ñ*¨<Ó8óó
ñ 
ˆ	ð (Ÿm™m›o°	Ñ9ˆˆ{ÑØˆùô "Xs   ¿C9c           	     óv  — d|v sJ d«       ‚| j                  |«      }|d   }t        |t        j                  «      r||   }�nD|d   d   }|d   d   }	|d   d   }
|d   j	                  «       dk(  r$|j
                  }t        j                  g |¬«      }nòg }|d   j                  d¬	«      d
   }t        j                  t        j                  |dd
 «      |fd¬«      j                  d«      }t        |j                  d   «      D ]j  }|d   ||   ||d
z       }|d
   ||   ||d
z       }|	||f   }||d   ||d
z      d
z
        }t        j                  d||«      |
z   }|j                  |«       Œl t        j                  |«      }|j	                  «       dk(  r!|j                  «       |j                  «       dœS t        j                  t!        ||«      D ���cg c]  \  }\  }}|d   |   ‘Œ c}}}d¬«      }|j#                  d
«      }|j#                  d
«      j%                  «       }t'        |j                  d   |j                  d   |j                  d   z  | j(                  z  «      }t        j*                  «       5  t-        |d„ |dd«      }ddd«       t/        |d¬«      j1                  d
«      }t        j*                  «       5  t/        ||dd¬«      j1                  d
«      }ddd«       t%        |«      }t3        ||«      t5        |||«      dœ}~~|S c c}}}w # 1 sw Y   Œ’xY w# 1 sw Y   ŒFxY w)z¾Compute BCE-with-logits and Dice losses for segmentation masks on matched pairs.

        Expects outputs to contain 'pred_masks' of shape [B, Q, H, W] and targets with key 'masks'.
        Ú
pred_masksz#pred_masks missing in model outputsÚspatial_featuresÚquery_featuresÚbiasr   rž   T)Úreturn_countsr   Nrk   zchw,nc->nhw)Úloss_mask_ceÚloss_mask_diceÚmaskséþÿÿÿr1   c                ó   — t        | «      S ©N)r   )Úlogitss    r"   ú<lambda>z)SetCriterion.loss_masks.<locals>.<lambda>þ  s   € Ô4°VÓ<€ r$   é   g      è?F)Úalign_cornersÚnearest)r»   Úmode)rq   Ú
isinstancer-   ÚTensorÚnumelrQ   ÚtensorÚuniquerr   ry   ÚcumsumÚranger   Úeinsumrz   r   rs   r…   r'   ÚmaxrJ   Úno_gradr   r	   ÚsqueezeÚsigmoid_ce_loss_jitÚdice_loss_jit)rL   rS   r   r†   r   r‰   r­   Ú	src_masksr®   r¯   r°   rQ   Úbatched_selected_masksÚper_batch_countsÚbatch_indicesrŽ   Úbatch_indicatorÚbox_indicatorÚthis_batch_queriesÚthis_batch_spatial_featuresÚthis_batch_masksr[   rŠ   ÚjÚtarget_masksÚ
num_pointsÚpoint_coordsÚpoint_logitsÚpoint_labelsÚnum_boxes_scalarrC   s                                  r"   Ú
loss_maskszSetCriterion.loss_masksº  s‡  € ð
 ˜wÑ&ÐMÐ(MÓMÐ&Ø×+Ñ+¨GÓ4ˆØ˜\Ñ*ˆ
ä�j¤%§,¡,Ô/ð # 3™ŠIà& |Ñ4Ð5GÑHÐØ$ \Ñ2Ð3CÑDˆNØ˜<Ñ(¨Ñ0ˆDà�1‰v�|‰|‹~ Ò"Ø)×0Ñ0�Ü!ŸL™L¨°FÔ;‘	à)+Ð&Ø#& q¡6§=¡=¸t =Ó#DÀQÑ#GÐ Ü %§	¡	¬5×+;Ñ+;Ð<LÈRÈaÐ<PÓ+QÐScÐ*dÐjkÔ l× sÑ sÐtuÓ v�äÐ/×5Ñ5°aÑ8Ó9ò D�AØ&)¨!¡f¨]¸1Ñ-=ÀÈaÐRSÉeÑ@TÐ&U�OØ$'¨¡F¨=¸Ñ+;¸mÈAÐPQÉEÑ>RÐ$S�Mà)7¸È-Ð8XÑ)YÐ&Ø2BÀ3ÀqÁ6È-ÐXYÐ\]ÑX]ÑJ^ÐabÑJbÑCcÑ2dÐ/ô Ÿ™Ø)Ø7Ø.óð
 ñð %ð +×1Ñ1Ð2BÕCð!Dô$ "ŸI™IÐ&<Ó=�	à�?‰?Ó Ò!à )§¡£Ø"+§-¡-£/ñð ô
 —y‘yÄÀWÈgÓAV×!WÐ!W±I°A±v¸¸1 ! G¡*¨Q£-Ô!WÐ]^Ô_ˆð ×'Ñ'¨Ó*ˆ	Ø#×-Ñ-¨aÓ0×6Ñ6Ó8ˆäØ�O‰O˜BÑØ�O‰O˜BÑ )§/¡/°"Ñ"5Ñ5¸×9UÑ9UÑUó
ˆ
ô
 �]‰]‹_ñ 	äEØÙ<ØØØóˆL÷	ô $ØØØô
÷ ‰'�!‹*ð	 	ô �]‰]‹_ñ 	ä'ØØØ#Øô	÷
 ‰g�a‹jð ÷	ô" ! Ó+Ðä/°¸lÐL\Ó]Ü+¨L¸,ÐHXÓYñ
ˆð
 ØØˆùôk "X÷	ð 	ú÷ 	ð 	ús   ÇLÊL#ËL/Ì#L,Ì/L8c           	     ót  — d|v sJ ‚| j                  |«      }|d   |   }t        j                  t        ||«      D ���	cg c]  \  }\  }}	|d   |	   ‘Œ c}	}}d¬«      }
t        j                  t        ||«      D ���	cg c]  \  }\  }}	|d   |	   ‘Œ c}	}}d¬«      }t        j                  t        ||«      D ���	cg c]  \  }\  }}	|d   |	   ‘Œ c}	}}d¬«      }|dd…df   |dd…d	f   z  }t	        ||
j                  |j                  «      |j                  |j                  «      |j                  |j                  «      | j                  ¬
«      \  }}}}|j                  «       |z  |j                  «       |z  |j                  «       |z  |j                  «       |z  dœS c c}	}}w c c}	}}w c c}	}}w )z;Compute keypoint losses on matched prediction/target pairs.Úpred_keypointsÚ	keypointsr   rk   rX   rj   Nr0   rº   )Úall_pred_keypointsÚtarget_keypointsrš   Útarget_areasrK   )Úloss_keypoints_l1Úloss_keypoints_findableÚloss_keypoints_visibleÚloss_keypoints_nll)	rq   r-   rr   rs   r   r|   rQ   rK   r   )rL   rS   r   r†   r   r‰   Úsrc_keypointsÚtargetrŠ   rÔ   rà   rš   r�   rá   Úloss_l1Úloss_findableÚloss_visibleÚloss_nlls                     r"   Úloss_keypointszSetCriterion.loss_keypoints%  s«  € ð   7Ñ*Ð*Ð*Ø×+Ñ+¨GÓ4ˆØÐ 0Ñ1°#Ñ6ˆÜ Ÿ9™9ÔSVÐW^Ð`gÓSh×%iÐ%iÁÀÉÈ!ÈQ f¨[Ñ&9¸!Ó&<Ô%iÐopÔqÐÜŸ™ÌcÐRYÐ[bÓNc×#dÐ#d¹N¸FÁFÀQÈ F¨8Ñ$4°QÓ$7Ô#dÐjkÔlˆÜ—y‘yÌ3ÈwÐX_ÓK`×!aÐ!a¹¸ÁÀ!ÀQ &¨¡/°!Ó"4Ô!aÐghÔiˆØ#¢A q DÑ)¨Lº¸A¸Ñ,>Ñ>ˆä9QØ,Ø-×0Ñ0°×1EÑ1EÓFØ)×,Ñ,¨]×-AÑ-AÓBØ%Ÿ™¨×)=Ñ)=Ó>Ø$(×$@Ñ$@ô:
Ñ6ˆ� ¨hð ")§¡£°Ñ!:Ø'4×'8Ñ'8Ó':¸YÑ'FØ&2×&6Ñ&6Ó&8¸9Ñ&DØ"*§,¡,£.°9Ñ"<ñ	
ð 	
ùô &jùÜ#dùÜ!as   ¿F%Á>F,Â=F3c                ó  — t        j                  t        |«      D ���cg c]  \  }\  }}t        j                  ||«      ‘Œ  c}}}«      }t        j                  |D ��cg c]  \  }}|‘Œ	 c}}«      }||fS c c}}}w c c}}w r·   ©r-   rr   Ú	enumerateÚ	full_like)rL   r†   rŽ   ÚsrcrŠ   Ú	batch_idxÚsrc_idxs          r"   rq   z%SetCriterion._get_src_permutation_idxD  sh   € ä—I‘IÌ)ÐT[ÓJ\×]Ð]¹;¸1¹h¸sÀAœuŸ™¨s°AÕ6Ô]Ó^ˆ	Ü—)‘)°×9¡X c¨1šSÓ9Ó:ˆØ˜'Ð!Ð!ùô ^ùÛ9ó   Ÿ#A7ÁA>
c                ó  — t        j                  t        |«      D ���cg c]  \  }\  }}t        j                  ||«      ‘Œ  c}}}«      }t        j                  |D ��cg c]  \  }}|‘Œ	 c}}«      }||fS c c}}}w c c}}w r·   rî   )rL   r†   rŽ   rŠ   Útgtrò   Útgt_idxs          r"   Ú_get_tgt_permutation_idxz%SetCriterion._get_tgt_permutation_idxJ  sh   € ä—I‘IÌ)ÐT[ÓJ\×]Ð]¹;¸1¹h¸qÀ#œuŸ™¨s°AÕ6Ô]Ó^ˆ	Ü—)‘)°×9¡X a¨šSÓ9Ó:ˆØ˜'Ð!Ð!ùô ^ùÛ9rô   c                ó²   — | j                   | j                  | j                  | j                  | j                  dœ}||v sJ d|› d�«       ‚ ||   ||||fi |¤ŽS )N)rX   Úcardinalityrj   r´   rÞ   zdo you really want to compute z loss?)rœ   r¦   r«   rÛ   rì   )rL   r    rS   r   r†   r   ÚkwargsÚloss_maps           r"   Úget_losszSetCriterion.get_lossP  sm   € à×&Ñ&Ø×0Ñ0Ø—_‘_Ø—_‘_Ø×,Ñ,ñ
ˆð �xÑÐNÐ#AÀ$ÀÀvÐ!NÓNÐØˆx˜‰~˜g w°¸ÑMÀfÑMÐMr$   c           
     ó¬  — | j                   r| j                  nd}|j                  «       D ��ci c]  \  }}|dk7  sŒ||“Œ }}}| j                  |||¬«      }|€| j	                  ||«      }n{t        j                  |«      s6t        j                  |t
        j                  | j                  |«      ¬«      }n0|j                  | j                  |«      t
        j                  ¬«      }i }	| j                  D ]&  }
|	j                  | j                  |
||||«      «       Œ( d|v r—t        |d   «      D ]†  \  }}| j                  |||¬«      }| j                  D ]^  }
i }|
dk(  rddi} | j                  |
||||fi |¤Ž}|j                  «       D ��ci c]  \  }}|d	|› �z   |“Œ }}}|	j                  |«       Œ` Œˆ d
|v r„|d
   }| j                  |||¬«      }| j                  D ]\  }
i }|
dk(  rd|d<    | j                  |
||||fi |¤Ž}|j                  «       D ��ci c]  \  }}|dz   |“Œ }}}|	j                  |«       Œ^ |	S c c}}w c c}}w c c}}w )u   Compute every configured loss for one (outputs, targets) pair.

        The Hungarian matcher is invoked on the last layer's outputs and reused for the auxiliary intermediate layers
        and the optional encoder outputs; each loss is then evaluated on the matched indices and normalized by
        ``num_boxes``.

        Args:
            outputs: Model output dictionary. Must contain the tensors required by
                every loss in ``self.losses`` (for example ``"pred_logits"``,
                ``"pred_boxes"``, ``"pred_masks"``, ``"pred_keypoints"``). May also
                contain ``"aux_outputs"`` (list of layer-wise outputs) and
                ``"enc_outputs"`` (encoder outputs); both are processed identically
                to the last layer and contribute prefixed keys to the returned dict.
            targets: Per-image target dictionaries; ``len(targets) == batch_size``.
                The expected keys depend on the losses being applied â€” see each
                ``loss_*`` method for its target requirements.
            num_boxes: Optional explicit box-count denominator.

                - ``None`` (default): call :meth:`num_boxes_for_targets` to derive
                  the distributed-reduced normalizer for the current batch.
                - ``float`` / ``int``: cast to a tensor on the model output device
                  and used verbatim. Passing ``1.0`` yields *unnormalized* loss
                  numerators (used by the manual-optimization path so the caller
                  can apply its own accumulated denominator).
                - ``torch.Tensor``: moved to the model output device and used
                  verbatim. The caller is responsible for any cross-rank reduction;
                  no extra all-reduce is performed in this branch.

        Returns:
            Dictionary of named loss tensors. Last-layer losses keep their base
            names (``"loss_ce"``, ``"loss_bbox"``, ``"loss_giou"``,
            ``"loss_mask_ce"``, ``"loss_mask_dice"``, ``"loss_keypoints_*"``).
            Auxiliary-layer losses get a ``"_<i>"`` suffix; encoder-layer losses
            get an ``"_enc"`` suffix.

        Examples:
            >>> import torch
            >>> from unittest.mock import MagicMock
            >>> from rfdetr.models.criterion import SetCriterion
            >>> criterion = SetCriterion.__new__(SetCriterion)
            >>> criterion.training = False
            >>> criterion.group_detr = 1
            >>> criterion.sum_group_losses = False
            >>> criterion.losses = []
            >>> criterion.matcher = MagicMock(return_value=[])
            >>> outputs = {"pred_logits": torch.zeros(1, 1, 1)}
            >>> targets = [{"labels": torch.tensor([0])}]
            >>> criterion.forward(outputs, targets, num_boxes=1.0)
            {}
        r   Úaux_outputs)rE   r]   )rQ   r^   rX   r‡   FrŠ   Úenc_outputsÚ_enc)r`   rE   ÚitemsrA   rf   r-   rP   ra   r'   rU   r|   rC   Úupdaterý   rï   )rL   rS   r   r   rE   Úkr¢   Úoutputs_without_auxr†   rC   r    rŽ   rÿ   rû   Úl_dictr   s                   r"   ÚforwardzSetCriterion.forward[  sm  € ðp )-¯ª�T—_’_¸1ˆ
Ø07·±³×V©¨¨1À1ÈÓCU˜q !™tÐVÐÑVð —,‘,Ð2°GÈ
�,ÓSˆàÐØ×2Ñ2°7¸GÓD‰IÜ—‘ Ô+ÜŸ™¨	¼¿¹ÈT×M`ÑM`ÐahÓMiÔj‰Ià!Ÿ™¨D×,?Ñ,?ÀÓ,HÔPU×P[ÑP[˜Ó\ˆIð ˆØ—K‘Kò 	UˆDØ�M‰M˜$Ÿ-™-¨¨g°wÀÈÓSÕTð	Uð ˜GÑ#Ü"+¨G°MÑ,BÓ"Cò 	*‘��;ØŸ,™, {°GÈ
˜,ÓS�Ø ŸK™Kò *�DØ�FØ˜xÒ'à"'¨ ˜Ø*˜TŸ]™]¨4°¸gÀwÐPYÑdÐ]cÑd�FØ9?¿¹»×H±°°A˜a A a S '™k¨1™nÐH�FÑHØ—M‘M &Õ)ñ*ð	*ð ˜GÑ#Ø! -Ñ0ˆKØ—l‘l ;°ÀJ�lÓOˆGØŸ™ò &�Ø�Ø˜8Ò#à$)�F˜5‘MØ&˜Ÿ™ t¨[¸'À7ÈIÑ`ÐY_Ñ`�Ø4:·L±L³N×C©D¨A¨q˜!˜f™* a™-ÐC�ÑCØ—‘˜fÕ%ð&ð ˆùóU Wùó6 Iùó Ds   ®I¼IÆI

ÈI)r   FFFFé   N)rJ   ÚintrK   zlist[int] | None)rS   údict[str, Any]Úreturnztorch.device)rS   r
  r   úlist[dict[str, torch.Tensor]]r  útorch.Tensor)T)
rS   Údictr   Úlistr†   r  r   r'   r  údict[str, torch.Tensor]r·   )rS   r
  r   r  r   ztorch.Tensor | float | Noner  r  )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r<   Ú__annotations__r?   ÚstaticmethodrU   rf   rœ   r-   rÇ   r¦   r«   rÛ   rì   rq   rø   rý   r  Ú__classcell__)rM   s   @r"   r:   r:   …   s.  ø… ñð /3Ð% tÓ2ð ØØ Ø%*ØØ')Ø48ð%Eð "%ð%Eð "2õ%EðN ògó ðgð$4Iàð4Ið /ð4Ið 
ó	4IólNð` €U‡]�]ƒ_ñó ðòò.iðV
àð
ð ð
ð ð	
ð
 ð
ð 
!ó
ò>"ò"ò	Nð 26ð	càðcð /ðcð /ð	cð
 
!÷cr$   r:   )g      Ð?r0   )r   r'   r   r'   )r   r  r   r  r3   r'   )"r  Ú
__future__r   Útypingr   r-   Útorch.nn.functionalr   Ú
functionalr   Úrfdetr.models.heads.keypointsr   Ú rfdetr.models.heads.segmentationr   r   r	   Úrfdetr.models.mathr
   Úrfdetr.utilitiesr   Úrfdetr.utilities.distributedr   r   r#   r+   r.   r6   ÚjitÚscriptrÊ   r8   rÉ   ÚModuler:   © r$   r"   ú<module>r%     sÀ   ðñ 9å "å ã ß Ð Ý å B÷ñ õ
 (Ý $ß Vô*ô<*ô	*ð"Øð"àð"ð ó"ð, —	‘	× Ñ  Ó+€ð*Øð*àð*ð ó*ð* —i‘i×&Ñ& Ó7Ð ôy�2—9‘9õ yr$   