docstr: Forward.
  
  Args:
      input (torch.Tensor or ComplexTensor): Encoded feature [B, T, N]
      ilens (torch.Tensor): input lengths [Batch]
  
  Returns:
      feats (torch.Tensor): [B, T, bottleneck_dim]
      ilens (torch.Tensor): (B,)
docstr_tok: ["Forward",".","Args",":","input","(","torch.Tensor","or","ComplexTensor",")",":","Encoded","feature","[","B",",","T",",","N","]","ilens","(","torch.Tensor",")",":","input","lengths","[","Batch","]","Returns",":","feats","(","torch.Tensor",")",":","[","B",",","T",",","bottleneck_dim","]","ilens","(","torch.Tensor",")",":","(","B",",",")"]
code: def forward(
      self,
      input: Union[torch.Tensor, ComplexTensor],
      ilens: torch.Tensor,
  ) -> Tuple[torch.Tensor, torch.Tensor]:
      """Forward.
  
      Args:
          input (torch.Tensor or ComplexTensor): Encoded feature [B, T, N]
          ilens (torch.Tensor): input lengths [Batch]
  
      Returns:
          feats (torch.Tensor): [B, T, bottleneck_dim]
          ilens (torch.Tensor): (B,)
      """
      # if complex spectrum
      if is_complex(input):
          feature = abs(input)
      else:
          feature = input
      feature = feature.transpose(1, 2)  # B, N, L
  
      feats = self.tcn(feature)  # [B, bottleneck_dim, L]
      feats = feats.transpose(1, 2)  # B, L, bottleneck_dim
  
      return feats, ilens
  
file_path: espnet/espnet2/diar/separator/tcn_separator_nomask.py
imports: from distutils.version import LooseVersion
  from typing import Tuple, Union
  import torch
  from torch_complex.tensor import ComplexTensor
  from espnet2.diar.layers.tcn_nomask import TemporalConvNet
  from espnet2.enh.layers.complex_utils import is_complex
  from espnet2.enh.separator.abs_separator import AbsSeparator
label_desc: Use image node_id 2 for calling the TCNSeparatorNomask obj's underlying member method code with example usage: obj.forward(input, ilens) and returns: feats,  ilens