class_docstr: Implementation of Multi-Head Attention
  
  The MH Block in paper: Accurate Learning of Graph Representations
  with Graph Multiset Pooling
  
  Args:
      dim_Q: The dimension of query tensor.
      dim_K: The dimension of key tensor.
      dim_V: The dimension of value tensor.
      num_heads: The number of attention heads.
      conv: The Graph Convolution Block for GMH. Default: None
      layer_norm: Whether to use LayerNorm.
code: def __init__(
      self, dim_Q, dim_K, dim_V, num_heads, conv=None, layer_norm=False
  ):
      super(MAB, self).__init__()
      self.dim_V = dim_V
      self.num_heads = num_heads
      self.layer_norm = layer_norm
      self.proj_q = nn.Linear(dim_K, dim_V)
      if conv is None:
          self.layer_k = nn.Linear(dim_K, dim_V)
          self.layer_v = nn.Linear(dim_K, dim_V)
      else:
          # GCNConv is enough
          self.layer_k = conv(dim_K, dim_V)
          self.layer_v = conv(dim_K, dim_V)
      if layer_norm:
          self.ln0 = nn.LayerNorm(dim_V)
          self.ln1 = nn.LayerNorm(dim_V)
  
      self.proj_o = nn.Linear(dim_V, dim_V)
  
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 MAB object from inherited base classes: nn with example: obj = MAB(dim_Q, dim_K, dim_V, num_heads, conv, layer_norm)