code: def evaluate(
      model,
      g,
      metapath_list,
      num_neighbors,
      features,
      labels,
      val_nid,
      loss_fcn,
      batch_size,
  ):
      model.eval()
  
      han_valid_sampler = HANSampler(
          g, metapath_list, num_neighbors=num_neighbors * 2
      )
      dataloader = DataLoader(
          dataset=val_nid,
          batch_size=batch_size,
          collate_fn=han_valid_sampler.sample_blocks,
          shuffle=False,
          drop_last=False,
          num_workers=4,
      )
      correct = total = 0
      prediction_list = []
      labels_list = []
      with torch.no_grad():
          for step, (seeds, blocks) in enumerate(dataloader):
              h_list = load_subtensors(blocks, features)
              blocks = [block.to(args["device"]) for block in blocks]
              hs = [h.to(args["device"]) for h in h_list]
  
              logits = model(blocks, hs)
              loss = loss_fcn(
                  logits,
                  labels[numpy.asarray(seeds)].to(args["device"]),
              )
              # get each predict label
              _, indices = torch.max(logits, dim=1)
              prediction = indices.long().cpu().numpy()
              labels_batch = labels[numpy.asarray(seeds)].cpu().numpy()
  
              prediction_list.append(prediction)
              labels_list.append(labels_batch)
  
              correct += (prediction == labels_batch).sum()
              total += prediction.shape[0]
  
      total_prediction = numpy.concatenate(prediction_list)
      total_labels = numpy.concatenate(labels_list)
      micro_f1 = f1_score(
          total_labels, total_prediction, average="micro"
      )
      macro_f1 = f1_score(
          total_labels, total_prediction, average="macro"
      )
      accuracy = correct / total
  
      return loss, accuracy, micro_f1, macro_f1
  
imports: import dgl
  import numpy
  import argparse
  import torch
  import torch.nn
  import torch.nn.functional
  from dgl.nn.pytorch import GATConv
  from dgl.sampling import RandomWalkNeighborSampler
  from sklearn.metrics import f1_score
  from torch.utils.data import DataLoader
  from model_hetero import SemanticAttention
  from utils import EarlyStopping, set_random_seed
label_desc: Use image node_id 2 for calling a global function with example usage: evaluate(model, g, metapath_list, num_neighbors, features, labels, val_nid, loss_fcn, batch_size) and returns: loss,  accuracy,  micro_f1,  macro_f1