class_docstr: GroverTransEncoder for encoding a molecular graph
  
  The GroverTransEncoder layer is used for encoding a molecular graph.
  The layer returns 4 outputs. They are atom messages aggregated from atom hidden states,
  atom messages aggregated from bond hidden states, bond messages aggregated from atom hidden
  states, bond messages aggregated from bond hidden states.
  
  Parameters
  ----------
  hidden_size: int
      the hidden size of the model.
  edge_fdim: int
      the dimension of additional feature for edge/bond.
  node_fdim: int
      the dimension of additional feature for node/atom.
  depth: int
      Dynamic message passing depth for use in MPNEncoder
  undirected: bool
      The message passing is undirected or not
  dropout: float
      the dropout ratio
  activation: str
      the activation function
  num_mt_block: int
      the number of mt block.
  num_head: int
      the number of attention AttentionHead.
  bias: bool
      enable bias term in all linear layers.
  res_connection: bool
      enables the skip-connection in MTBlock.
class_docstr_tok: ["GroverTransEncoder","for","encoding","a","molecular","graph","The","GroverTransEncoder","layer","is","used","for","encoding","a","molecular","graph",".","The","layer","returns","4","outputs",".","They","are","atom","messages","aggregated","from","atom","hidden","states",",","atom","messages","aggregated","from","bond","hidden","states",",","bond","messages","aggregated","from","atom","hidden","states",",","bond","messages","aggregated","from","bond","hidden","states",".","Parameters","--","--","--","--","--","hidden_size",":","int","the","hidden","size","of","the","model",".","edge_fdim",":","int","the","dimension","of","additional","feature","for","edge\/bond",".","node_fdim",":","int","the","dimension","of","additional","feature","for","node\/atom",".","depth",":","int","Dynamic","message","passing","depth","for","use","in","MPNEncoder","undirected",":","bool","The","message","passing","is","undirected","or","not","dropout",":","float","the","dropout","ratio","activation",":","str","the","activation","function","num_mt_block",":","int","the","number","of","mt","block",".","num_head",":","int","the","number","of","attention","AttentionHead",".","bias",":","bool","enable","bias","term","in","all","linear","layers",".","res_connection",":","bool","enables","the","skip-connection","in","MTBlock","."]
docstr: Transfer the output of atom/bond multi-head attention to the final atom/bond output.
          
code: def _atom_bond_transform(
      self,
      to_atom=True,  # False: to bond
      atomwise_input=None,
      bondwise_input=None,
      original_f_atoms=None,
      original_f_bonds=None,
      a2a=None,
      a2b=None,
      b2a=None,
      b2revb=None,
  ):
      """Transfer the output of atom/bond multi-head attention to the final atom/bond output."""
  
      if to_atom:
          # atom input to atom output
          (
              atomwise_input,
              _,
          ) = self._pointwise_feed_forward_to_atom_embedding(
              atomwise_input,
              original_f_atoms,
              a2a,
              self.ffn_atom_from_atom,
          )
          atom_in_atom_out = self.atom_from_atom_sublayer(
              None, atomwise_input
          )
          # bond to atom
          (
              bondwise_input,
              _,
          ) = self._pointwise_feed_forward_to_atom_embedding(
              bondwise_input,
              original_f_atoms,
              a2b,
              self.ffn_atom_from_bond,
          )
          bond_in_atom_out = self.atom_from_bond_sublayer(
              None, bondwise_input
          )
          return atom_in_atom_out, bond_in_atom_out
      else:  # to bond embeddings
          # atom input to bond output
          atom_list_for_bond = torch.cat(
              [b2a.unsqueeze(dim=1), a2a[b2a]], dim=1
          )
          (
              atomwise_input,
              _,
          ) = self._pointwise_feed_forward_to_bond_embedding(
              atomwise_input,
              original_f_bonds,
              atom_list_for_bond,
              b2a[b2revb],
              self.ffn_bond_from_atom,
          )
          atom_in_bond_out = self.bond_from_atom_sublayer(
              None, atomwise_input
          )
          # bond input to bond output
          bond_list_for_bond = a2b[b2a]
          (
              bondwise_input,
              _,
          ) = self._pointwise_feed_forward_to_bond_embedding(
              bondwise_input,
              original_f_bonds,
              bond_list_for_bond,
              b2revb,
              self.ffn_bond_from_bond,
          )
          bond_in_bond_out = self.bond_from_bond_sublayer(
              None, bondwise_input
          )
          return atom_in_bond_out, bond_in_bond_out
  
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 5 for calling the GroverTransEncoder obj's underlying member method code with example usage: obj._atom_bond_transform(to_atom, atomwise_input, bondwise_input, original_f_atoms, original_f_bonds, a2a, a2b, b2a, b2revb) and returns: atom_in_atom_out,  bond_in_atom_out, atom_in_bond_out,  bond_in_bond_out