class_docstr: E2E module.
  
  :param int idim: dimension of inputs
  :param int odim: dimension of outputs
  :param Namespace args: argument Namespace containing options
class_docstr_tok: ["E2E","module",".",":","param","int","idim",":","dimension","of","inputs",":","param","int","odim",":","dimension","of","outputs",":","param","Namespace","args",":","argument","Namespace","containing","options"]
docstr: E2E forward.
  
  :param torch.Tensor xs_pad: batch of padded input sequences (B, Tmax, idim)
  :param torch.Tensor ilens: batch of lengths of input sequences (B)
  :param torch.Tensor ys_pad:
      batch of padded character id sequence tensor (B, num_spkrs, Lmax)
  :return: ctc loss value
  :rtype: torch.Tensor
  :return: attention loss value
  :rtype: torch.Tensor
  :return: accuracy in attention decoder
  :rtype: float
docstr_tok: ["E2E","forward",".",":","param","torch.Tensor","xs_pad",":","batch","of","padded","input","sequences","(","B",",","Tmax",",","idim",")",":","param","torch.Tensor","ilens",":","batch","of","lengths","of","input","sequences","(","B",")",":","param","torch.Tensor","ys_pad",":","batch","of","padded","character","id","sequence","tensor","(","B",",","num_spkrs",",","Lmax",")",":","return",":","ctc","loss","value",":","rtype",":","torch.Tensor",":","return",":","attention","loss","value",":","rtype",":","torch.Tensor",":","return",":","accuracy","in","attention","decoder",":","rtype",":","float"]
code: def forward(self, xs_pad, ilens, ys_pad):
      """E2E forward.
  
      :param torch.Tensor xs_pad: batch of padded input sequences (B, Tmax, idim)
      :param torch.Tensor ilens: batch of lengths of input sequences (B)
      :param torch.Tensor ys_pad:
          batch of padded character id sequence tensor (B, num_spkrs, Lmax)
      :return: ctc loss value
      :rtype: torch.Tensor
      :return: attention loss value
      :rtype: torch.Tensor
      :return: accuracy in attention decoder
      :rtype: float
      """
      import editdistance
  
      # 0. Frontend
      if self.frontend is not None:
          hs_pad, hlens, mask = self.frontend(
              to_torch_tensor(xs_pad), ilens
          )
          if isinstance(hs_pad, list):
              hlens_n = [None] * self.num_spkrs
              for i in range(self.num_spkrs):
                  hs_pad[i], hlens_n[i] = self.feature_transform(
                      hs_pad[i], hlens
                  )
              hlens = hlens_n
          else:
              hs_pad, hlens = self.feature_transform(hs_pad, hlens)
      else:
          hs_pad, hlens = xs_pad, ilens
  
      # 1. Encoder
      if not isinstance(
          hs_pad, list
      ):  # single-channel input xs_pad (single- or multi-speaker)
          hs_pad, hlens, _ = self.enc(hs_pad, hlens)
      else:  # multi-channel multi-speaker input xs_pad
          for i in range(self.num_spkrs):
              hs_pad[i], hlens[i], _ = self.enc(hs_pad[i], hlens[i])
  
      # 2. CTC loss
      if self.mtlalpha == 0:
          loss_ctc, min_perm = None, None
      else:
          if not isinstance(
              hs_pad, list
          ):  # single-speaker input xs_pad
              loss_ctc = torch.mean(self.ctc(hs_pad, hlens, ys_pad))
          else:  # multi-speaker input xs_pad
              ys_pad = ys_pad.transpose(0, 1)  # (num_spkrs, B, Lmax)
              loss_ctc_perm = torch.stack(
                  [
                      self.ctc(
                          hs_pad[i // self.num_spkrs],
                          hlens[i // self.num_spkrs],
                          ys_pad[i % self.num_spkrs],
                      )
                      for i in range(self.num_spkrs**2)
                  ],
                  dim=1,
              )  # (B, num_spkrs^2)
              loss_ctc, min_perm = self.pit.pit_process(loss_ctc_perm)
              logging.info("ctc loss:" + str(float(loss_ctc)))
  
      # 3. attention loss
      if self.mtlalpha == 1:
          loss_att = None
          acc = None
      else:
          if not isinstance(
              hs_pad, list
          ):  # single-speaker input xs_pad
              loss_att, acc, _ = self.dec(hs_pad, hlens, ys_pad)
          else:
              for i in range(ys_pad.size(1)):  # B
                  ys_pad[:, i] = ys_pad[min_perm[i], i]
              rslt = [
                  self.dec(hs_pad[i], hlens[i], ys_pad[i], strm_idx=i)
                  for i in range(self.num_spkrs)
              ]
              loss_att = sum([r[0] for r in rslt]) / float(len(rslt))
              acc = sum([r[1] for r in rslt]) / float(len(rslt))
      self.acc = acc
  
      # 4. compute cer without beam search
      if self.mtlalpha == 0 or self.char_list is None:
          cer_ctc = None
      else:
          cers = []
          for ns in range(self.num_spkrs):
              y_hats = self.ctc.argmax(hs_pad[ns]).data
              for i, y in enumerate(y_hats):
                  y_hat = [x[0] for x in groupby(y)]
                  y_true = ys_pad[ns][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
  
      # 5. compute cer/wer
      if (
          self.training
          or not (self.report_cer or self.report_wer)
          or not isinstance(hs_pad, list)
      ):
          cer, wer = 0.0, 0.0
      else:
          if self.recog_args.ctc_weight > 0.0:
              lpz = [
                  self.ctc.log_softmax(hs_pad[i]).data
                  for i in range(self.num_spkrs)
              ]
          else:
              lpz = None
  
          word_eds, char_eds, word_ref_lens, char_ref_lens = (
              [],
              [],
              [],
              [],
          )
          nbest_hyps = [
              self.dec.recognize_beam_batch(
                  hs_pad[i],
                  torch.tensor(hlens[i]),
                  lpz[i],
                  self.recog_args,
                  self.char_list,
                  self.rnnlm,
                  strm_idx=i,
              )
              for i in range(self.num_spkrs)
          ]
          # remove <sos> and <eos>
          y_hats = [
              [
                  nbest_hyp[0]["yseq"][1:-1]
                  for nbest_hyp in nbest_hyps[i]
              ]
              for i in range(self.num_spkrs)
          ]
          for i in range(len(y_hats[0])):
              hyp_words = []
              hyp_chars = []
              ref_words = []
              ref_chars = []
              for ns in range(self.num_spkrs):
                  y_hat = y_hats[ns][i]
                  y_true = ys_pad[ns][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.append(seq_hat_text.split())
                  ref_words.append(seq_true_text.split())
                  hyp_chars.append(seq_hat_text.replace(" ", ""))
                  ref_chars.append(seq_true_text.replace(" ", ""))
  
              tmp_word_ed = [
                  editdistance.eval(
                      hyp_words[ns // self.num_spkrs],
                      ref_words[ns % self.num_spkrs],
                  )
                  for ns in range(self.num_spkrs**2)
              ]  # h1r1,h1r2,h2r1,h2r2
              tmp_char_ed = [
                  editdistance.eval(
                      hyp_chars[ns // self.num_spkrs],
                      ref_chars[ns % self.num_spkrs],
                  )
                  for ns in range(self.num_spkrs**2)
              ]  # h1r1,h1r2,h2r1,h2r2
  
              word_eds.append(
                  self.pit.min_pit_sample(torch.tensor(tmp_word_ed))[0]
              )
              word_ref_lens.append(len(sum(ref_words, [])))
              char_eds.append(
                  self.pit.min_pit_sample(torch.tensor(tmp_char_ed))[0]
              )
              char_ref_lens.append(len("".join(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 = loss_att
          loss_att_data = float(loss_att)
          loss_ctc_data = None
      elif alpha == 1:
          self.loss = loss_ctc
          loss_att_data = None
          loss_ctc_data = float(loss_ctc)
      else:
          self.loss = alpha * loss_ctc + (1 - alpha) * loss_att
          loss_att_data = float(loss_att)
          loss_ctc_data = float(loss_ctc)
  
      loss_data = float(self.loss)
      if loss_data < CTC_LOSS_THRESHOLD and not math.isnan(loss_data):
          self.reporter.report(
              loss_ctc_data,
              loss_att_data,
              self.acc,
              cer_ctc,
              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
  import sys
  from itertools import groupby
  import numpy
  import torch
  from espnet.nets.asr_interface import ASRInterface
  from espnet.nets.e2e_asr_common import get_vgg2l_odim, label_smoothing_dist
  from espnet.nets.pytorch_backend.ctc import ctc_for
  from espnet.nets.pytorch_backend.e2e_asr import E2E
  from espnet.nets.pytorch_backend.e2e_asr import Reporter
  from espnet.nets.pytorch_backend.frontends.feature_transform import feature_transform_for
  from espnet.nets.pytorch_backend.frontends.frontend import frontend_for
  from espnet.nets.pytorch_backend.initialization import lecun_normal_init_parameters, set_forget_bias_to_one
  from espnet.nets.pytorch_backend.nets_utils import get_subsample, make_pad_mask, 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 RNNP, VGG2L
  from espnet.nets.pytorch_backend.rnn.encoders import encoder_for
label_desc: Use image node_id 6 for calling the E2E obj's underlying member method code with example usage: obj.forward(xs_pad, ilens, ys_pad) and returns: self