[FIXED] Merging 2 plots in TensorBoard 2 with TensorFlow 2

Issue

I would like to merge on the same plot both the precision and recall using Tensorflow and tensorboard V2. I found many examples for the previous versions, but none of them is working in my case.

I have created a Keras callback that calculates the precision and recall, then I call a tensorflow summary to log them in the same logger. I can visualize them in Tensorboard, but in 2 separated plots.

Class ClassificationReport(Callback):
    def __init__(self, data_generator, steps, label_names, log_directory):
        """
        Instantiator
        :param data_generator: the data generator that produces the input data
        :param steps: int, batch size
        :param data_type, string, 'training', 'validation' or 'test', used a prefix in the logs
        :param log_directory: pathlib2 path to the TensorBoard log directory

        """

        self.data_generator = data_generator
        self.steps = steps
        self.data_type = data_type
        self.logger = tensorflow.summary.create_file_writer(str(log_directory / self.data_type))

        # names of the scalar to consider in the sklearn classification report
        self._scalar_names = ['precision', 'recall']

    def on_epoch_end(self, epoch, logs={}):
        """
        log the precision and recall

        :param epoch: int, number of epochs
        :param logs: the Keras dictionary where the metrics are stored
        """

        y_true = numpy.zeros(self.steps)
        y_predicted = numpy.zeros(self.steps)

       ...Here I fetch y_true and y_predicted with the data_generator

        # The current report is calculated by SciKit-Learn
        current_report = classification_report(y_true, y_predicted, output_dict=True)

        with self.logger.as_default():
            for scalar_name in self._scalar_names:
                tensorflow.summary.scalar(
                    name="{} / macro average / {}".format(self.data_type, scalar_name),
                    data=current_report['macro avg'][scalar_name],
                    step=epoch)

        return super().on_epoch_end(epoch, logs)

As far as I understant the Tensorboard 2 logic, it doesn’t seem to be possible to plot 2 scalar summaries on the same plot… Any advice is welcomed at this stage.

Solution

Use two different writers with the same scalar summary name.

import numpy as np
import tensorflow as tf

logger1 = tf.summary.create_file_writer('logs/scalar/precision')
logger2 = tf.summary.create_file_writer('logs/scalar/recall')

precision = np.random.uniform(size=10)
recall = np.random.uniform(size=10)

for i in range(10):
    with logger1.as_default():
        tf.summary.scalar(name='precision-recall', data=precision[i], step=i)
    with logger2.as_default():
        tf.summary.scalar(name='precision-recall', data=recall[i], step=i)

tensorboard –logdir logs/scalar

enter image description here

From this answer, adapted for tf2: https://stackoverflow.com/a/38718948/5597718

Answered By – Manoj Mohan

Answer Checked By – Cary Denson (Easybugfix Admin)

Leave a Reply

(*) Required, Your email will not be published