Search code examples
pythontensorflowkerasrastertensorboard

TensorBoard: adding output image to callback


I built a network that attempts to predict raster images of surface temperatures. The output of the network is a (1000, 1000) size array, representing a raster image. For training and testing these are compared to the real raster of their respective samples. I understand how to add the training image to my TensorBoard callback but I'd like to also add the network's output image to the callback, so that I could compare them visually. Is this possible?

x = Input(shape = (2))
x = Dense(4)(x)
x = Reshape((2, 2))(x)

Where Reshape would be the last layer (or one before some deconvolution layer).


Solution

  • Depending on the tensorflow version you are using, I would have 2 different codes to suggest. I will assume you use > 2.0 and post the code I use for that version for image-to-image models. I basically initialize a callback with a noisy image (I am doing denoising but you can easily adapt to your problem), and the corresponding ground truth image. I then use the model to do the inference after each epoch.

    """Inspired by https://github.com/sicara/tf-explain/blob/master/tf_explain/callbacks/grad_cam.py"""
    import numpy as np
    import tensorflow as tf
    from tensorflow.keras.callbacks import Callback
    
    
    class TensorBoardImage(Callback):
        def __init__(self, log_dir, image, noisy_image):
            super().__init__()
            self.log_dir = log_dir
            self.image = image
            self.noisy_image = noisy_image
    
        def set_model(self, model):
            self.model = model
            self.writer = tf.summary.create_file_writer(self.log_dir, filename_suffix='images')
    
        def on_train_begin(self, _):
            self.write_image(self.image, 'Original Image', 0)
    
        def on_train_end(self, _):
            self.writer.close()
    
        def write_image(self, image, tag, epoch):
            image_to_write = np.copy(image)
            image_to_write -= image_to_write.min()
            image_to_write /= image_to_write.max()
            with self.writer.as_default():
                tf.summary.image(tag, image_to_write, step=epoch)
    
        def on_epoch_end(self, epoch, logs={}):
            denoised_image = self.model.predict_on_batch(self.noisy_image)
            self.write_image(denoised_image, 'Denoised Image', epoch)
    
    

    So typically you would use this the following way:

    # define the model
    model = Model(inputs, outputs)
    # define the callback
    image_tboard_cback = TensorBoardImage(
        log_dir=log_dir + '/images',
        image=val_gt[0:1],
        noisy_image=val_noisy[0:1],
    )
    # fit the model
    model.fit(
        x, 
        y, 
        callbacks=[image_tboard_cback,],
    )
    

    If you use versions prior to 2.0 I can direct to this gist I wrote (which is a bit more intricate).