class_docstr: Head of the Grounding DINO: Marrying DINO with Grounded Pre-Training for
  Open-Set Object Detection.
  
  Args:
      contrastive_cfg (dict, optional): Contrastive config that contains
        keys like ``max_text_len``. Defaults to dict(max_text_len=256).
class_docstr_tok: ["Head","of","the","Grounding","DINO",":","Marrying","DINO","with","Grounded","Pre-Training","for","Open-Set","Object","Detection",".","Args",":","contrastive_cfg","(","dict",",","optional",")",":","Contrastive","config","that","contains","keys","like","``","max_text_len","``",".","Defaults","to","dict","(","max_text_len=256",")","."]
docstr: Loss function for outputs from a single decoder layer of a single
  feature level.
  
  Args:
      cls_scores (Tensor): Box score logits from a single decoder layer
          for all images, has shape (bs, num_queries, cls_out_channels).
      bbox_preds (Tensor): Sigmoid outputs from a single decoder layer
          for all images, with normalized coordinate (cx, cy, w, h) and
          shape (bs, num_queries, 4).
      batch_gt_instances (list[:obj:`InstanceData`]): Batch of
          gt_instance. It usually includes ``bboxes`` and ``labels``
          attributes.
      batch_img_metas (list[dict]): Meta information of each image, e.g.,
          image size, scaling factor, etc.
  
  Returns:
      Tuple[Tensor]: A tuple including `loss_cls`, `loss_box` and
      `loss_iou`.
