code: def main(args):
      # load and preprocess dataset
      data = load_data(args)
      features = torch.FloatTensor(data.features)
      labels = torch.LongTensor(data.labels)
      if hasattr(torch, "BoolTensor"):
          train_mask = torch.BoolTensor(data.train_mask)
          val_mask = torch.BoolTensor(data.val_mask)
          test_mask = torch.BoolTensor(data.test_mask)
      else:
          train_mask = torch.ByteTensor(data.train_mask)
          val_mask = torch.ByteTensor(data.val_mask)
          test_mask = torch.ByteTensor(data.test_mask)
      in_feats = features.shape[1]
      n_classes = data.num_labels
      n_edges = data.graph.number_of_edges()
      print(
          """----Data statistics------'
        #Edges %d
        #Classes %d
        #Train samples %d
        #Val samples %d
        #Test samples %d"""
          % (
              n_edges,
              n_classes,
              train_mask.int().sum().item(),
              val_mask.int().sum().item(),
              test_mask.int().sum().item(),
          )
      )
  
      if args.gpu < 0:
          cuda = False
      else:
          cuda = True
          torch.cuda.set_device(args.gpu)
          features = features.cuda()
          labels = labels.cuda()
          train_mask = train_mask.cuda()
          val_mask = val_mask.cuda()
          test_mask = test_mask.cuda()
  
      # graph preprocess and calculate normalization factor
      g = data.graph
      # add self loop
      if args.self_loop:
          g.remove_edges_from(nx.selfloop_edges(g))
          g.add_edges_from(zip(g.nodes(), g.nodes()))
      g = DGLGraph(g)
      n_edges = g.number_of_edges()
      # normalization
      degs = g.in_degrees().float()
      norm = torch.pow(degs, -0.5)
      norm[torch.isinf(norm)] = 0
      g.ndata["node_feat"] = features
      if cuda:
          norm = norm.cuda()
      g.ndata["norm"] = norm.unsqueeze(1)
  
      G = GraphData()
      G.from_dgl(g)
  
      # create GCN model
      model = GCN(
          in_feats,
          args.n_hidden,
          n_classes,
          args.n_layers,
          args.aggregate_type,
          args.output_size,
          dropout=args.dropout,
      )
  
      if cuda:
          model.cuda()
      loss_fcn = torch.nn.CrossEntropyLoss()
  
      # use optimizer
      optimizer = torch.optim.Adam(
          model.parameters(), lr=args.lr, weight_decay=args.weight_decay
      )
  
      # initialize graph
      dur = []
      for epoch in range(args.n_epochs):
          model.train()
          if epoch >= 3:
              t0 = time.time()
          # forward
          logits = model(G)
          loss = loss_fcn(logits[train_mask], labels[train_mask])
  
          optimizer.zero_grad()
          loss.backward()
          optimizer.step()
  
          if epoch >= 3:
              dur.append(time.time() - t0)
  
          acc = evaluate(model, G, labels, val_mask)
          print(
              "Epoch {:05d} | Time(s) {:.4f} | Loss {:.4f} | Accuracy {:.4f} | "
              "ETputs(KTEPS) {:.2f}".format(
                  epoch,
                  np.mean(dur),
                  loss.item(),
                  acc,
                  n_edges / np.mean(dur) / 1000,
              )
          )
  
      print()
      acc = evaluate(model, G, labels, test_mask)
      print("Test accuracy {:.2%}".format(acc))
  
file_path: graph4nlp/graph4nlp/pytorch/test/node_classification/node_classification_test.py
imports: import argparse
  import time
  import networkx
  import numpy
  import torch
  import torch.nn
  from dgl import DGLGraph
  from dgl.data import load_data, register_data_args
  from ...data.data import GraphData
  from ...modules.graph_embedding_learning.graphsage import GraphSAGE
  from ...modules.prediction.classification.node_classification.BiLSTMFeedForwardNN import BiLSTMFeedForwardNN
label_desc: Use image node_id 2 for calling a global function with example usage: main(args) without return types