class_docstr: E2E module.
  
  :param List idims: List of dimensions of inputs
  :param int odim: dimension of outputs
  :param Namespace args: argument Namespace containing options
docstr: E2E forward.
  
  :param List xs_pad_list: list of batch (torch.Tensor) of padded input sequences
                          [(B, Tmax_1, idim), (B, Tmax_2, idim),..]
  :param List ilens_list:
      list of batch (torch.Tensor) of lengths of input sequences [(B), (B), ..]
  :param torch.Tensor ys_pad:
      batch of padded character id sequence tensor (B, Lmax)
  :return: loss value
  :rtype: torch.Tensor
code: def forward(self, xs_pad_list, ilens_list, ys_pad):
      """E2E forward.
  
      :param List xs_pad_list: list of batch (torch.Tensor) of padded input sequences
                              [(B, Tmax_1, idim), (B, Tmax_2, idim),..]
      :param List ilens_list:
          list of batch (torch.Tensor) of lengths of input sequences [(B), (B), ..]
      :param torch.Tensor ys_pad:
          batch of padded character id sequence tensor (B, Lmax)
      :return: loss value
      :rtype: torch.Tensor
      """
      import editdistance
  
      if self.replace_sos:
          tgt_lang_ids = ys_pad[:, 0:1]
          ys_pad = ys_pad[
              :, 1:
          ]  # remove target language ID in the beginning
      else:
          tgt_lang_ids = None
  
      hs_pad_list, hlens_list, self.loss_ctc_list = [], [], []
      for idx in range(self.num_encs):
          # 1. Encoder
          hs_pad, hlens, _ = self.enc[idx](
              xs_pad_list[idx], ilens_list[idx]
          )
  
          # 2. CTC loss
          if self.mtlalpha == 0:
              self.loss_ctc_list.append(None)
          else:
              ctc_idx = 0 if self.share_ctc else idx
              loss_ctc = self.ctc[ctc_idx](hs_pad, hlens, ys_pad)
              self.loss_ctc_list.append(loss_ctc)
          hs_pad_list.append(hs_pad)
          hlens_list.append(hlens)
  
      # 3. attention loss
      if self.mtlalpha == 1:
          self.loss_att, acc = None, None
      else:
          self.loss_att, acc, _ = self.dec(
              hs_pad_list, hlens_list, ys_pad, lang_ids=tgt_lang_ids
          )
      self.acc = acc
  
      # 4. compute cer without beam search
      if self.mtlalpha == 0 or self.char_list is None:
          cer_ctc_list = [None] * (self.num_encs + 1)
      else:
          cer_ctc_list = []
          for ind in range(self.num_encs):
              cers = []
              ctc_idx = 0 if self.share_ctc else ind
              y_hats = self.ctc[ctc_idx].argmax(hs_pad_list[ind]).data
              for i, y in enumerate(y_hats):
                  y_hat = [x[0] for x in groupby(y)]
                  y_true = ys_pad[i]
  
                  seq_hat = [
                      self.char_list[int(idx)]
                      for idx in y_hat
                      if int(idx) != -1
                  ]
                  seq_true = [
                      self.char_list[int(idx)]
                      for idx in y_true
                      if int(idx) != -1
                  ]
                  seq_hat_text = "".join(seq_hat).replace(
                      self.space, " "
                  )
                  seq_hat_text = seq_hat_text.replace(self.blank, "")
                  seq_true_text = "".join(seq_true).replace(
                      self.space, " "
                  )
  
                  hyp_chars = seq_hat_text.replace(" ", "")
                  ref_chars = seq_true_text.replace(" ", "")
                  if len(ref_chars) > 0:
                      cers.append(
                          editdistance.eval(hyp_chars, ref_chars)
                          / len(ref_chars)
                      )
  
              cer_ctc = sum(cers) / len(cers) if cers else None
              cer_ctc_list.append(cer_ctc)
          cer_ctc_weighted = np.sum(
              [
                  item * self.weights_ctc_train[i]
                  for i, item in enumerate(cer_ctc_list)
              ]
          )
          cer_ctc_list = [float(cer_ctc_weighted)] + [
              float(item) for item in cer_ctc_list
          ]
  
      # 5. compute cer/wer
      if self.training or not (self.report_cer or self.report_wer):
          cer, wer = 0.0, 0.0
          # oracle_cer, oracle_wer = 0.0, 0.0
      else:
          if self.recog_args.ctc_weight > 0.0:
              lpz_list = []
              for idx in range(self.num_encs):
                  ctc_idx = 0 if self.share_ctc else idx
                  lpz = (
                      self.ctc[ctc_idx]
                      .log_softmax(hs_pad_list[idx])
                      .data
                  )
                  lpz_list.append(lpz)
          else:
              lpz_list = None
  
          word_eds, word_ref_lens, char_eds, char_ref_lens = (
              [],
              [],
              [],
              [],
          )
          nbest_hyps = self.dec.recognize_beam_batch(
              hs_pad_list,
              hlens_list,
              lpz_list,
              self.recog_args,
              self.char_list,
              self.rnnlm,
              lang_ids=tgt_lang_ids.squeeze(1).tolist()
              if self.replace_sos
              else None,
          )
          # remove <sos> and <eos>
          y_hats = [
              nbest_hyp[0]["yseq"][1:-1] for nbest_hyp in nbest_hyps
          ]
          for i, y_hat in enumerate(y_hats):
              y_true = ys_pad[i]
  
              seq_hat = [
                  self.char_list[int(idx)]
                  for idx in y_hat
                  if int(idx) != -1
              ]
              seq_true = [
                  self.char_list[int(idx)]
                  for idx in y_true
                  if int(idx) != -1
              ]
              seq_hat_text = "".join(seq_hat).replace(
                  self.recog_args.space, " "
              )
              seq_hat_text = seq_hat_text.replace(
                  self.recog_args.blank, ""
              )
              seq_true_text = "".join(seq_true).replace(
                  self.recog_args.space, " "
              )
  
              hyp_words = seq_hat_text.split()
              ref_words = seq_true_text.split()
              word_eds.append(editdistance.eval(hyp_words, ref_words))
              word_ref_lens.append(len(ref_words))
              hyp_chars = seq_hat_text.replace(" ", "")
              ref_chars = seq_true_text.replace(" ", "")
              char_eds.append(editdistance.eval(hyp_chars, ref_chars))
              char_ref_lens.append(len(ref_chars))
  
          wer = (
              0.0
              if not self.report_wer
              else float(sum(word_eds)) / sum(word_ref_lens)
          )
          cer = (
              0.0
              if not self.report_cer
              else float(sum(char_eds)) / sum(char_ref_lens)
          )
  
      alpha = self.mtlalpha
      if alpha == 0:
          self.loss = self.loss_att
          loss_att_data = float(self.loss_att)
          loss_ctc_data_list = [None] * (self.num_encs + 1)
      elif alpha == 1:
          self.loss = torch.sum(
              torch.cat(
                  [
                      (item * self.weights_ctc_train[i]).unsqueeze(0)
                      for i, item in enumerate(self.loss_ctc_list)
                  ]
              )
          )
          loss_att_data = None
          loss_ctc_data_list = [float(self.loss)] + [
              float(item) for item in self.loss_ctc_list
          ]
      else:
          self.loss_ctc = torch.sum(
              torch.cat(
                  [
                      (item * self.weights_ctc_train[i]).unsqueeze(0)
                      for i, item in enumerate(self.loss_ctc_list)
                  ]
              )
          )
          self.loss = (
              alpha * self.loss_ctc + (1 - alpha) * self.loss_att
          )
          loss_att_data = float(self.loss_att)
          loss_ctc_data_list = [float(self.loss_ctc)] + [
              float(item) for item in self.loss_ctc_list
          ]
  
      loss_data = float(self.loss)
      if loss_data < CTC_LOSS_THRESHOLD and not math.isnan(loss_data):
          self.reporter.report(
              loss_ctc_data_list,
              loss_att_data,
              acc,
              cer_ctc_list,
              cer,
              wer,
              loss_data,
          )
      else:
          logging.warning("loss (=%f) is not correct", loss_data)
      return self.loss
  
imports: import argparse
  import logging
  import math
  import os
  from itertools import groupby
  import chainer
  import numpy
  import torch
  from chainer import reporter
  from espnet.nets.asr_interface import ASRInterface
  from espnet.nets.e2e_asr_common import label_smoothing_dist
  from espnet.nets.pytorch_backend.ctc import ctc_for
  from espnet.nets.pytorch_backend.nets_utils import get_subsample, pad_list, to_device, to_torch_tensor
  from espnet.nets.pytorch_backend.rnn.attentions import att_for
  from espnet.nets.pytorch_backend.rnn.decoders import decoder_for
  from espnet.nets.pytorch_backend.rnn.encoders import Encoder, encoder_for
  from espnet.nets.scorers.ctc import CTCPrefixScorer
  from espnet.utils.cli_utils import strtobool
label_desc: Use image node_id 9 for calling the E2E obj's underlying member method code with example usage: obj.forward(xs_pad_list, ilens_list, ys_pad) and returns: self