class_docstr: Generates attention head using GroverMPNEncoder for generating query, key and value
  
  Parameters
  ----------
  hidden_size: int
      Dimension of hidden layer
  undirected: bool
      If set to `True`, the graph is considered as an undirected graph.
  depth: int
      number of hops in a message passing iteration
  atom_messages: bool
      True if encoding atom-messages else False.
class_docstr_tok: ["Generates","attention","head","using","GroverMPNEncoder","for","generating","query",",","key","and","value","Parameters","--","--","--","--","--","hidden_size",":","int","Dimension","of","hidden","layer","undirected",":","bool","If","set","to","`","True","`",",","the","graph","is","considered","as","an","undirected","graph",".","depth",":","int","number","of","hops","in","a","message","passing","iteration","atom_messages",":","bool","True","if","encoding","atom-messages","else","False","."]
code: def __init__(
      self,
      hidden_size: int = 128,
      bias: bool = True,
      depth: int = 1,
      dropout: float = 0.0,
      undirected: bool = False,
      atom_messages: bool = False,
  ):
      super(GroverAttentionHead, self).__init__()
      self.atom_messages = atom_messages
  
      # FIXME We assume that we are using a hidden layer to transform the initial atom message
      # and bond messages to hidden dimension size.
      self.mpn_q = GroverMPNEncoder(
          atom_messages=atom_messages,
          init_message_dim=hidden_size,
          attached_feat_fdim=hidden_size,
          hidden_size=hidden_size,
          bias=bias,
          depth=depth,
          dropout=dropout,
          undirected=undirected,
          attach_feats=False,
          input_layer="none",
          dynamic_depth="truncnorm",
      )
  
      self.mpn_k = GroverMPNEncoder(
          atom_messages=atom_messages,
          init_message_dim=hidden_size,
          attached_feat_fdim=hidden_size,
          hidden_size=hidden_size,
          bias=bias,
          depth=depth,
          dropout=dropout,
          undirected=undirected,
          attach_feats=False,
          input_layer="none",
          dynamic_depth="truncnorm",
      )
  
      self.mpn_v = GroverMPNEncoder(
          atom_messages=atom_messages,
          init_message_dim=hidden_size,
          attached_feat_fdim=hidden_size,
          hidden_size=hidden_size,
          bias=bias,
          depth=depth,
          dropout=dropout,
          undirected=undirected,
          attach_feats=False,
          input_layer="none",
          dynamic_depth="truncnorm",
      )
  
imports: from typing import List, Dict
  import numpy
  from scipy import stats
  from deepchem.models.torch_models.readout import GroverReadout
  from deepchem.models.torch_models.layers import SublayerConnection, PositionwiseFeedForward
label_desc: Use image node_id 1 to create a new GroverAttentionHead object from inherited base classes: nn with example: obj = GroverAttentionHead(hidden_size, bias, depth, dropout, undirected, atom_messages)