class_docstr: Dual-path RNN module with MulCat blocks.
  
  Args:
      input_size: int, dimension of the input feature.
          The input should have shape (batch, seq_len, input_size).
      hidden_size: int, dimension of the hidden state.
      output_size: int, dimension of the output size.
      num_spk: int, the number of speakers in the output.
      dropout: float, the dropout rate in the LSTM layer. (Default: 0.0)
      bidirectional: bool, whether the RNN layers are bidirectional. (Default: True)
      num_layers: int, number of stacked MulCat blocks. (Default: 4)
      input_normalize: bool, whether to apply GroupNorm on the input Tensor.
          (Default: False)
code: def __init__(
      self,
      input_size: int,
      hidden_size: int,
      output_size: int,
      num_spk: int,
      dropout: float = 0.0,
      num_layers: int = 4,
      bidirectional: bool = True,
      input_normalize: bool = False,
  ):
      super().__init__()
  
      self.rows_grnn = nn.ModuleList([])
      self.cols_grnn = nn.ModuleList([])
      self.rows_normalization = nn.ModuleList([])
      self.cols_normalization = nn.ModuleList([])
  
      # create the dual path pipeline
      for i in range(num_layers):
          self.rows_grnn.append(
              MulCatBlock(
                  input_size,
                  hidden_size,
                  dropout,
                  bidirectional=bidirectional,
              )
          )
          self.cols_grnn.append(
              MulCatBlock(
                  input_size,
                  hidden_size,
                  dropout,
                  bidirectional=bidirectional,
              )
          )
          if input_normalize:
              self.rows_normalization.append(
                  nn.GroupNorm(1, input_size, eps=1e-8)
              )
              self.cols_normalization.append(
                  nn.GroupNorm(1, input_size, eps=1e-8)
              )
          else:
              # used to disable normalization
              self.rows_normalization.append(nn.Identity())
              self.cols_normalization.append(nn.Identity())
  
      self.output = nn.Sequential(
          nn.PReLU(), nn.Conv2d(input_size, output_size * num_spk, 1)
      )
  
file_path: espnet/espnet2/enh/layers/dpmulcat.py
imports: import torch
  import torch.nn
label_desc: Use image node_id 1 to create a new DPMulCat object from inherited base classes: nn with example: obj = DPMulCat(input_size, hidden_size, output_size, num_spk, dropout, num_layers, bidirectional, input_normalize)