class_docstr: Implementation of Graph Multiset Transformer pooling operator
  Referenced from: Accurate Learning of Graph Representations
  with Graph Multiset Pooling
  
  Args:
      input_dim: The size of input feature
      hidden_dim: The number of hidden units.
      output_dim: The size of output feature.
      conv: A graph convolution layer. Default: pgl.nn.GCNCONV
      num_nodes: The number of average nodes.
      pooling_ratio: The pooling ratio of GMPool. Default: 0.25
      pool_sequences: A str list that contains the blocks refered in GMT paper.
                      Default`["GMPool_G", "SelfAtt", "GMPool_I"]`)
      num_heads: The number of attention heads. Default: 4
      layer_norm: Wether to use LayerNorm. Default: False
      
code: def __init__(
      self,
      input_dim,
      hidden_dim,
      output_dim,
      conv=None,
      num_nodes=30,
      pooling_ratio=0.25,
      pool_sequences=None,
      num_heads=4,
      layer_norm=False,
  ):
      super(GraphMultisetTransformer, self).__init__()
      self.input_dim = input_dim
      self.hidden_dim = hidden_dim
      self.output_dim = output_dim
      self.conv = conv or pgl.nn.GCNConv
      self.num_nodes = num_nodes
      self.pooling_ratio = pooling_ratio
      self.pool_sequences = (
          ["GMPool_G", "SelfAtt", "GMPool_I"]
          if pool_sequences is None
          else pool_sequences
      )
      self.num_heads = num_heads
      self.layer_norm = layer_norm
      self.pools = nn.LayerList()
      num_out_nodes = math.ceil(num_nodes * pooling_ratio)
      self.lin1 = nn.Linear(input_dim, hidden_dim)
      self.lin2 = nn.Linear(hidden_dim, output_dim)
  
      for i, pool_type in enumerate(self.pool_sequences):
          if pool_type not in ["GMPool_G", "GMPool_I", "SelfAtt"]:
              raise ValueError(
                  "Elements in 'pool_sequences' should be one "
                  "of 'GMPool_G', 'GMPool_I', or 'SelfAtt'"
              )
          if i == len(self.pool_sequences) - 1:
              num_out_nodes = 1
  
          if pool_type == "GMPool_G":
              self.pools.append(
                  PMA(
                      hidden_dim,
                      num_heads,
                      num_out_nodes,
                      conv=self.conv,
                      layer_norm=layer_norm,
                  )
              )
              num_out_nodes = math.ceil(
                  num_out_nodes * self.pooling_ratio
              )
          elif pool_type == "GMPool_I":
              self.pools.append(
                  PMA(
                      hidden_dim,
                      num_heads,
                      num_out_nodes,
                      conv=None,
                      layer_norm=layer_norm,
                  )
              )
              num_out_nodes = math.ceil(
                  num_out_nodes * self.pooling_ratio
              )
          elif pool_type == "SelfAtt":
              self.pools.append(
                  SAB(
                      hidden_dim,
                      hidden_dim,
                      num_heads,
                      conv=None,
                      layer_norm=layer_norm,
                  )
              )
  
imports: import paddle
  import paddle.nn
  import math
  import paddle.nn.functional
  import pgl
  from pgl.utils.transform import to_dense_batch
label_desc: Use image node_id 1 to create a new GraphMultisetTransformer object from inherited base classes: nn with example: obj = GraphMultisetTransformer(input_dim, hidden_dim, output_dim, conv, num_nodes, pooling_ratio, pool_sequences, num_heads, layer_norm)