class_docstr: CTC module
  
  :param int odim: dimension of outputs
  :param int eprojs: number of encoder projection units
  :param float dropout_rate: dropout rate (0.0 ~ 1.0)
  :param str ctc_type: builtin
  :param bool reduce: reduce the CTC loss into a scalar
code: def loss_fn(self, th_pred, th_target, th_ilen, th_olen):
      if self.ctc_type in ["builtin", "cudnnctc"]:
          th_pred = th_pred.log_softmax(2)
          # Use the deterministic CuDNN implementation of CTC loss to avoid
          #  [issue#17798](https://github.com/pytorch/pytorch/issues/17798)
          with torch.backends.cudnn.flags(deterministic=True):
              loss = self.ctc_loss(th_pred, th_target, th_ilen, th_olen)
          # Batch-size average
          loss = loss / th_pred.size(1)
          return loss
      elif self.ctc_type == "gtnctc":
          targets = [t.tolist() for t in th_target]
          log_probs = torch.nn.functional.log_softmax(th_pred, dim=2)
          return self.ctc_loss(log_probs, targets, th_ilen, 0, "none")
      else:
          raise NotImplementedError
  
file_path: espnet/espnet/nets/pytorch_backend/ctc.py
imports: import logging
  import numpy
  import torch
  import torch.nn.functional
  from packaging.version import parse
  from espnet.nets.pytorch_backend.nets_utils import to_device
label_desc: Use image node_id 2 for calling the CTC obj's underlying member method code with example usage: obj.loss_fn(th_pred, th_target, th_ilen, th_olen) and returns: loss, self