code: def on_epoch_end(self, callback_data, model, epoch):
      self.eval_set.reset()
      eval_set = self.eval_set.__iter__()
  
      n = 0
      while n < self.num_images:
          (x, t) = eval_set.next()
          (gt_boxes, gt_classes, num_gt_boxes, difficult, im_shape) = t
  
          gt_boxes = gt_boxes.reshape((-1, 4, self.be.bsz))
  
          outputs = model.fprop(x, inference=True)
  
          images = x.get()
          for k, output in enumerate(outputs):
              ngt = num_gt_boxes[0, k]
  
              # creates a PIL image object with the gt_boxes and predicted boxes
              img = plot_image(
                  img=images[:, k],
                  im_shape=im_shape[:, k],
                  gt_boxes=gt_boxes[:ngt, :, k],
                  boxes=output,
                  score_threshold=self.score_threshold,
              )
  
              file_name = os.path.join(
                  self.image_dir, "image_e{}_{}.jpg".format(epoch, n)
              )
              img.save(file_name)
              # logger.info('Saved sample images to: {}'.format(file_name))
  
              n = n + 1
              if n >= self.num_images:
                  break
  
file_path: neon/examples/ssd/callbacks.py
imports: import numpy
  from neon.callbacks.callbacks import Callback
  from neon import logger
  from inference import get_boxes
  from util.voc_eval import voc_eval
  from util.util import plot_image
  import os
label_desc: Use image node_id 2 for calling the ssd_image_callback obj's underlying member method code with example usage: obj.on_epoch_end(callback_data, model, epoch) without return types