class_docstr: The Attentive FP model for molecular representation learning from the
  `"Pushing the Boundaries of Molecular Representation for Drug Discovery
  with the Graph Attention Mechanism"
  <https://pubs.acs.org/doi/10.1021/acs.jmedchem.9b00959>`_ paper, based on
  graph attention mechanisms.
  
  Args:
      in_channels (int): Size of each input sample.
      hidden_channels (int): Hidden node feature dimensionality.
      out_channels (int): Size of each output sample.
      edge_dim (int): Edge feature dimensionality.
      num_layers (int): Number of GNN layers.
      num_timesteps (int): Number of iterative refinement steps for global
          readout.
      dropout (float, optional): Dropout probability. (default: :obj:`0.0`)
code: def forward(
      self,
      x: Tensor,
      edge_index: Tensor,
      edge_attr: Tensor,
      batch: Tensor,
  ) -> Tensor:
      """"""  # noqa: D419
      # Atom Embedding:
      x = F.leaky_relu_(self.lin1(x))
  
      h = F.elu_(self.gate_conv(x, edge_index, edge_attr))
      h = F.dropout(h, p=self.dropout, training=self.training)
      x = self.gru(h, x).relu_()
  
      for conv, gru in zip(self.atom_convs, self.atom_grus):
          h = conv(x, edge_index)
          h = F.elu(h)
          h = F.dropout(h, p=self.dropout, training=self.training)
          x = gru(h, x).relu()
  
      # Molecule Embedding:
      row = torch.arange(batch.size(0), device=batch.device)
      edge_index = torch.stack([row, batch], dim=0)
  
      out = global_add_pool(x, batch).relu_()
      for t in range(self.num_timesteps):
          h = F.elu_(self.mol_conv((x, out), edge_index))
          h = F.dropout(h, p=self.dropout, training=self.training)
          out = self.mol_gru(h, out).relu_()
  
      # Predictor:
      out = F.dropout(out, p=self.dropout, training=self.training)
      return self.lin2(out)
  
imports: from typing import Optional
  import torch
  import torch.nn.functional
  from torch import Tensor
  from torch.nn import GRUCell, Linear, Parameter
  from torch_geometric.nn import GATConv, MessagePassing, global_add_pool
  from torch_geometric.nn.inits import glorot, zeros
  from torch_geometric.typing import Adj, OptTensor
  from torch_geometric.utils import softmax
label_desc: Use image node_id 3 for calling the AttentiveFP obj's underlying member method code with example usage: obj.forward(x, edge_index, edge_attr, batch) and returns: self