class_docstr: The class for implementing DRRG loss. This is partially adapted from
  https://github.com/GXYM/DRRG licensed under the MIT license.
  
  DRRG: `Deep Relational Reasoning Graph Network for Arbitrary Shape Text
  Detection <https://arxiv.org/abs/1908.05900>`_.
  
  Args:
      ohem_ratio (float): The negative/positive ratio in ohem. Defaults to
          3.0.
      downsample_ratio (float): Downsample ratio. Defaults to 1.0. TODO:
          remove it.
      orientation_thr (float): The threshold for distinguishing between
          head edge and tail edge among the horizontal and vertical edges
          of a quadrangle. Defaults to 2.0.
      resample_step (float): The step size for resampling the text center
          line. Defaults to 8.0.
      num_min_comps (int): The minimum number of text components, which
          should be larger than k_hop1 mentioned in paper. Defaults to 9.
      num_max_comps (int): The maximum number of text components. Defaults
          to 600.
      min_width (float): The minimum width of text components. Defaults to
          8.0.
      max_width (float): The maximum width of text components. Defaults to
          24.0.
      center_region_shrink_ratio (float): The shrink ratio of text center
          regions. Defaults to 0.3.
      comp_shrink_ratio (float): The shrink ratio of text components.
          Defaults to 1.0.
      comp_w_h_ratio (float): The width to height ratio of text components.
          Defaults to 0.3.
      min_rand_half_height(float): The minimum half-height of random text
          components. Defaults to 8.0.
      max_rand_half_height (float): The maximum half-height of random
          text components. Defaults to 24.0.
      jitter_level (float): The jitter level of text component geometric
          features. Defaults to 0.2.
      loss_text (dict): The loss config used to calculate the text loss.
          Defaults to ``dict(type='MaskedBalancedBCEWithLogitsLoss',
          fallback_negative_num=100, eps=1e-5)``.
      loss_center (dict): The loss config used to calculate the center loss.
          Defaults to ``dict(type='MaskedBCEWithLogitsLoss')``.
      loss_top (dict): The loss config used to calculate the top loss, which
          is a part of the height loss. Defaults to
          ``dict(type='SmoothL1Loss', reduction='none')``.
      loss_btm (dict): The loss config used to calculate the bottom loss,
          which is a part of the height loss. Defaults to
          ``dict(type='SmoothL1Loss', reduction='none')``.
      loss_sin (dict): The loss config used to calculate the sin loss.
          Defaults to ``dict(type='MaskedSmoothL1Loss')``.
      loss_cos (dict): The loss config used to calculate the cos loss.
          Defaults to ``dict(type='MaskedSmoothL1Loss')``.
      loss_gcn (dict): The loss config used to calculate the GCN loss.
          Defaults to ``dict(type='CrossEntropyLoss')``.
docstr: Compute Drrg loss.
  
  Args:
      preds (tuple): The prediction
          tuple(pred_maps, gcn_pred, gt_labels), each of shape
          :math:`(N, 6, H, W)`, :math:`(N, 2)` and :math:`(m ,n)`, where
          :math:`m * n = N`.
      data_samples (list[TextDetDataSample]): The data samples.
  
  Returns:
      dict:  A loss dict with ``loss_text``, ``loss_center``,
      ``loss_height``, ``loss_sin``, ``loss_cos``, and ``loss_gcn``.