docstr_tok: ["Loss","function","for","outputs","from","a","single","decoder","layer","of","a","single","feature","level",".","Args",":","cls_scores","(","Tensor",")",":","Box","score","logits","from","a","single","decoder","layer","for","all","images",",","has","shape","(","bs",",","num_queries",",","cls_out_channels",")",".","bbox_preds","(","Tensor",")",":","Sigmoid","outputs","from","a","single","decoder","layer","for","all","images",",","with","normalized","coordinate","(","cx",",","cy",",","w",",","h",")","and","shape","(","bs",",","num_queries",",","4",")",".","batch_gt_instances","(","list","[",":","obj",":","`","InstanceData","`","]",")",":","Batch","of","gt_instance",".","It","usually","includes","``","bboxes","``","and","``","labels","``","attributes",".","batch_img_metas","(","list","[","dict","]",")",":","Meta","information","of","each","image",",","e.g.",",","image","size",",","scaling","factor",",","etc",".","Returns",":","Tuple","[","Tensor","]",":","A","tuple","including","`","loss_cls","`",",","`","loss_box","`","and","`","loss_iou","`","."]
code: def loss_by_feat_single(
      self,
      cls_scores: Tensor,
      bbox_preds: Tensor,
      batch_gt_instances: InstanceList,
      batch_img_metas: List[dict],
  ) -> Tuple[Tensor]:
      """Loss function for outputs from a single decoder layer of a single
      feature level.
  
      Args:
          cls_scores (Tensor): Box score logits from a single decoder layer
              for all images, has shape (bs, num_queries, cls_out_channels).
          bbox_preds (Tensor): Sigmoid outputs from a single decoder layer
              for all images, with normalized coordinate (cx, cy, w, h) and
              shape (bs, num_queries, 4).
          batch_gt_instances (list[:obj:`InstanceData`]): Batch of
              gt_instance. It usually includes ``bboxes`` and ``labels``
              attributes.
          batch_img_metas (list[dict]): Meta information of each image, e.g.,
              image size, scaling factor, etc.
  
      Returns:
          Tuple[Tensor]: A tuple including `loss_cls`, `loss_box` and
          `loss_iou`.
      """
      num_imgs = cls_scores.size(0)
      cls_scores_list = [cls_scores[i] for i in range(num_imgs)]
      bbox_preds_list = [bbox_preds[i] for i in range(num_imgs)]
      with torch.no_grad():
          cls_reg_targets = self.get_targets(
              cls_scores_list,
              bbox_preds_list,
              batch_gt_instances,
              batch_img_metas,
          )
      (
          labels_list,
          label_weights_list,
          bbox_targets_list,
          bbox_weights_list,
          num_total_pos,
          num_total_neg,
      ) = cls_reg_targets
      labels = torch.stack(labels_list, 0)
      label_weights = torch.stack(label_weights_list, 0)
      bbox_targets = torch.cat(bbox_targets_list, 0)
      bbox_weights = torch.cat(bbox_weights_list, 0)
  
      # ===== this change =====
      # Loss is not computed for the padded regions of the text.
      assert self.text_masks.dim() == 2
      text_masks = self.text_masks.new_zeros(
          (self.text_masks.size(0), self.max_text_len)
      )
      text_masks[:, : self.text_masks.size(1)] = self.text_masks
      text_mask = (text_masks > 0).unsqueeze(1)
      text_mask = text_mask.repeat(1, cls_scores.size(1), 1)
      cls_scores = torch.masked_select(
          cls_scores, text_mask
      ).contiguous()
  
      labels = torch.masked_select(labels, text_mask)
      label_weights = label_weights[..., None].repeat(
          1, 1, text_mask.size(-1)
      )
      label_weights = torch.masked_select(label_weights, text_mask)
  
      # classification loss
      # construct weighted avg_factor to match with the official DETR repo
      cls_avg_factor = (
          num_total_pos * 1.0 + num_total_neg * self.bg_cls_weight
      )
      if self.sync_cls_avg_factor:
          cls_avg_factor = reduce_mean(
              cls_scores.new_tensor([cls_avg_factor])
          )
      cls_avg_factor = max(cls_avg_factor, 1)
  
      if isinstance(self.loss_cls, QualityFocalLoss):
          raise NotImplementedError(
              "QualityFocalLoss for GroundingDINOHead is not supported yet."
          )
      else:
          loss_cls = self.loss_cls(
              cls_scores,
              labels,
              label_weights,
              avg_factor=cls_avg_factor,
          )
  
      # Compute the average number of gt boxes across all gpus, for
      # normalization purposes
      num_total_pos = loss_cls.new_tensor([num_total_pos])
      num_total_pos = torch.clamp(
          reduce_mean(num_total_pos), min=1
      ).item()
  
      # construct factors used for rescale bboxes
      factors = []
      for img_meta, bbox_pred in zip(batch_img_metas, bbox_preds):
          (
              img_h,
              img_w,
          ) = img_meta["img_shape"]
          factor = (
              bbox_pred.new_tensor([img_w, img_h, img_w, img_h])
              .unsqueeze(0)
              .repeat(bbox_pred.size(0), 1)
          )
          factors.append(factor)
      factors = torch.cat(factors, 0)
  
      # DETR regress the relative position of boxes (cxcywh) in the image,
      # thus the learning target is normalized by the image size. So here
      # we need to re-scale them for calculating IoU loss
      bbox_preds = bbox_preds.reshape(-1, 4)
      bboxes = bbox_cxcywh_to_xyxy(bbox_preds) * factors
      bboxes_gt = bbox_cxcywh_to_xyxy(bbox_targets) * factors
  
      # regression IoU loss, defaultly GIoU loss
      loss_iou = self.loss_iou(
          bboxes, bboxes_gt, bbox_weights, avg_factor=num_total_pos
      )
  
      # regression L1 loss
      loss_bbox = self.loss_bbox(
          bbox_preds,
          bbox_targets,
          bbox_weights,
          avg_factor=num_total_pos,
      )
      return loss_cls, loss_bbox, loss_iou
  
imports: import copy
  import math
  from typing import Dict, List, Optional, Tuple, Union
  import torch
  import torch.nn
  from mmcv.cnn import Linear
  from mmengine.model import constant_init
  from mmengine.structures import InstanceData
  from torch import Tensor
  from mmdet.models.losses import QualityFocalLoss
  from mmdet.registry import MODELS
  from mmdet.structures import SampleList
  from mmdet.structures.bbox import bbox_cxcywh_to_xyxy, bbox_xyxy_to_cxcywh
  from mmdet.utils import InstanceList, reduce_mean
  from ..layers import inverse_sigmoid
  from .atss_vlfusion_head import convert_grounding_to_cls_scores
  from .dino_head import DINOHead
label_desc: Use image node_id 10 for calling the GroundingDINOHead obj's underlying member method code with example usage: obj.loss_by_feat_single(cls_scores, bbox_preds, batch_gt_instances, batch_img_metas) and returns: loss_cls,  loss_bbox,  loss_iou