I'm working on a segmentation problem in Keras and I want to display segmentation results at the end of every training epoch.
I want something similar to Tensorflow: How to Display Custom Images in Tensorboard (e.g. Matplotlib Plots), but using Keras. I know that Keras has the TensorBoard callback but it seems limited for this purpose.
I know this would break the Keras backend abstraction, but I'm interested in using TensorFlow backend anyway.
Is it possible to achieve that with Keras + TensorFlow?
Using TensorBoard with Keras Model. Place the logs in a timestamped subdirectory to allow easy selection of different training runs. Start TensorBoard through the command line or within a notebook experience. The two interfaces are generally the same. In notebooks, use the %tensorboard line magic.
So, the following solution works well for me:
import tensorflow as tf def make_image(tensor): """ Convert an numpy representation image to Image protobuf. Copied from https://github.com/lanpa/tensorboard-pytorch/ """ from PIL import Image height, width, channel = tensor.shape image = Image.fromarray(tensor) import io output = io.BytesIO() image.save(output, format='PNG') image_string = output.getvalue() output.close() return tf.Summary.Image(height=height, width=width, colorspace=channel, encoded_image_string=image_string) class TensorBoardImage(keras.callbacks.Callback): def __init__(self, tag): super().__init__() self.tag = tag def on_epoch_end(self, epoch, logs={}): # Load image img = data.astronaut() # Do something to the image img = (255 * skimage.util.random_noise(img)).astype('uint8') image = make_image(img) summary = tf.Summary(value=[tf.Summary.Value(tag=self.tag, image=image)]) writer = tf.summary.FileWriter('./logs') writer.add_summary(summary, epoch) writer.close() return tbi_callback = TensorBoardImage('Image Example') Just pass the callback to fit or fit_generator.
Note that you can also run some operations using the model inside the callback. For example, you may run the model on some images to check its performance.
![]()
Based on the above answers and my own searching, I provide the following code to finish the following things using TensorBoard in Keras:
x and ground truth disparity map gt;x and ground truth 'gt', at some iteration time;y of your model, at some iteration time.First of all, you have to make your costumed callback class with Callback. Note that a callback has access to its associated model through the class property self.model. Also Note: you have to feed the input to the model with feed_dict, if you want to get and display the output of your model.
from keras.callbacks import Callback import numpy as np from keras import backend as K import tensorflow as tf import cv2 # make the 1 channel input image or disparity map look good within this color map. This function is not necessary for this Tensorboard problem shown as above. Just a function used in my own research project. def colormap_jet(img): return cv2.cvtColor(cv2.applyColorMap(np.uint8(img), 2), cv2.COLOR_BGR2RGB) class customModelCheckpoint(Callback): def __init__(self, log_dir='./logs/tmp/', feed_inputs_display=None): super(customModelCheckpoint, self).__init__() self.seen = 0 self.feed_inputs_display = feed_inputs_display self.writer = tf.summary.FileWriter(log_dir) # this function will return the feeding data for TensorBoard visualization; # arguments: # * feed_input_display : [(input_yourModelNeed, left_image, disparity_gt ), ..., (input_yourModelNeed, left_image, disparity_gt), ...], i.e., the list of tuples of Numpy Arrays what your model needs as input and what you want to display using TensorBoard. Note: you have to feed the input to the model with feed_dict, if you want to get and display the output of your model. def custom_set_feed_input_to_display(self, feed_inputs_display): self.feed_inputs_display = feed_inputs_display # copied from the above answers; def make_image(self, numpy_img): from PIL import Image height, width, channel = numpy_img.shape image = Image.fromarray(numpy_img) import io output = io.BytesIO() image.save(output, format='PNG') image_string = output.getvalue() output.close() return tf.Summary.Image(height=height, width=width, colorspace= channel, encoded_image_string=image_string) # A callback has access to its associated model through the class property self.model. def on_batch_end(self, batch, logs = None): logs = logs or {} self.seen += 1 if self.seen % 200 == 0: # every 200 iterations or batches, plot the costumed images using TensorBorad; summary_str = [] for i in range(len(self.feed_inputs_display)): feature, disp_gt, imgl = self.feed_inputs_display[i] disp_pred = np.squeeze(K.get_session().run(self.model.output, feed_dict = {self.model.input : feature}), axis = 0) #disp_pred = np.squeeze(self.model.predict_on_batch(feature), axis = 0) summary_str.append(tf.Summary.Value(tag= 'plot/img0/{}'.format(i), image= self.make_image( colormap_jet(imgl)))) # function colormap_jet(), defined above; summary_str.append(tf.Summary.Value(tag= 'plot/disp_gt/{}'.format(i), image= self.make_image( colormap_jet(disp_gt)))) summary_str.append(tf.Summary.Value(tag= 'plot/disp/{}'.format(i), image= self.make_image( colormap_jet(disp_pred)))) self.writer.add_summary(tf.Summary(value = summary_str), global_step =self.seen) Next, pass this callback object to fit_generator() for your model, like:
feed_inputs_4_display = some_function_you_wrote() callback_mc = customModelCheckpoint( log_dir = log_save_path, feed_inputd_display = feed_inputs_4_display) # or callback_mc.custom_set_feed_input_to_display(feed_inputs_4_display) yourModel.fit_generator(... callbacks = callback_mc) ... Now your can run the code, and go the TensorBoard host to see the costumed image display. For example, this is what I got using the aforementioned code: 
Done! Enjoy!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With