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 source sequences (B, Tmax, idim)
  :param torch.Tensor ilens: batch of lengths of source sequences (B)
  :param torch.Tensor ys_pad: batch of padded target sequences
                              (B, num_spkrs, Lmax)
  :return: ctc loass 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","source","sequences","(","B",",","Tmax",",","idim",")",":","param","torch.Tensor","ilens",":","batch","of","lengths","of","source","sequences","(","B",")",":","param","torch.Tensor","ys_pad",":","batch","of","padded","target","sequences","(","B",",","num_spkrs",",","Lmax",")",":","return",":","ctc","loass","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 source sequences (B, Tmax, idim)
      :param torch.Tensor ilens: batch of lengths of source sequences (B)
      :param torch.Tensor ys_pad: batch of padded target sequences
                                  (B, num_spkrs, Lmax)
      :return: ctc loass value
      :rtype: torch.Tensor
      :return: attention loss value
      :rtype: torch.Tensor
      :return: accuracy in attention decoder
      :rtype: float
      """
      # 1. forward encoder
      xs_pad = xs_pad[:, : max(ilens)]  # for data parallel
      src_mask = (
          make_non_pad_mask(ilens.tolist())
          .to(xs_pad.device)
          .unsqueeze(-2)
      )
      hs_pad, hs_mask = self.encoder(
          xs_pad, src_mask
      )  # list: speaker differentiate
      self.hs_pad = hs_pad
  
      # 2. ctc
      # TODO(karita) show predicted text
      # TODO(karita) calculate these stats
      cer_ctc = None
      assert self.mtlalpha > 0.0
      batch_size = xs_pad.size(0)
      ys_pad = ys_pad.transpose(0, 1)  # (num_spkrs, B, Lmax)
      hs_len = [
          hs_mask[i].view(batch_size, -1).sum(1)
          for i in range(self.num_spkrs)
      ]
      loss_ctc_perm = torch.stack(
          [
              self.ctc(
                  hs_pad[i // self.num_spkrs].view(
                      batch_size, -1, self.adim
                  ),
                  hs_len[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)))
  
      # Permute the labels according to loss
      for b in range(batch_size):  # B
          ys_pad[:, b] = ys_pad[min_perm[b], b]  # (num_spkrs, B, Lmax)
      ys_out_len = [
          float(torch.sum(ys_pad[i] != self.ignore_id))
          for i in range(self.num_spkrs)
      ]
  
      # TODO(karita) show predicted text
      # TODO(karita) calculate these stats
      if self.error_calculator is not None:
          cer_ctc = []
          for i in range(self.num_spkrs):
              ys_hat = self.ctc.argmax(
                  hs_pad[i].view(batch_size, -1, self.adim)
              ).data
              cer_ctc.append(
                  self.error_calculator(
                      ys_hat.cpu(), ys_pad[i].cpu(), is_ctc=True
                  )
              )
          cer_ctc = sum(
              map(lambda x: x[0] * x[1], zip(cer_ctc, ys_out_len))
          ) / sum(ys_out_len)
      else:
          cer_ctc = None
  
      # 3. forward decoder
      if self.mtlalpha == 1.0:
          loss_att, self.acc, cer, wer = None, None, None, None
      else:
          pred_pad, pred_mask = [None] * self.num_spkrs, [
              None
          ] * self.num_spkrs
          loss_att, acc = [None] * self.num_spkrs, [
              None
          ] * self.num_spkrs
          for i in range(self.num_spkrs):
              (
                  pred_pad[i],
                  pred_mask[i],
                  loss_att[i],
                  acc[i],
              ) = self.decoder_and_attention(
                  hs_pad[i], hs_mask[i], ys_pad[i], batch_size
              )
  
          # 4. compute attention loss
          # The following is just an approximation
          loss_att = sum(
              map(lambda x: x[0] * x[1], zip(loss_att, ys_out_len))
          ) / sum(ys_out_len)
          self.acc = sum(
              map(lambda x: x[0] * x[1], zip(acc, ys_out_len))
          ) / sum(ys_out_len)
  
          # 5. compute cer/wer
          if self.training or self.error_calculator is None:
              cer, wer = None, None
          else:
              ys_hat = pred_pad.argmax(dim=-1)
              cer, wer = self.error_calculator(
                  ys_hat.cpu(), ys_pad.cpu()
              )
  
      # copyied from e2e_asr
      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 logging
  import math
  from argparse import Namespace
  import numpy
  import torch
  from espnet.nets.asr_interface import ASRInterface
  from espnet.nets.ctc_prefix_score import CTCPrefixScore
  from espnet.nets.e2e_asr_common import end_detect
  from espnet.nets.pytorch_backend.ctc import CTC
  from espnet.nets.pytorch_backend.e2e_asr import CTC_LOSS_THRESHOLD
  from espnet.nets.pytorch_backend.e2e_asr_mix import E2E
  from espnet.nets.pytorch_backend.e2e_asr_mix import PIT
  from espnet.nets.pytorch_backend.e2e_asr_transformer import E2E
  from espnet.nets.pytorch_backend.nets_utils import make_non_pad_mask, th_accuracy
  from espnet.nets.pytorch_backend.rnn.decoders import CTC_SCORING_RATIO
  from espnet.nets.pytorch_backend.transformer.add_sos_eos import add_sos_eos
  from espnet.nets.pytorch_backend.transformer.encoder_mix import EncoderMix
  from espnet.nets.pytorch_backend.transformer.mask import subsequent_mask, target_mask
label_desc: Use image node_id 3 for calling the E2E obj's underlying member method code with example usage: obj.forward(xs_pad, ilens, ys_pad) and returns: self