class_docstr: Resource Efficient Source Separator
  This is the class that implements RE-SepFormer
  
  Arguments:
  ----------
  input_dim: int,
      Input feature dimension
  causal: bool,
      Whether the system is causal.
  num_spk: int,
      Number of target speakers.
  nonlinear: class
      the nonlinear function for mask estimation,
      select from 'relu', 'tanh', 'sigmoid'
  layer: int,
      number of blocks. Default is 2 for RE-SepFormer.
  unit: int,
      Dimensionality of the hidden state.
  segment_size: int,
      Chunk size for splitting long features
  dropout: float,
      dropout ratio. Default is 0.
  mem_type: 'hc', 'h', 'c', 'id', 'av'  or None.
      This controls whether a memory representation will be used to ensure continuity between segments.
      In 'av' mode, the summary state is is calculated by simply averaging over the time dimension of each segment
      In 'id' mode, both the hidden and cell states
      will be identically returned.
      When mem_type is None, the memory model will be removed.
  seg_model: class,
      The model that processes the within segment elements
  mem_model: class,
      The memory model that ensures continuity between the segments
  
  Example
  ---------
  >>> x = torch.randn(10, 64, 100)
  >>> seg_mdl = SBTransformerBlock_wnormandskip(1, 64, 8)
  >>> mem_mdl = SBTransformerBlock_wnormandskip(1, 64, 8)
  >>> resepformer = ResourceEfficientSeparator(64, num_spk=3, mem_type='av', seg_model=seg_mdl, mem_model=mem_mdl)
  >>> out = resepformer.forward(x)
  >>> out.shape
  torch.Size([3, 10, 64, 100])
code: def __init__(
      self,
      input_dim: int,
      causal: bool = True,
      num_spk: int = 2,
      nonlinear: str = "relu",
      layer: int = 3,
      unit: int = 512,
      segment_size: int = 20,
      dropout: float = 0.0,
      mem_type: str = "hc",
      seg_model=None,
      mem_model=None,
  ):
      super().__init__()
  
      self.num_spk = num_spk
  
      self.segment_size = segment_size
  
      if mem_type not in ("hc", "h", "c", "id", "av", None):
          raise ValueError(
              "Not supporting mem_type={}".format(mem_type)
          )
  
      self.model = ResourceEfficientSeparationPipeline(
          input_size=input_dim,
          hidden_size=unit,
          output_size=input_dim * num_spk,
          dropout=dropout,
          num_blocks=layer,
          bidirectional=(not causal),
          norm_type="cln" if causal else "gln",
          segment_size=segment_size,
          mem_type=mem_type,
          seg_model=seg_model,
          mem_model=mem_model,
      )
  
      if nonlinear not in ("sigmoid", "relu", "tanh"):
          raise ValueError(
              "Not supporting nonlinear={}".format(nonlinear)
          )
  
      self.nonlinear = {
          "sigmoid": torch.nn.Sigmoid(),
          "relu": torch.nn.ReLU(),
          "tanh": torch.nn.Tanh(),
      }[nonlinear]
  
imports: import torch
  import torch.nn
  from speechbrain.lobes.models.dual_path import select_norm
  from speechbrain.lobes.models.transformer.Transformer import TransformerEncoder, PositionalEncoding, get_lookahead_mask
  import speechbrain.nnet.RNN
  import copy
label_desc: Use image node_id 1 to create a new ResourceEfficientSeparator object from inherited base classes: nn with example: obj = ResourceEfficientSeparator(input_dim, causal, num_spk, nonlinear, layer, unit, segment_size, dropout, mem_type, seg_model, mem_model)