class_docstr: TCN (Temporal Convolution Network) Separation Module
  
  Generates masks for separation.
  
  Args:
      input_dim (int): Input feature dimension, <N>.
      num_sources (int): The number of sources to separate.
      kernel_size (int): The convolution kernel size of conv blocks, <P>.
      num_featrs (int): Input/output feature dimenstion of conv blocks, <B, Sc>.
      num_hidden (int): Intermediate feature dimention of conv blocks, <H>
      num_layers (int): The number of conv blocks in one stack, <X>.
      num_stacks (int): The number of conv block stacks, <R>.
      msk_activate (str): The activation function of the mask output.
  
  Note:
      This implementation corresponds to the "non-causal" setting in the paper.
code: def __init__(
      self,
      input_dim: int,
      num_sources: int,
      kernel_size: int,
      num_feats: int,
      num_hidden: int,
      num_layers: int,
      num_stacks: int,
      msk_activate: str,
  ):
      super().__init__()
  
      self.input_dim = input_dim
      self.num_sources = num_sources
  
      self.input_norm = torch.nn.GroupNorm(
          num_groups=1, num_channels=input_dim, eps=1e-8
      )
      self.input_conv = torch.nn.Conv1d(
          in_channels=input_dim, out_channels=num_feats, kernel_size=1
      )
  
      self.receptive_field = 0
      self.conv_layers = torch.nn.ModuleList([])
      for s in range(num_stacks):
          for l in range(num_layers):
              multi = 2**l
              self.conv_layers.append(
                  ConvBlock(
                      io_channels=num_feats,
                      hidden_channels=num_hidden,
                      kernel_size=kernel_size,
                      dilation=multi,
                      padding=multi,
                      # The last ConvBlock does not need residual
                      no_residual=(
                          l == (num_layers - 1)
                          and s == (num_stacks - 1)
                      ),
                  )
              )
              self.receptive_field += (
                  kernel_size
                  if s == 0 and l == 0
                  else (kernel_size - 1) * multi
              )
      self.output_prelu = torch.nn.PReLU()
      self.output_conv = torch.nn.Conv1d(
          in_channels=num_feats,
          out_channels=input_dim * num_sources,
          kernel_size=1,
      )
      if msk_activate == "sigmoid":
          self.mask_activate = torch.nn.Sigmoid()
      elif msk_activate == "relu":
          self.mask_activate = torch.nn.ReLU()
      else:
          raise ValueError(f"Unsupported activation {msk_activate}")
  
file_path: audio/src/torchaudio/models/conv_tasnet.py
imports: from typing import Optional, Tuple
  import torch
label_desc: Use image node_id 1 to create a new MaskGenerator object from inherited base classes: torch.nn with example: obj = MaskGenerator(input_dim, num_sources, kernel_size, num_feats, num_hidden, num_layers, num_stacks, msk_activate)