class_docstr: The evaluation interface for unsupervised graph representation learning evaluated with 
  linear classification. You can refer to `the benchmark code 
  <https://github.com/divelab/DIG/tree/dig/benchmarks/sslgraph>`_ 
  for examples of usage.
  
  Args:
      full_dataset (torch_geometric.data.Dataset): The graph classification dataset.
      train_mask (Tensor, optional): Boolean tensor of shape :obj:`[n_nodes,]`, indicating 
          nodes for training. Set to :obj:`None` if included in dataset.
          (default: :obj:`None`)
      val_mask (Tensor, optional): Boolean tensor of shape :obj:`[n_nodes,]`, indicating 
          nodes for validation. Set to :obj:`None` if included in dataset.
          (default: :obj:`None`)
      test_mask (Tensor, optional): Boolean tensor of shape :obj:`[n_nodes,]`, indicating 
          nodes for test. Set to :obj:`None` if included in dataset. (default: :obj:`None`)
      classifier (string, optional): Linear classifier for evaluation, :obj:`"SVC"` or 
          :obj:`"LogReg"`. (default: :obj:`"LogReg"`)
      log_interval (int, optional): Perform evaluation per k epochs. (default: :obj:`1`)
      device (int, or torch.device, optional): Device for computation. (default: :obj:`None`)
      **kwargs (optional): Training and evaluation configs in :meth:`setup_train_config`.
      
  Examples
  --------
  >>> node_dataset = get_node_dataset("Cora") # using default train/test split
  >>> evaluator = NodeUnsupervised(node_dataset, log_interval=10, device=0)
  >>> evaluator.evaluate(model, encoder)
  
  >>> node_dataset = SomeDataset()
  >>> # Using your own dataset or with different train/test split
  >>> train_mask, val_mask, test_mask = torch.Tensor([...]), torch.Tensor([...]), torch.Tensor([...])
  >>> evaluator = NodeUnsupervised(node_dataset, train_mask, val_mask, test_mask, log_interval=10, device=0)
  >>> evaluator.evaluate(model, encoder)
code: def log_reg(self, train_embs, train_lbls, test_embs, test_lbls):
      hid_units = train_embs.shape[1]
      train_embs = torch.from_numpy(train_embs).to(self.device)
      train_lbls = torch.from_numpy(train_lbls).to(self.device)
      test_embs = torch.from_numpy(test_embs).to(self.device)
      test_lbls = torch.from_numpy(test_lbls).to(self.device)
  
      xent = nn.CrossEntropyLoss()
      log = LogReg(hid_units, self.num_classes)
      log.to(self.device)
      opt = torch.optim.Adam(
          log.parameters(), lr=0.01, weight_decay=self.logreg_wd
      )
  
      best_val = 0
      test_acc = None
      for it in range(300):
          log.train()
          opt.zero_grad()
  
          logits = log(train_embs)
          loss = xent(logits, train_lbls)
  
          loss.backward()
          opt.step()
  
      logits = log(test_embs)
      preds = torch.argmax(logits, dim=1)
      acc = torch.sum(preds == test_lbls).float() / test_lbls.shape[0]
  
      return acc.item()
  
imports: import copy
  import torch
  import numpy
  import torch.nn
  from torch_geometric.loader import DataLoader
  from sklearn import preprocessing
label_desc: Use image node_id 7 for calling the NodeUnsupervised obj's underlying member method code with example usage: obj.log_reg(train_embs, train_lbls, test_embs, test_lbls) and returns: acc