docstr: Tests corner head loss when truth is empty and non-empty.
code: def test_corner_head_loss(self):
      """Tests corner head loss when truth is empty and non-empty."""
      s = 256
      img_metas = [
          {
              "img_shape": (s, s, 3),
              "scale_factor": 1,
              "batch_input_shape": (s, s, 3),
          }
      ]
  
      corner_head = CornerHead(num_classes=4, in_channels=1)
  
      # Corner head expects a multiple levels of features per image
      feat = [
          torch.rand(1, 1, s // 4, s // 4)
          for _ in range(corner_head.num_feat_levels)
      ]
      forward_outputs = corner_head.forward(feat)
  
      # Test that empty ground truth encourages the network to
      # predict background
      gt_instances = InstanceData()
      gt_instances.bboxes = torch.empty((0, 4))
      gt_instances.labels = torch.LongTensor([])
      gt_bboxes_ignore = None
  
      empty_gt_losses = corner_head.loss_by_feat(
          *forward_outputs, [gt_instances], img_metas, gt_bboxes_ignore
      )
      empty_det_loss = sum(empty_gt_losses["det_loss"])
      empty_push_loss = sum(empty_gt_losses["push_loss"])
      empty_pull_loss = sum(empty_gt_losses["pull_loss"])
      empty_off_loss = sum(empty_gt_losses["off_loss"])
      self.assertTrue(
          empty_det_loss.item() > 0, "det loss should be non-zero"
      )
      self.assertTrue(
          empty_push_loss.item() == 0,
          "there should be no push loss when there are no true boxes",
      )
      self.assertTrue(
          empty_pull_loss.item() == 0,
          "there should be no pull loss when there are no true boxes",
      )
      self.assertTrue(
          empty_off_loss.item() == 0,
          "there should be no box loss when there are no true boxes",
      )
  
      # When truth is non-empty then both cls and box loss
      # should be nonzero for random inputs
      gt_instances = InstanceData()
      gt_instances.bboxes = torch.Tensor(
          [[23.6667, 23.8757, 238.6326, 151.8874]]
      )
      gt_instances.labels = torch.LongTensor([2])
  
      one_gt_losses = corner_head.loss_by_feat(
          *forward_outputs, [gt_instances], img_metas, gt_bboxes_ignore
      )
      onegt_det_loss = sum(one_gt_losses["det_loss"])
      onegt_push_loss = sum(one_gt_losses["push_loss"])
      onegt_pull_loss = sum(one_gt_losses["pull_loss"])
      onegt_off_loss = sum(one_gt_losses["off_loss"])
      self.assertTrue(
          onegt_det_loss.item() > 0, "det loss should be non-zero"
      )
      self.assertTrue(
          onegt_push_loss.item() == 0,
          "there should be no push loss when there are only one true box",
      )
      self.assertTrue(
          onegt_pull_loss.item() > 0, "pull loss should be non-zero"
      )
      self.assertTrue(
          onegt_off_loss.item() > 0, "off loss should be non-zero"
      )
  
      gt_instances = InstanceData()
      gt_instances.bboxes = torch.Tensor(
          [
              [23.6667, 23.8757, 238.6326, 151.8874],
              [123.6667, 123.8757, 138.6326, 251.8874],
          ]
      )
      gt_instances.labels = torch.LongTensor([2, 3])
  
      two_gt_losses = corner_head.loss_by_feat(
          *forward_outputs, [gt_instances], img_metas, gt_bboxes_ignore
      )
      twogt_det_loss = sum(two_gt_losses["det_loss"])
      twogt_push_loss = sum(two_gt_losses["push_loss"])
      twogt_pull_loss = sum(two_gt_losses["pull_loss"])
      twogt_off_loss = sum(two_gt_losses["off_loss"])
      self.assertTrue(
          twogt_det_loss.item() > 0, "det loss should be non-zero"
      )
      # F.relu limits push loss larger than or equal to 0.
      self.assertTrue(
          twogt_push_loss.item() >= 0, "push loss should be non-zero"
      )
      self.assertTrue(
          twogt_pull_loss.item() > 0, "pull loss should be non-zero"
      )
      self.assertTrue(
          twogt_off_loss.item() > 0, "off loss should be non-zero"
      )
  
file_path: mmdetection/tests/test_models/test_dense_heads/test_corner_head.py
imports: from unittest import TestCase
  import torch
  from mmengine.structures import InstanceData
  from mmdet.evaluation import bbox_overlaps
  from mmdet.models.dense_heads import CornerHead
label_desc: Use image node_id 1 for calling the TestCornerHead obj's underlying member method code with example usage: obj.test_corner_head_loss() without return types