code: def validate(self):
      self.logger.info("Running evaluation")
  
      self.logger.info(
          "Num examples = %d", len(self.data.val_dl.dataset)
      )
      self.logger.info(
          "Validation Batch size = %d", self.data.val_batch_size
      )
  
      eval_loss = 0
      nb_eval_steps = 0
  
      validation_scores = {
          metric["name"]: 0.0 for metric in self.metrics
      }
  
      for step, batch in enumerate(progress_bar(self.data.val_dl)):
          self.model.eval()
          batch = batch.to(self.device)
  
          with torch.no_grad():
              outputs = self.model(batch, masked_lm_labels=batch)
              tmp_eval_loss = outputs[0]
              eval_loss += tmp_eval_loss.mean().item()
  
              cpu_device = torch.device("cpu")
              batch.to(cpu_device)
              torch.cuda.empty_cache()
  
          nb_eval_steps += 1
  
      eval_loss = eval_loss / nb_eval_steps
      perplexity = torch.exp(torch.tensor(eval_loss))
  
      results = {"loss": eval_loss, "perplexity": float(perplexity)}
  
      results.update(validation_scores)
  
      return results
  
file_path: fast-bert/fast_bert/learner_lm.py
imports: import os
  import torch
  from packaging import version
  from pathlib import Path
  import numpy
  from fastprogress.fastprogress import master_bar, progress_bar
  from tensorboardX import SummaryWriter
  from .learner_util import Learner
  from .data_lm import BertLMDataBunch
  from transformers import WEIGHTS_NAME, BertConfig, BertForMaskedLM, RobertaConfig, RobertaForMaskedLM, DistilBertConfig, DistilBertForMaskedLM, CamembertConfig, CamembertForMaskedLM, ElectraConfig, ElectraForMaskedLM
  from torch.optim.lr_scheduler import _LRScheduler, Optimizer
label_desc: Use image node_id 5 for calling the BertLMLearner obj's underlying member method code with example usage: obj.validate() and returns: results