QBoard » Artificial Intelligence & ML » AI and ML - Tensorflow » TensorBoard - Plot training and validation losses on the same graph?

TensorBoard - Plot training and validation losses on the same graph?

  • Is there a way to plot both the training losses and validation losses on the same graph?

    It's easy to have two separate scalar summaries for each of them individually, but this puts them on separate graphs. If both are displayed in the same graph it's much easier to see the gap between them and whether or not they have begin to diverge due to overfitting.

    Is there a built in way to do this? If not, a work around way? Thank you much!

      September 1, 2020 5:24 PM IST
    0
  • The work-around I have been doing is to use two SummaryWriter with different log dir for training set and cross-validation set respectively. And you will see something like this:


      September 1, 2020 5:40 PM IST
    1
    • Laksh Nath
      Laksh Nath @Mitali Bhavsar Thanks! I had thought this approach might work, but hadn't tried it yet. Of course, this makes comparing runs along with validations more tedious/messy, but at least it's an option. I'll leave the question open for now though so hopefully...  more
      September 2, 2020
    • Mitali Bhavsar
      Mitali Bhavsar @Laksh Nath Sure, Wait for your good news.. BTW, as for the comparisons among runs as well as validations, I don't think it's a problem however, since you can just save them to "run1/train", "run2/train", "run1/validation",...  more
      September 2, 2020
  • Rather than displaying the two lines separately, you can instead plot the difference between validation and training losses as its own scalar summary to track the divergence.

    This doesn't give as much information on a single plot (compared with adding two summaries), but it helps with being able to compare multiple runs (and not adding multiple summaries per run).

      September 2, 2020 12:10 PM IST
    0
  • For completeness, since tensorboard 1.5.0 this is now possible.

    You can use the custom scalars plugin. For this, you need to first make tensorboard layout configuration and write it to the event file. From the tensorboard example:

    import tensorflow as tf
    from tensorboard import summary
    from tensorboard.plugins.custom_scalar import layout_pb2
    
    # The layout has to be specified and written only once, not at every step
    
    layout_summary = summary.custom_scalar_pb(layout_pb2.Layout(
      category=[
        layout_pb2.Category(
          title='losses',
          chart=[
              layout_pb2.Chart(
                  title='losses',
                  multiline=layout_pb2.MultilineChartContent(
                    tag=[r'loss.*'],
                  )),
              layout_pb2.Chart(
                  title='baz',
                  margin=layout_pb2.MarginChartContent(
                    series=[
                      layout_pb2.MarginChartContent.Series(
                        value='loss/baz/scalar_summary',
                        lower='baz_lower/baz/scalar_summary',
                        upper='baz_upper/baz/scalar_summary'),
                    ],
                  )), 
          ]),
        layout_pb2.Category(
          title='trig functions',
          chart=[
              layout_pb2.Chart(
                  title='wave trig functions',
                  multiline=layout_pb2.MultilineChartContent(
                    tag=[r'trigFunctions/cosine', r'trigFunctions/sine'],
                  )),
              # The range of tangent is different. Let's give it its own chart.
              layout_pb2.Chart(
                  title='tan',
                  multiline=layout_pb2.MultilineChartContent(
                    tag=[r'trigFunctions/tangent'],
                  )),
          ],
          # This category we care less about. Let's make it initially closed.
          closed=True),
      ]))
    
    writer = tf.summary.FileWriter(".")
    writer.add_summary(layout_summary)
    # ...
    # Add any summary data you want to the file
    # ...
    writer.close()


    A Category is group of Charts. Each Chart corresponds to a single plot which displays several scalars together. The Chart can plot simple scalars (MultilineChartContent) or filled areas (MarginChartContent, e.g. when you want to plot the deviation of some value). The tag member of MultilineChartContent must be a list of regex-es which match the tags of the scalars that you want to group in the Chart. For more details check the proto definitions of the objects in https://github.com/tensorflow/tensorboard/blob/master/tensorboard/plugins/custom_scalar/layout.proto. Note that if you have several FileWriters writing to the same directory, you need to write the layout in only one of the files. Writing it to a separate file also works.

    To view the data in TensorBoard, you need to open the Custom Scalars tab. Here is an example image of what to expect https://user-images.githubusercontent.com/4221553/32865784-840edf52-ca19-11e7-88bc-1806b1243e0d.png

      September 2, 2020 2:23 PM IST
    0
  • Here is an example, creating two tf.summary.FileWriters which share the same root directory. Creating a tf.summary.scalar shared by the two tf.summary.FileWriters. At every time step, get the summary and update each tf.summary.FileWriter.

    import os
    
    import tqdm
    import tensorflow as tf
    
    
    def tb_test():
        sess = tf.Session()
    
        x = tf.placeholder(dtype=tf.float32)
        summary = tf.summary.scalar('Values', x)
        merged = tf.summary.merge_all()
    
        sess.run(tf.global_variables_initializer())
    
        writer_1 = tf.summary.FileWriter(os.path.join('tb_summary', 'train'))
        writer_2 = tf.summary.FileWriter(os.path.join('tb_summary', 'eval'))
    
        for i in tqdm.tqdm(range(200)):
            # train
            summary_1 = sess.run(merged, feed_dict={x: i-10})
            writer_1.add_summary(summary_1, i)
            # eval
            summary_2 = sess.run(merged, feed_dict={x: i+10})            
            writer_2.add_summary(summary_2, i)
    
        writer_1.close()
        writer_2.close()
    
    
    if __name__ == '__main__':
        tb_test()​

    Here is the result:



    The orange line shows the result of the evaluation stage, and correspondingly, the blue line illustrates the data of the training stage.

      September 2, 2020 3:17 PM IST
    0