code: def __init__(
      self,
      input_dim: int,
      output_dim: int,
      gnn_latent_dim: Union[List[int]],
      gnn_dropout: float = 0.0,
      gnn_emb_normalization: bool = False,
      gcn_adj_normalization: bool = True,
      add_self_loop: bool = True,
      gnn_nonlinear: str = "relu",
      readout: str = "mean",
      concate: bool = False,
      fc_latent_dim: Union[List[int]] = [],
      fc_dropout: float = 0.0,
      fc_nonlinear: str = "relu",
  ):
      super(GCNNet, self).__init__()
      # first and last layer - dim_features and classes
      self.input_dim = input_dim
      self.output_dim = output_dim
      # GNN part
      self.gnn_latent_dim = gnn_latent_dim
      self.gnn_dropout = gnn_dropout
      self.num_gnn_layers = len(self.gnn_latent_dim)
      self.add_self_loop = add_self_loop
      self.gnn_emb_normalization = gnn_emb_normalization
      self.gcn_adj_normalization = gcn_adj_normalization
      self.gnn_nonlinear = get_nonlinear(gnn_nonlinear)
      self.concate = concate
      # readout
      self.readout_layer = GNNPool(readout)
      # FC part
      self.fc_latent_dim = fc_latent_dim
      self.fc_dropout = fc_dropout
      self.num_mlp_layers = len(self.fc_latent_dim) + 1
      self.fc_nonlinear = get_nonlinear(fc_nonlinear)
  
      if self.concate:
          self.emb_dim = sum(self.gnn_latent_dim)
      else:
          self.emb_dim = self.gnn_latent_dim[-1]
  
      # GNN layers
      self.convs = nn.ModuleList()
      self.convs.append(
          GCNConv(
              input_dim,
              self.gnn_latent_dim[0],
              add_self_loops=self.add_self_loop,
              normalize=self.gcn_adj_normalization,
          )
      )
      for i in range(1, self.num_gnn_layers):
          self.convs.append(
              GCNConv(
                  self.gnn_latent_dim[i - 1],
                  self.gnn_latent_dim[i],
                  add_self_loops=self.add_self_loop,
                  normalize=self.gcn_adj_normalization,
              )
          )
      # FC layers
      self.mlps = nn.ModuleList()
      if self.num_mlp_layers > 1:
          self.mlps.append(
              nn.Linear(self.emb_dim, self.fc_latent_dim[0])
          )
  
          for i in range(1, self.num_mlp_layers - 1):
              self.mlps.append(
                  nn.Linear(
                      self.fc_latent_dim[i - 1], self.fc_latent_dim[1]
                  )
              )
          self.mlps.append(
              nn.Linear(self.fc_latent_dim[-1], self.output_dim)
          )
      else:
          self.mlps.append(nn.Linear(self.emb_dim, self.output_dim))
  
imports: import torch
  import torch.nn
  from functools import partial
  from typing import Union, List
  import torch.nn.functional
  from torch_geometric.data import Batch
  from torch_geometric.nn.conv.gcn_conv import gcn_norm
  from torch_geometric.nn.conv import GCNConv
  from torch_geometric.nn.glob import global_mean_pool, global_add_pool, global_max_pool
  from torch import Tensor
  from torch_sparse import SparseTensor, fill_diag
  from torch_geometric.typing import Adj, OptTensor, Size
  from torch_geometric.utils import add_self_loops
  from dig.xgraph.models import GNNPool
  from collections import OrderedDict
label_desc: Use image node_id 1 to create a new GCNNet object from inherited base classes: GNNBase with example: obj = GCNNet(input_dim, output_dim, gnn_latent_dim, gnn_dropout, gnn_emb_normalization, gcn_adj_normalization, add__loop, gnn_nonlinear, readout, concate, fc_latent_dim, fc_dropout, fc_nonlinear)