class_docstr: A class to wrap training code.
docstr: Evaluate on the validation set.
  
  NOTE(brendan): We should not be using the test set to develop the
  algorithm (basic machine learning good practices).
code: def evaluate(self, source, dag, name, batch_size=1, max_num=None):
      """Evaluate on the validation set.
  
      NOTE(brendan): We should not be using the test set to develop the
      algorithm (basic machine learning good practices).
      """
      self.shared.eval()
      self.controller.eval()
  
      data = source[: max_num * self.max_length]
  
      total_loss = 0
      hidden = self.shared.init_hidden(batch_size)
  
      pbar = range(0, data.size(0) - 1, self.max_length)
      for count, idx in enumerate(pbar):
          inputs, targets = self.get_batch(data, idx, volatile=True)
          output, hidden, _ = self.shared(
              inputs, dag, hidden=hidden, is_train=False
          )
          output_flat = output.view(-1, self.dataset.num_tokens)
          total_loss += len(inputs) * self.ce(output_flat, targets).data
          hidden.detach_()
          ppl = math.exp(
              utils.to_item(total_loss) / (count + 1) / self.max_length
          )
  
      val_loss = utils.to_item(total_loss) / len(data)
      ppl = math.exp(val_loss)
  
      self.tb.scalar_summary(f"eval/{name}_loss", val_loss, self.epoch)
      self.tb.scalar_summary(f"eval/{name}_ppl", ppl, self.epoch)
      logger.info(f"eval | loss: {val_loss:8.2f} | ppl: {ppl:8.2f}")
  
imports: import contextlib
  import glob
  import math
  import os
  import numpy
  import scipy.signal
  from tensorboard import TensorBoard
  import torch
  from torch import nn
  import torch.nn.parallel
  from torch.autograd import Variable
  import models
  import utils
label_desc: Use image node_id 8 for calling the Trainer obj's underlying member method code with example usage: obj.evaluate(source, dag, name, batch_size, max_num) without return types