class_docstr: The encoder for the InfoGraph model. It is a message passing graph convolutional
  network that produces encoded representations for molecular graph inputs.
  
  Parameters
  ----------
  num_features: int
      Number of node features for each input
  edge_features: int
      Number of edge features for each input
  embedding_dim: int
      Dimension of the embedding
  
  Example
  -------
  >>> import numpy as np
  >>> from deepchem.models.torch_models.infograph import InfoGraphEncoder
  >>> from deepchem.feat.graph_data import GraphData
  >>> encoder = InfoGraphEncoder(num_features=25, edge_features=10, embedding_dim=32)
  >>> node_features = np.random.randn(10, 25)
  >>> edge_index = np.array([[0, 1, 2], [1, 2, 3]])
  >>> edge_features = np.random.randn(3, 10)
  >>> graph_index = np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
  >>> data = GraphData(node_features=node_features, edge_index=edge_index, edge_features=edge_features, graph_index=graph_index).numpy_to_torch()
  >>> embedding, feature_map = encoder(data)
  >>> print(embedding.shape)
  torch.Size([1, 64])
docstr: Encode input graphs into an embedding and feature map.
  
  Parameters
  ----------
  data: Union[BatchGraphData, GraphData]
      Contains information about graphs.
  
  Returns
  -------
  torch.Tensor
      Encoded tensor of input data.
  torch.Tensor
      Feature map tensor of input data.
docstr_tok: ["Encode","input","graphs","into","an","embedding","and","feature","map",".","Parameters","--","--","--","--","--","data",":","Union","[","BatchGraphData",",","GraphData","]","Contains","information","about","graphs",".","Returns","--","--","--","-","torch.Tensor","Encoded","tensor","of","input","data",".","torch.Tensor","Feature","map","tensor","of","input","data","."]
code: def forward(self, data):
      """
      Encode input graphs into an embedding and feature map.
  
      Parameters
      ----------
      data: Union[BatchGraphData, GraphData]
          Contains information about graphs.
  
      Returns
      -------
      torch.Tensor
          Encoded tensor of input data.
      torch.Tensor
          Feature map tensor of input data.
  
      """
      out = F.relu(self.lin0(data.node_features))
      h = out.unsqueeze(0)
  
      for i in range(3):
          m = F.relu(
              self.conv(out, data.edge_index, data.edge_features)
          )
          out, h = self.gru(m.unsqueeze(0), h)
          out = out.squeeze(0)
          feat_map = out
  
      # set2set doubles the dimensionality of the embedding
      out = self.set2set(out, data.graph_index)
      return out, feat_map
  
imports: import torch
  import torch.nn
  import torch.nn.functional
  from torch.nn import GRU, Linear, ReLU, Sequential
  from typing import Iterable, List, Tuple, Optional, Dict, Literal
  from deepchem.metrics import to_one_hot
  import deepchem
  from deepchem.models.losses import SoftmaxCrossEntropy
  from deepchem.feat.graph_data import BatchGraphData
  from deepchem.models.losses import GlobalMutualInformationLoss, LocalMutualInformationLoss
  from deepchem.models.torch_models.layers import MultilayerPerceptron
  from deepchem.models.torch_models.modular import ModularTorchModel
label_desc: Use image node_id 2 for calling the InfoGraphEncoder obj's underlying member method code with example usage: obj.forward(data) and returns: out,  feat_map