class_docstr: DNN mask based Beamformer
  
  Citation:
      Multichannel End-to-end Speech Recognition; T. Ochiai et al., 2017;
      https://arxiv.org/abs/1703.04783
class_docstr_tok: ["DNN","mask","based","Beamformer","Citation",":","Multichannel","End-to-end","Speech","Recognition",";","T.","Ochiai","et","al.",",","2017",";","https",":","\/\/arxiv.org\/abs\/1703.04783"]
docstr: The forward function
  
  Notation:
      B: Batch
      C: Channel
      T: Time or Sequence length
      F: Freq
  
  Args:
      data (ComplexTensor): (B, T, C, F)
      ilens (torch.Tensor): (B,)
  Returns:
      enhanced (ComplexTensor): (B, T, F)
      ilens (torch.Tensor): (B,)
docstr_tok: ["The","forward","function","Notation",":","B",":","Batch","C",":","Channel","T",":","Time","or","Sequence","length","F",":","Freq","Args",":","data","(","ComplexTensor",")",":","(","B",",","T",",","C",",","F",")","ilens","(","torch.Tensor",")",":","(","B",",",")","Returns",":","enhanced","(","ComplexTensor",")",":","(","B",",","T",",","F",")","ilens","(","torch.Tensor",")",":","(","B",",",")"]
code: def forward(
      self, data: ComplexTensor, ilens: torch.LongTensor
  ) -> Tuple[ComplexTensor, torch.LongTensor, ComplexTensor]:
      """The forward function
  
      Notation:
          B: Batch
          C: Channel
          T: Time or Sequence length
          F: Freq
  
      Args:
          data (ComplexTensor): (B, T, C, F)
          ilens (torch.Tensor): (B,)
      Returns:
          enhanced (ComplexTensor): (B, T, F)
          ilens (torch.Tensor): (B,)
  
      """
  
      def apply_beamforming(data, ilens, psd_speech, psd_noise):
          # u: (B, C)
          if self.ref_channel < 0:
              u, _ = self.ref(psd_speech, ilens)
          else:
              # (optional) Create onehot vector for fixed reference microphone
              u = torch.zeros(
                  *(data.size()[:-3] + (data.size(-2),)),
                  device=data.device,
              )
              u[..., self.ref_channel].fill_(1)
  
          ws = get_mvdr_vector(psd_speech, psd_noise, u)
          enhanced = apply_beamforming_vector(ws, data)
  
          return enhanced, ws
  
      # data (B, T, C, F) -> (B, F, C, T)
      data = data.permute(0, 3, 2, 1)
  
      # mask: (B, F, C, T)
      masks, _ = self.mask(data, ilens)
      assert self.nmask == len(masks)
  
      if self.nmask == 2:  # (mask_speech, mask_noise)
          mask_speech, mask_noise = masks
  
          psd_speech = get_power_spectral_density_matrix(
              data, mask_speech
          )
          psd_noise = get_power_spectral_density_matrix(
              data, mask_noise
          )
  
          enhanced, ws = apply_beamforming(
              data, ilens, psd_speech, psd_noise
          )
  
          # (..., F, T) -> (..., T, F)
          enhanced = enhanced.transpose(-1, -2)
          mask_speech = mask_speech.transpose(-1, -3)
      else:  # multi-speaker case: (mask_speech1, ..., mask_noise)
          mask_speech = list(masks[:-1])
          mask_noise = masks[-1]
  
          psd_speeches = [
              get_power_spectral_density_matrix(data, mask)
              for mask in mask_speech
          ]
          psd_noise = get_power_spectral_density_matrix(
              data, mask_noise
          )
  
          enhanced = []
          ws = []
          for i in range(self.nmask - 1):
              psd_speech = psd_speeches.pop(i)
              # treat all other speakers' psd_speech as noises
              enh, w = apply_beamforming(
                  data, ilens, psd_speech, sum(psd_speeches) + psd_noise
              )
              psd_speeches.insert(i, psd_speech)
  
              # (..., F, T) -> (..., T, F)
              enh = enh.transpose(-1, -2)
              mask_speech[i] = mask_speech[i].transpose(-1, -3)
  
              enhanced.append(enh)
              ws.append(w)
  
      return enhanced, ilens, mask_speech
  
file_path: espnet/espnet/nets/pytorch_backend/frontends/dnn_beamformer.py
imports: from typing import Tuple
  import torch
  from torch.nn import functional
  from torch_complex.tensor import ComplexTensor
  from espnet.nets.pytorch_backend.frontends.beamformer import apply_beamforming_vector, get_mvdr_vector, get_power_spectral_density_matrix
  from espnet.nets.pytorch_backend.frontends.mask_estimator import MaskEstimator
label_desc: Use image node_id 2 for calling the DNN_Beamformer obj's underlying member method code with example usage: obj.forward(data, ilens) and returns: enhanced,  ilens,  mask_speech, enhanced,  ws