class_docstr: Unconstrained Speech Enhancement and Separation (USES) Network.
  
  Reference:
      [1] W. Zhang, K. Saijo, Z.-Q., Wang, S. Watanabe, and Y. Qian,
      “Toward Universal Speech Enhancement for Diverse Input Conditions,”
      in Proc. ASRU, 2023.
  
  args:
      input_size (int): dimension of the input feature.
      output_size (int): dimension of the output.
      bottleneck_size (int): dimension of the bottleneck feature.
          Must be a multiple of `att_heads`.
      num_blocks (int): number of processing blocks.
      num_spatial_blocks (int): number of processing blocks with channel modeling.
      segment_size (int): number of frames in each non-overlapping segment.
          This is used to segment long utterances into smaller segments for
          efficient processing.
      memory_size (int): group size of global memory tokens.
          The basic use of memory tokens is to store the history information from
          previous segments.
          The memory tokens are updated by the output of the last block after
          processing each segment.
      memory_types (int): numbre of memory token groups.
          Each group corresponds to a different type of processing, i.e.,
              the first group is used for denoising without dereverberation,
              the second group is used for denoising with dereverberation,
      rnn_type (str): type of the RNN cell in the improved Transformer layer.
      hidden_size (int): hidden dimension of the RNN cell.
      att_heads (int): number of attention heads in Transformer.
      dropout (float): dropout ratio. Default is 0.
      activation (str): non-linear activation function applied in each block.
      bidirectional (bool): whether the RNN layers are bidirectional.
      norm_type (str): normalization type in the improved Transformer layer.
      ch_mode (str): mode of channel modeling.
          Select from "att" and "tac".
      ch_att_dim (int): dimension of the channel attention.
      eps (float): epsilon for layer normalization.
code: def __init__(
      self,
      input_size,
      output_size,
      bottleneck_size=64,
      num_blocks=6,
      num_spatial_blocks=3,
      segment_size=64,
      memory_size=20,
      memory_types=1,
      # Transformer-related arguments
      rnn_type="lstm",
      hidden_size=128,
      att_heads=4,
      dropout=0.0,
      activation="relu",
      bidirectional=True,
      norm_type="cLN",
      ch_mode="att",
      ch_att_dim=256,
      eps=1e-5,
  ):
      super().__init__()
  
      # [B, input_size, T] -> [B, input_size, T]
      self.layer_norm = ChannelwiseLayerNorm(input_size)
      # [B, input_size, T] -> [B, bottleneck_size, T]
      self.bottleneck_conv1x1 = nn.Conv1d(
          input_size, bottleneck_size, 1, bias=False
      )
  
      self.input_size = input_size
      self.bottleneck_size = bottleneck_size
      self.output_size = output_size
  
      assert num_blocks >= num_spatial_blocks, (
          num_blocks,
          num_spatial_blocks,
      )
      assert ch_mode in ("att", "tac"), ch_mode
      self.atf_blocks = nn.ModuleList()
      for i in range(num_blocks):
          self.atf_blocks.append(
              ATFBlock(
                  input_size=bottleneck_size,
                  rnn_type=rnn_type,
                  hidden_size=hidden_size,
                  att_heads=att_heads,
                  dropout=dropout,
                  activation=activation,
                  bidirectional=bidirectional,
                  norm_type=norm_type,
                  ch_mode=ch_mode,
                  ch_att_dim=ch_att_dim,
                  eps=eps,
                  with_channel_modeling=i < num_spatial_blocks,
              )
          )
  
      self.segment_size = segment_size
      self.memory_size = memory_size
      self.memory_types = memory_types
      if memory_types == 1:
          # single group of memory tokens (only used to provide history information)
          # (B=1, C=1, bottleneck_size, F=1, memory_size)
          self.memory_tokens = nn.Parameter(
              torch.randn(1, 1, bottleneck_size, 1, memory_size)
          )
      else:
          # >1 groups of memory tokens (used to also control processing behavior)
          self.memory_tokens = nn.ParameterList(
              [
                  nn.Parameter(
                      torch.randn(1, 1, bottleneck_size, 1, memory_size)
                  )
                  for _ in range(memory_types)
              ]
          )
  
      self.output = nn.Sequential(
          nn.PReLU(), nn.Conv2d(bottleneck_size, output_size, 1)
      )
  
imports: import warnings
  import torch
  import torch.nn
  from espnet2.enh.layers.dptnet import ImprovedTransformerLayer
  from espnet2.enh.layers.tcn import ChannelwiseLayerNorm
  from espnet2.torch_utils.get_layer_from_string import get_layer
label_desc: Use image node_id 1 to create a new USES object from inherited base classes: nn with example: obj = USES(input_size, output_size, bottleneck_size, num_blocks, num_spatial_blocks, segment_size, memory_size, memory_types, rnn_type, hidden_size, att_heads, dropout, activation, bidirectional, norm_type, ch_mode, ch_att_dim, eps)