class_docstr: Joint model Enhancement and Speech to Text.
class_docstr_tok: ["Joint","model","Enhancement","and","Speech","to","Text","."]
docstr: Compute  PIT loss.
  
  Args:
      losses (torch.Tensor): (batch, nref, nhyp)
  Returns:
      perm: list: (batch, n_spk)
      loss: torch.Tensor: (batch)
docstr_tok: ["Compute","PIT","loss",".","Args",":","losses","(","torch.Tensor",")",":","(","batch",",","nref",",","nhyp",")","Returns",":","perm",":","list",":","(","batch",",","n_spk",")","loss",":","torch.Tensor",":","(","batch",")"]
code: def permutation_invariant_training(self, losses: torch.Tensor):
      """Compute  PIT loss.
  
      Args:
          losses (torch.Tensor): (batch, nref, nhyp)
      Returns:
          perm: list: (batch, n_spk)
          loss: torch.Tensor: (batch)
      """
      hyp_perm, min_perm_loss = [], []
      losses_cpu = losses.data.cpu()
      for b, b_loss in enumerate(losses_cpu):
          # hungarian algorithm
          try:
              row_ind, col_ind = linear_sum_assignment(b_loss)
          except ValueError as err:
              if str(err) == "cost matrix is infeasible":
                  # random assignment since the cost is always inf
                  col_ind = np.array([0, 1])
                  min_perm_loss.append(
                      torch.mean(losses[b, col_ind, col_ind])
                  )
                  hyp_perm.append(col_ind)
                  continue
              else:
                  raise
  
          min_perm_loss.append(torch.mean(losses[b, row_ind, col_ind]))
          hyp_perm.append(
              torch.as_tensor(
                  col_ind, dtype=torch.long, device=losses.device
              )
          )
  
      return hyp_perm, torch.stack(min_perm_loss)
  
imports: import logging
  import random
  from contextlib import contextmanager
  from typing import Dict, List, Tuple, Union
  import numpy
  import torch
  import torch.nn.functional
  from packaging.version import parse
  from scipy.optimize import linear_sum_assignment
  from typeguard import check_argument_types
  from espnet2.asr.espnet_model import ESPnetASRModel
  from espnet2.diar.espnet_model import ESPnetDiarizationModel
  from espnet2.enh.espnet_model import ESPnetEnhancementModel
  from espnet2.st.espnet_model import ESPnetSTModel
  from espnet2.torch_utils.device_funcs import force_gatherable
  from espnet2.train.abs_espnet_model import AbsESPnetModel
label_desc: Use image node_id 9 for calling the ESPnetEnhS2TModel obj's underlying member method code with example usage: obj.permutation_invariant_training(losses) and returns: hyp_perm,  torch