class_docstr: Deep duaL-path RNN with TAC applied to each layer/block.
  
  args:
      rnn_type: string, select from 'RNN', 'LSTM' and 'GRU'.
      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.
      dropout: float, dropout ratio. Default is 0.
      num_layers: int, number of stacked RNN layers. Default is 1.
      bidirectional: bool, whether the RNN layers are bidirectional.
                  Default is False.
class_docstr_tok: ["Deep","duaL-path","RNN","with","TAC","applied","to","each","layer\/block",".","args",":","rnn_type",":","string",",","select","from","'RNN","'",",","'LSTM","'","and","'GRU","'",".","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",".","dropout",":","float",",","dropout","ratio",".","Default","is","0.","num_layers",":","int",",","number","of","stacked","RNN","layers",".","Default","is","1.","bidirectional",":","bool",",","whether","the","RNN","layers","are","bidirectional",".","Default","is","False","."]
code: def forward(self, input, num_mic):
      # input shape: batch, ch, N, dim1, dim2
      # num_mic shape: batch,
      # apply RNN on dim1 first, then dim2, then ch
  
      batch_size, ch, N, dim1, dim2 = input.shape
      output = input
      for i in range(len(self.row_rnn)):
          # intra-segment RNN
          output = output.view(batch_size * ch, N, dim1, dim2)
          row_input = (
              output.permute(0, 3, 2, 1)
              .contiguous()
              .view(batch_size * ch * dim2, dim1, -1)
          )  # B*ch*dim2, dim1, N
          row_output, _ = self.row_rnn[i](
              row_input
          )  # B*ch*dim2, dim1, N
          row_output = (
              row_output.view(batch_size * ch, dim2, dim1, -1)
              .permute(0, 3, 2, 1)
              .contiguous()
          )  # B*ch, N, dim1, dim2
          row_output = self.row_norm[i](row_output)
          output = output + row_output  # B*ch, N, dim1, dim2
  
          # inter-segment RNN
          col_input = (
              output.permute(0, 2, 3, 1)
              .contiguous()
              .view(batch_size * ch * dim1, dim2, -1)
          )  # B*ch*dim1, dim2, N
          col_output, _ = self.col_rnn[i](col_input)  # B*dim1, dim2, N
          col_output = (
              col_output.view(batch_size * ch, dim1, dim2, -1)
              .permute(0, 3, 1, 2)
              .contiguous()
          )  # B*ch, N, dim1, dim2
          col_output = self.col_norm[i](col_output)
          output = output + col_output  # B*ch, N, dim1, dim2
  
          # TAC for cross-channel communication
          ch_input = output.view(input.shape)  # B, ch, N, dim1, dim2
          ch_input = (
              ch_input.permute(0, 3, 4, 1, 2).contiguous().view(-1, N)
          )  # B*dim1*dim2*ch, N
          ch_output = self.ch_transform[i](ch_input).view(
              batch_size, dim1 * dim2, ch, -1
          )  # B, dim1*dim2, ch, H
          # mean pooling across channels
          if num_mic.max() == 0:
              # fixed geometry array
              ch_mean = ch_output.mean(2).view(
                  batch_size * dim1 * dim2, -1
              )  # B*dim1*dim2, H
          else:
              # only consider valid channels
              ch_mean = [
                  ch_output[b, :, : num_mic[b]].mean(1).unsqueeze(0)
                  for b in range(batch_size)
              ]  # 1, dim1*dim2, H
              ch_mean = torch.cat(ch_mean, 0).view(
                  batch_size * dim1 * dim2, -1
              )  # B*dim1*dim2, H
          ch_output = ch_output.view(
              batch_size * dim1 * dim2, ch, -1
          )  # B*dim1*dim2, ch, H
          ch_mean = (
              self.ch_average[i](ch_mean)
              .unsqueeze(1)
              .expand_as(ch_output)
              .contiguous()
          )  # B*dim1*dim2, ch, H
          ch_output = torch.cat(
              [ch_output, ch_mean], 2
          )  # B*dim1*dim2, ch, 2H
          ch_output = self.ch_concat[i](
              ch_output.view(-1, ch_output.shape[-1])
          )  # B*dim1*dim2*ch, N
          ch_output = (
              ch_output.view(batch_size, dim1, dim2, ch, -1)
              .permute(0, 3, 4, 1, 2)
              .contiguous()
          )  # B, ch, N, dim1, dim2
          ch_output = self.ch_norm[i](
              ch_output.view(batch_size * ch, N, dim1, dim2)
          )  # B*ch, N, dim1, dim2
          output = output + ch_output
  
      output = self.output(output)  # B*ch, N, dim1, dim2
  
      return output
  
file_path: espnet/espnet2/enh/layers/dprnn.py
imports: import torch
  import torch.nn
  from torch.autograd import Variable
label_desc: Use image node_id 2 for calling the DPRNN_TAC obj's underlying member method code with example usage: obj.forward(input, num_mic) and returns: output