docstr_tok: ["Compute","Drrg","loss",".","Args",":","preds","(","tuple",")",":","The","prediction","tuple","(","pred_maps",",","gcn_pred",",","gt_labels",")",",","each","of","shape",":","math",":","`","(","N",",","6",",","H",",","W",")","`",",",":","math",":","`","(","N",",","2",")","`","and",":","math",":","`","(","m",",","n",")","`",",","where",":","math",":","`","m","*","n","=","N","`",".","data_samples","(","list","[","TextDetDataSample","]",")",":","The","data","samples",".","Returns",":","dict",":","A","loss","dict","with","``","loss_text","``",",","``","loss_center","``",",","``","loss_height","``",",","``","loss_sin","``",",","``","loss_cos","``",",","and","``","loss_gcn","``","."]
code: def forward(
      self,
      preds: Tuple[Tensor, Tensor, Tensor],
      data_samples: Sequence[TextDetDataSample],
  ) -> Dict:
      """Compute Drrg loss.
  
      Args:
          preds (tuple): The prediction
              tuple(pred_maps, gcn_pred, gt_labels), each of shape
              :math:`(N, 6, H, W)`, :math:`(N, 2)` and :math:`(m ,n)`, where
              :math:`m * n = N`.
          data_samples (list[TextDetDataSample]): The data samples.
  
      Returns:
          dict:  A loss dict with ``loss_text``, ``loss_center``,
          ``loss_height``, ``loss_sin``, ``loss_cos``, and ``loss_gcn``.
      """
      assert isinstance(preds, tuple)
  
      (
          gt_text_masks,
          gt_center_region_masks,
          gt_masks,
          gt_top_height_maps,
          gt_bot_height_maps,
          gt_sin_maps,
          gt_cos_maps,
          _,
      ) = self.get_targets(data_samples)
      pred_maps, gcn_pred, gt_labels = preds
      pred_text_region = pred_maps[:, 0, :, :]
      pred_center_region = pred_maps[:, 1, :, :]
      pred_sin_map = pred_maps[:, 2, :, :]
      pred_cos_map = pred_maps[:, 3, :, :]
      pred_top_height_map = pred_maps[:, 4, :, :]
      pred_bot_height_map = pred_maps[:, 5, :, :]
      feature_sz = pred_maps.size()
      device = pred_maps.device
  
      # bitmask 2 tensor
      mapping = {
          "gt_text_masks": gt_text_masks,
          "gt_center_region_masks": gt_center_region_masks,
          "gt_masks": gt_masks,
          "gt_top_height_maps": gt_top_height_maps,
          "gt_bot_height_maps": gt_bot_height_maps,
          "gt_sin_maps": gt_sin_maps,
          "gt_cos_maps": gt_cos_maps,
      }
      gt = {}
      for key, value in mapping.items():
          gt[key] = value
          if abs(self.downsample_ratio - 1.0) < 1e-2:
              gt[key] = self._batch_pad(gt[key], feature_sz[2:])
          else:
              gt[key] = [
                  imrescale(
                      mask,
                      scale=self.downsample_ratio,
                      interpolation="nearest",
                  )
                  for mask in gt[key]
              ]
              gt[key] = self._batch_pad(gt[key], feature_sz[2:])
              if key in ["gt_top_height_maps", "gt_bot_height_maps"]:
                  gt[key] *= self.downsample_ratio
          gt[key] = torch.from_numpy(gt[key]).float().to(device)
  
      scale = torch.sqrt(
          1.0 / (pred_sin_map**2 + pred_cos_map**2 + 1e-8)
      )
      pred_sin_map = pred_sin_map * scale
      pred_cos_map = pred_cos_map * scale
  
      loss_text = self.loss_text(
          pred_text_region, gt["gt_text_masks"], gt["gt_masks"]
      )
  
      text_mask = (gt["gt_text_masks"] * gt["gt_masks"]).float()
      negative_text_mask = (
          (1 - gt["gt_text_masks"]) * gt["gt_masks"]
      ).float()
      loss_center_positive = self.loss_center(
          pred_center_region, gt["gt_center_region_masks"], text_mask
      )
      loss_center_negative = self.loss_center(
          pred_center_region,
          gt["gt_center_region_masks"],
          negative_text_mask,
      )
      loss_center = loss_center_positive + 0.5 * loss_center_negative
  
      center_mask = (
          gt["gt_center_region_masks"] * gt["gt_masks"]
      ).float()
      map_sz = pred_top_height_map.size()
      ones = torch.ones(map_sz, dtype=torch.float, device=device)
      loss_top = self.loss_top(
          pred_top_height_map / (gt["gt_top_height_maps"] + 1e-2), ones
      )
      loss_btm = self.loss_btm(
          pred_bot_height_map / (gt["gt_bot_height_maps"] + 1e-2), ones
      )
      gt_height = gt["gt_top_height_maps"] + gt["gt_bot_height_maps"]
      loss_height = torch.sum(
          (torch.log(gt_height + 1) * (loss_top + loss_btm))
          * center_mask
      ) / (torch.sum(center_mask) + 1e-6)
  
      loss_sin = self.loss_sin(
          pred_sin_map, gt["gt_sin_maps"], center_mask
      )
      loss_cos = self.loss_cos(
          pred_cos_map, gt["gt_cos_maps"], center_mask
      )
  
      loss_gcn = self.loss_gcn(
          gcn_pred, gt_labels.view(-1).to(gcn_pred.device)
      )
  
      results = dict(
          loss_text=loss_text,
          loss_center=loss_center,
          loss_height=loss_height,
          loss_sin=loss_sin,
          loss_cos=loss_cos,
          loss_gcn=loss_gcn,
      )
  
      return results
  
imports: from typing import Dict, List, Sequence, Tuple
  import cv2
  import numpy
  import torch
  from mmcv.image import imrescale
  from mmdet.models.utils import multi_apply
  from numpy import ndarray
  from numpy.linalg import norm
  from torch import Tensor
  from mmocr.registry import MODELS
  from mmocr.structures import TextDetDataSample
  from mmocr.utils import check_argument
  from .textsnake_module_loss import TextSnakeModuleLoss
label_desc: Use image node_id 2 for calling the DRRGModuleLoss obj's underlying member method code with example usage: obj.forward(preds, data_samples) and returns: results