code: def train():
      model.train()
      optimizer.zero_grad()
      z = model.encode(train_data.x, train_data.edge_index)
  
      # We perform a new round of negative sampling for every training epoch:
      neg_edge_index = negative_sampling(
          edge_index=train_data.edge_index,
          num_nodes=train_data.num_nodes,
          num_neg_samples=train_data.edge_label_index.size(1),
          method="sparse",
      )
  
      edge_label_index = torch.cat(
          [train_data.edge_label_index, neg_edge_index],
          dim=-1,
      )
      edge_label = torch.cat(
          [
              train_data.edge_label,
              train_data.edge_label.new_zeros(neg_edge_index.size(1)),
          ],
          dim=0,
      )
  
      out = model.decode(z, edge_label_index).view(-1)
      loss = criterion(out, edge_label)
      loss.backward()
      optimizer.step()
      return loss
  
file_path: pytorch_geometric/examples/link_pred.py
imports: import os.path
  import torch
  from sklearn.metrics import roc_auc_score
  import torch_geometric.transforms
  from torch_geometric.datasets import Planetoid
  from torch_geometric.nn import GCNConv
  from torch_geometric.utils import negative_sampling
label_desc: Use image node_id 1 for calling a global function with example usage: train() and returns: loss