class_docstr: The class for implementing EmbLossV1. This was partially adapted from
  https://github.com/whai362/pan_pp.pytorch.
  
  Args:
      feature_dim (int): The dimension of the feature. Defaults to 4.
      delta_aggregation (float): The delta for aggregation. Defaults to 0.5.
      delta_discrimination (float): The delta for discrimination.
          Defaults to 1.5.
docstr: Compute the loss for a single image.
  
  Args:
      emb (torch.Tensor): The embedding feature.
      instance (torch.Tensor): The instance feature.
      kernel (torch.Tensor): The kernel feature.
      training_mask (torch.Tensor): The effective mask.
docstr_tok: ["Compute","the","loss","for","a","single","image",".","Args",":","emb","(","torch.Tensor",")",":","The","embedding","feature",".","instance","(","torch.Tensor",")",":","The","instance","feature",".","kernel","(","torch.Tensor",")",":","The","kernel","feature",".","training_mask","(","torch.Tensor",")",":","The","effective","mask","."]
code: def _forward_single(
      self,
      emb: torch.Tensor,
      instance: torch.Tensor,
      kernel: torch.Tensor,
      training_mask: torch.Tensor,
  ) -> torch.Tensor:
      """Compute the loss for a single image.
  
      Args:
          emb (torch.Tensor): The embedding feature.
          instance (torch.Tensor): The instance feature.
          kernel (torch.Tensor): The kernel feature.
          training_mask (torch.Tensor): The effective mask.
      """
      training_mask = (training_mask > 0.5).float()
      kernel = (kernel > 0.5).float()
      instance = instance * training_mask
      instance_kernel = (instance * kernel).view(-1)
      instance = instance.view(-1)
      emb = emb.view(self.feature_dim, -1)
  
      unique_labels, unique_ids = torch.unique(
          instance_kernel, sorted=True, return_inverse=True
      )
      num_instance = unique_labels.size(0)
      if num_instance <= 1:
          return 0
  
      emb_mean = emb.new_zeros(
          (self.feature_dim, num_instance), dtype=torch.float32
      )
      for i, lb in enumerate(unique_labels):
          if lb == 0:
              continue
          ind_k = instance_kernel == lb
          emb_mean[:, i] = torch.mean(emb[:, ind_k], dim=1)
  
      l_agg = emb.new_zeros(num_instance, dtype=torch.float32)
      for i, lb in enumerate(unique_labels):
          if lb == 0:
              continue
          ind = instance == lb
          emb_ = emb[:, ind]
          dist = (emb_ - emb_mean[:, i : i + 1]).norm(p=2, dim=0)
          dist = F.relu(dist - self.delta_aggregation) ** 2
          l_agg[i] = torch.mean(torch.log(dist + 1.0))
      l_agg = torch.mean(l_agg[1:])
  
      if num_instance > 2:
          emb_interleave = emb_mean.permute(1, 0).repeat(
              num_instance, 1
          )
          emb_band = (
              emb_mean.permute(1, 0)
              .repeat(1, num_instance)
              .view(-1, self.feature_dim)
          )
  
          mask = (
              (1 - torch.eye(num_instance, dtype=torch.int8))
              .view(-1, 1)
              .repeat(1, self.feature_dim)
          )
          mask = mask.view(num_instance, num_instance, -1)
          mask[0, :, :] = 0
          mask[:, 0, :] = 0
          mask = mask.view(num_instance * num_instance, -1)
  
          dist = emb_interleave - emb_band
          dist = (
              dist[mask > 0].view(-1, self.feature_dim).norm(p=2, dim=1)
          )
          dist = F.relu(2 * self.delta_discrimination - dist) ** 2
          l_dis = torch.mean(torch.log(dist + 1.0))
      else:
          l_dis = 0
  
      l_agg = self.weights[0] * l_agg
      l_dis = self.weights[1] * l_dis
      l_reg = (
          torch.mean(torch.log(torch.norm(emb_mean, 2, 0) + 1.0))
          * 0.001
      )
      loss = l_agg + l_dis + l_reg
      return loss
  
imports: import warnings
  from typing import Dict, Sequence, Tuple, Union
  import numpy
  import torch
  import torch.nn.functional
  from mmdet.models.utils import multi_apply
  from torch import nn
  from mmocr.registry import MODELS
  from mmocr.structures import TextDetDataSample
  from .seg_based_module_loss import SegBasedModuleLoss
label_desc: Use image node_id 2 for calling the PANEmbLossV1 obj's underlying member method code with example usage: obj._forward_single(emb, instance, kernel, training_mask) and returns: loss, int