class_docstr: TCNDenseNet block from iNeuBe
  
  Reference:
  Lu, Y. J., Cornell, S., Chang, X., Zhang, W., Li, C., Ni, Z., ... & Watanabe, S.
  Towards Low-Distortion Multi-Channel Speech Enhancement:
  The ESPNET-Se Submission to the L3DAS22 Challenge. ICASSP 2022 p. 9201-9205.
  
  Args:
      n_spk: number of output sources/speakers.
      in_freqs: number of complex STFT frequencies.
      mic_channels: number of microphones channels
          (only fixed-array geometry supported).
      hid_chans: number of channels in the subsampling/upsampling conv layers.
      hid_chans_dense: number of channels in the densenet layers
          (reduce this to reduce VRAM requirements).
      ksz_dense: kernel size in the densenet layers thorough iNeuBe.
      ksz_tcn: kernel size in the TCN submodule.
      tcn_repeats: number of repetitions of blocks in the TCN submodule.
      tcn_blocks: number of blocks in the TCN submodule.
      tcn_channels: number of channels in the TCN submodule.
      activation: activation function to use in the whole iNeuBe model,
          you can use any torch supported activation e.g. 'relu' or 'elu'.
code: def __init__(
      self,
      n_spk=1,
      in_freqs=257,
      mic_channels=1,
      hid_chans=32,
      hid_chans_dense=32,
      ksz_dense=(3, 3),
      ksz_tcn=3,
      tcn_repeats=4,
      tcn_blocks=7,
      tcn_channels=384,
      activation=torch.nn.ELU,
  ):
      super(TCNDenseUNet, self).__init__()
      self.n_spk = n_spk
      self.in_channels = in_freqs
      self.mic_channels = mic_channels
  
      num_freqs = in_freqs - 2
      first = torch.nn.Sequential(
          torch.nn.Conv2d(
              self.mic_channels * 2,
              hid_chans,
              (3, 3),
              (1, 1),
              (1, 0),
              padding_mode="reflect",
          ),
          DenseBlock(
              hid_chans,
              hid_chans,
              num_freqs,
              ksz=ksz_dense,
              activation=activation,
              hid_chans=hid_chans_dense,
          ),
      )
  
      freq_axis_dims = self._get_depth(num_freqs)
      self.encoder = torch.nn.ModuleList([])
      self.encoder.append(first)
  
      for layer_indx in range(len(freq_axis_dims)):
          downsample = Conv2DActNorm(
              hid_chans,
              hid_chans,
              (3, 3),
              (1, 2),
              (1, 0),
              activation=activation,
          )
          denseblocks = DenseBlock(
              hid_chans,
              hid_chans,
              freq_axis_dims[layer_indx],
              ksz=ksz_dense,
              activation=activation,
              hid_chans=hid_chans_dense,
          )
          c_layer = torch.nn.Sequential(downsample, denseblocks)
          self.encoder.append(c_layer)
  
      self.encoder.append(
          Conv2DActNorm(
              hid_chans,
              hid_chans * 2,
              (3, 3),
              (1, 2),
              (1, 0),
              activation=activation,
          )
      )
      self.encoder.append(
          Conv2DActNorm(
              hid_chans * 2,
              hid_chans * 4,
              (3, 3),
              (1, 2),
              (1, 0),
              activation=activation,
          )
      )
      self.encoder.append(
          Conv2DActNorm(
              hid_chans * 4,
              tcn_channels,
              (3, 3),
              (1, 1),
              (1, 0),
              activation=activation,
          )
      )
  
      self.tcn = []
      for r in range(tcn_repeats):
          for x in range(tcn_blocks):
              self.tcn.append(
                  TCNResBlock(
                      tcn_channels,
                      tcn_channels,
                      ksz_tcn,
                      dilation=2**x,
                      activation=activation,
                  )
              )
  
      self.tcn = torch.nn.Sequential(*self.tcn)
      self.decoder = torch.nn.ModuleList([])
      self.decoder.append(
          Conv2DActNorm(
              tcn_channels * 2,
              hid_chans * 4,
              (3, 3),
              (1, 1),
              (1, 0),
              activation=activation,
              upsample=True,
          )
      )
      self.decoder.append(
          Conv2DActNorm(
              hid_chans * 8,
              hid_chans * 2,
              (3, 3),
              (1, 2),
              (1, 0),
              activation=activation,
              upsample=True,
          )
      )
      self.decoder.append(
          Conv2DActNorm(
              hid_chans * 4,
              hid_chans,
              (3, 3),
              (1, 2),
              (1, 0),
              activation=activation,
              upsample=True,
          )
      )
  
      for dec_indx in range(len(freq_axis_dims)):
          c_num_freqs = freq_axis_dims[
              len(freq_axis_dims) - dec_indx - 1
          ]
          denseblocks = DenseBlock(
              hid_chans * 2,
              hid_chans * 2,
              c_num_freqs,
              ksz=ksz_dense,
              activation=activation,
              hid_chans=hid_chans_dense,
          )
          upsample = Conv2DActNorm(
              hid_chans * 2,
              hid_chans,
              (3, 3),
              (1, 2),
              (1, 0),
              activation=activation,
              upsample=True,
          )
          c_layer = torch.nn.Sequential(denseblocks, upsample)
          self.decoder.append(c_layer)
  
      last = torch.nn.Sequential(
          DenseBlock(
              hid_chans * 2,
              hid_chans * 2,
              self.in_channels - 2,
              ksz=ksz_dense,
              activation=activation,
              hid_chans=hid_chans_dense,
          ),
          torch.nn.ConvTranspose2d(
              hid_chans * 2, 2 * self.n_spk, (3, 3), (1, 1), (1, 0)
          ),
      )
      self.decoder.append(last)
  
imports: import torch
  from packaging.version import parse
  from torch_complex.tensor import ComplexTensor
  from espnet2.torch_utils.get_layer_from_string import get_layer
label_desc: Use image node_id 1 to create a new TCNDenseUNet object from inherited base classes: torch.nn with example: obj = TCNDenseUNet(n_spk, in_freqs, mic_channels, hid_chans, hid_chans_dense, ksz_dense, ksz_tcn, tcn_repeats, tcn_blocks, tcn_channels, activation)