code: def compute_loss(
      self, embeddings, labels, indices_tuple, ref_emb, ref_labels
  ):
      c_f.indices_tuple_not_supported(indices_tuple)
      c_f.labels_required(labels)
      c_f.ref_not_supported(embeddings, labels, ref_emb, ref_labels)
      dtype, device = embeddings.dtype, embeddings.device
  
      N = labels.size(0)
      a1_idx, p_idx, a2_idx, n_idx = lmu.get_all_pairs_indices(labels)
      I_pos = torch.zeros(N, N, dtype=dtype, device=device)
      I_neg = torch.zeros(N, N, dtype=dtype, device=device)
      I_pos[a1_idx, p_idx] = 1
      I_pos[a1_idx, a1_idx] = 1
      I_neg[a2_idx, n_idx] = 1
      N_pos = torch.sum(I_pos, dim=1)
      safe_N = N_pos > 0
      if torch.sum(safe_N) == 0:
          return self.zero_losses()
      sim_all = self.distance(embeddings)
  
      mask = I_neg.unsqueeze(dim=0).repeat(N, 1, 1)
  
      sim_all_repeat = sim_all.unsqueeze(dim=1).repeat(1, N, 1)
      # compute the difference matrix
      sim_diff = sim_all_repeat - sim_all_repeat.permute(0, 2, 1)
      # pass through the sigmoid and ignores the relevance score of the query to itself
      sim_sg = self.sigmoid(sim_diff, temp=self.anneal) * mask
      # compute the number of negatives before
      sim_all_rk = torch.sum(sim_sg, dim=-1)
  
      if self.variant == "Ds":
          sim_all_rk = torch.log(1 + sim_all_rk)
      elif self.variant == "Dq":
          sim_all_rk = 1 / (1 + sim_all_rk) ** (self.alpha)
  
      elif self.variant == "Iu":
          sim_all_rk = (1 + sim_all_rk) * torch.log(1 + sim_all_rk)
  
      elif self.variant == "Ib":
          b = self.b
          sim_all_rk = (
              1
              / b**2
              * (b * sim_all_rk - torch.log(1 + b * sim_all_rk))
          )
      elif self.variant == "O":
          pass
      else:
          raise Exception(f"variant <{self.variant}> not available!")
  
      loss = torch.sum(sim_all_rk * I_pos, dim=-1)[safe_N] / N_pos[
          safe_N
      ].reshape(-1)
      loss = torch.sum(loss) / torch.sum(safe_N)
      if self.variant == "Dq":
          loss = 1 - loss
  
      return {
          "loss": {
              "losses": loss,
              "indices": torch.where(safe_N)[0],
              "reduction_type": "already_reduced",
          }
      }
  
file_path: pytorch-metric-learning/src/pytorch_metric_learning/losses/pnp_loss.py
imports: import torch
  from ..distances import CosineSimilarity
  from ..utils import common_functions
  from ..utils import loss_and_miner_utils
  from .base_metric_loss_function import BaseMetricLossFunction
label_desc: Use image node_id 2 for calling the PNPLoss obj's underlying member method code with example usage: obj.compute_loss(embeddings, labels, indices_tuple, ref_emb, ref_labels) and returns: dict, self