class_docstr: Graph Information Network (GIN) encoder. This is a graph convolutional network that produces encoded representations for molecular graph inputs.
  
  Parameters
  ----------
  num_features: int
      The number of node features
  embedding_dim: int
      The dimension of the output embedding
  num_gc_layers: int, optional (default 5)
      The number of graph convolutional layers to use
  
  Example
  -------
  >>> import numpy as np
  >>> from deepchem.models.torch_models.infograph import GINEncoder
  >>> from deepchem.feat.graph_data import GraphData
  >>> encoder = GINEncoder(num_features=25, 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, intermediate_embeddings = encoder(data)
  >>> print(embedding.shape)
  torch.Size([1, 30])
  
  References
  ----------
  .. [1] Xu, K., Hu, W., Leskovec, J. & Jegelka, S. How Powerful are Graph Neural Networks? arXiv:1810.00826 [cs, stat] (2019).
code: def __init__(
      self,
      num_features: int,
      embedding_dim: int,
      num_gc_layers: int = 5,
  ):
      dim = int(
          embedding_dim / num_gc_layers
      )  # the output dimension of this encoder is modified by the number of GC layers, so this is necessary to ensure that the output dimension is consistent with the InfoGraphEncoder
      super().__init__()
  
      self.num_gc_layers = num_gc_layers
  
      self.convs = torch.nn.ModuleList()
      self.bns = torch.nn.ModuleList()
  
      for i in range(num_gc_layers):
          if i == 0:
              nn = Sequential(
                  Linear(num_features, dim), ReLU(), Linear(dim, dim)
              )
          else:
              nn = Sequential(
                  Linear(dim, dim), ReLU(), Linear(dim, dim)
              )
          conv = GINConv(nn)
          bn = torch.nn.BatchNorm1d(dim)
  
          self.convs.append(conv)
          self.bns.append(bn)
  
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 1 to create a new GINEncoder object from inherited base classes: torch.nn with example: obj = GINEncoder(num_features, embedding_dim, num_gc_layers)