code: def train(train_dataloader, val_dataloader, device, model):
      # define loss function and optimizer
      loss_fcn = nn.BCEWithLogitsLoss()
      optimizer = torch.optim.Adam(
          model.parameters(), lr=5e-3, weight_decay=0
      )
  
      # training loop
      for epoch in range(400):
          model.train()
          logits = []
          total_loss = 0
          # mini-batch loop
          for batch_id, batched_graph in enumerate(train_dataloader):
              batched_graph = batched_graph.to(device)
              features = batched_graph.ndata["feat"].float()
              labels = batched_graph.ndata["label"].float()
              logits = model(batched_graph, features)
              loss = loss_fcn(logits, labels)
              optimizer.zero_grad()
              loss.backward()
              optimizer.step()
              total_loss += loss.item()
          print(
              "Epoch {:05d} | Loss {:.4f} |".format(
                  epoch, total_loss / (batch_id + 1)
              )
          )
  
          if (epoch + 1) % 5 == 0:
              avg_score = evaluate_in_batches(
                  val_dataloader, device, model
              )  # evaluate F1-score instead of loss
              print(
                  "                            Acc. (F1-score) {:.4f} ".format(
                      avg_score
                  )
              )
  
file_path: dgl/examples/pytorch/gat/train_ppi.py
imports: import dgl.nn
  import numpy
  import torch
  import torch.nn
  import torch.nn.functional
  from dgl.data.ppi import PPIDataset
  from dgl.dataloading import GraphDataLoader
  from sklearn.metrics import f1_score
label_desc: Use image node_id 3 for calling a global function with example usage: train(train_dataloader, val_dataloader, device, model) without return types