class_docstr: The TensorBoardImages callback will write a selection of images from the validation pass to tensorboard using the
  TensorboardX library and torchvision.utils.make_grid (requires torchvision). Images are selected from the given key and saved to the given
  path. Full name of image sub directory will be model name + _ + comment.
  
  Example: ::
  
      >>> from torchbearer import Trial, state_key
      >>> from torchbearer.callbacks import TensorBoardImages
      >>> import datetime
      >>> current_time = datetime.now().strftime('%b%d_%H-%M-%S')
      >>> IMAGE_KEY = state_key('image_key')
  
      >>> # Callback that will log to tensorboard under "(model name)_(current time)"
      >>> tb = TensorBoardImages(comment=current_time, name='test_image', key=IMAGE_KEY)
      >>> # Trial that will run log to tensorboard images stored under IMAGE_KEY
      >>> t = Trial(None, callbacks=[tb], metrics=['acc', 'loss'])
  
  Args:
      log_dir (str): The tensorboard log path for output
      comment (str): Descriptive comment to append to path
      name (str): The name of the image
      key (StateKey): The key in state containing image data (tensor of size [c, w, h] or [b, c, w, h])
      write_each_epoch (bool): If True, write data on every epoch, else write only for the first epoch.
      num_images (int): The number of images to write
      nrow: See `torchvision.utils.make_grid <https://pytorch.org/docs/stable/torchvision/utils.html#torchvision.utils.make_grid>`_
      padding: See `torchvision.utils.make_grid <https://pytorch.org/docs/stable/torchvision/utils.html#torchvision.utils.make_grid>`_
      normalize: See `torchvision.utils.make_grid <https://pytorch.org/docs/stable/torchvision/utils.html#torchvision.utils.make_grid>`_
      norm_range: See `torchvision.utils.make_grid <https://pytorch.org/docs/stable/torchvision/utils.html#torchvision.utils.make_grid>`_
      scale_each: See `torchvision.utils.make_grid <https://pytorch.org/docs/stable/torchvision/utils.html#torchvision.utils.make_grid>`_
      pad_value: See `torchvision.utils.make_grid <https://pytorch.org/docs/stable/torchvision/utils.html#torchvision.utils.make_grid>`_
      visdom (bool): If true, log to visdom instead of tensorboard
      visdom_params (VisdomParams): Visdom parameter settings object, uses default if None
  
  State Requirements:
      - :attr:`torchbearer.state.EPOCH`: State should have the current epoch stored
      - `key`: State should have images stored under the given state key
class_docstr_tok: ["The","TensorBoardImages","callback","will","write","a","selection","of","images","from","the","validation","pass","to","tensorboard","using","the","TensorboardX","library","and","torchvision.utils.make_grid","(","requires","torchvision",")",".","Images","are","selected","from","the","given","key","and","saved","to","the","given","path",".","Full","name","of","image","sub","directory","will","be","model","name","+","_","+","comment",".","Example",":",":",":",">",">",">","from","torchbearer","import","Trial",",","state_key",">",">",">","from","torchbearer.callbacks","import","TensorBoardImages",">",">",">","import","datetime",">",">",">","current_time","=","datetime.now","(",")",".strftime","(","'","%","b","%","d_","%","H-","%","M-","%","S","'",")",">",">",">","IMAGE_KEY","=","state_key","(","'image_key","'",")",">",">",">","#","Callback","that","will","log","to","tensorboard","under","``","(","model","name",")","_","(","current","time",")","''",">",">",">","tb","=","TensorBoardImages","(","comment=current_time",",","name='test_image","'",",","key=IMAGE_KEY",")",">",">",">","#","Trial","that","will","run","log","to","tensorboard","images","stored","under","IMAGE_KEY",">",">",">","t","=","Trial","(","None",",","callbacks=","[","tb","]",",","metrics=","[","'acc","'",",","'loss","'","]",")","Args",":","log_dir","(","str",")",":","The","tensorboard","log","path","for","output","comment","(","str",")",":","Descriptive","comment","to","append","to","path","name","(","str",")",":","The","name","of","the","image","key","(","StateKey",")",":","The","key","in","state","containing","image","data","(","tensor","of","size","[","c",",","w",",","h","]","or","[","b",",","c",",","w",",","h","]",")","write_each_epoch","(","bool",")",":","If","True",",","write","data","on","every","epoch",",","else","write","only","for","the","first","epoch",".","num_images","(","int",")",":","The","number","of","images","to","write","nrow",":","See","`","torchvision.utils.make_grid","<","https",":","\/\/pytorch.org\/docs\/stable\/torchvision\/utils.html","#","torchvision.utils.make_grid",">","`","_","padding",":","See","`","torchvision.utils.make_grid","<","https",":","\/\/pytorch.org\/docs\/stable\/torchvision\/utils.html","#","torchvision.utils.make_grid",">","`","_","normalize",":","See","`","torchvision.utils.make_grid","<","https",":","\/\/pytorch.org\/docs\/stable\/torchvision\/utils.html","#","torchvision.utils.make_grid",">","`","_","norm_range",":","See","`","torchvision.utils.make_grid","<","https",":","\/\/pytorch.org\/docs\/stable\/torchvision\/utils.html","#","torchvision.utils.make_grid",">","`","_","scale_each",":","See","`","torchvision.utils.make_grid","<","https",":","\/\/pytorch.org\/docs\/stable\/torchvision\/utils.html","#","torchvision.utils.make_grid",">","`","_","pad_value",":","See","`","torchvision.utils.make_grid","<","https",":","\/\/pytorch.org\/docs\/stable\/torchvision\/utils.html","#","torchvision.utils.make_grid",">","`","_","visdom","(","bool",")",":","If","true",",","log","to","visdom","instead","of","tensorboard","visdom_params","(","VisdomParams",")",":","Visdom","parameter","settings","object",",","uses","default","if","None","State","Requirements",":","-",":","attr",":","`","torchbearer.state.EPOCH","`",":","State","should","have","the","current","epoch","stored","-","`","key","`",":","State","should","have","images","stored","under","the","given","state","key"]
code: def __init__(
      self,
      log_dir="./logs",
      comment="torchbearer",
      name="Image",
      key=torchbearer.Y_PRED,
      write_each_epoch=True,
      num_images=16,
      nrow=8,
      padding=2,
      normalize=False,
      norm_range=None,
      scale_each=False,
      pad_value=0,
      visdom=False,
      visdom_params=None,
  ):
      super(TensorBoardImages, self).__init__(
          log_dir, comment, visdom=visdom, visdom_params=visdom_params
      )
      self.name = name
      self.key = key
      self.write_each_epoch = write_each_epoch
      self.num_images = num_images
      self.nrow = nrow
      self.padding = padding
      self.normalize = normalize
      self.norm_range = norm_range
      self.scale_each = scale_each
      self.pad_value = pad_value
  
      self._data = None
      self.done = False
  
imports: import copy
  import os
  import warnings
  import torch
  import torch.nn.functional
  import torchbearer
  from torchbearer.callbacks import Callback
label_desc: Use image node_id 1 to create a new TensorBoardImages object from inherited base classes: AbstractTensorBoard with example: obj = TensorBoardImages(log_dir, comment, name, key, write_each_epoch, num_images, nrow, padding, normalize, norm_range, scale_each, pad_value, visdom, visdom_params)