TensorBoard-在同一张图上绘制训练和验证损失吗?
machine-learning
tensorboard
tensorflow
10
0

有没有办法在同一张图上同时绘制训练损失和验证损失?

分别有两个单独的标量摘要很容易,但这会将它们放在单独的图上。如果两者都显示在同一张图中,则更容易查看它们之间的间隙以及它们是否因过度拟合而开始发散。

有内置的方法可以做到这一点吗?如果没有,一种解决方法?非常感谢!

参考资料:
Stack Overflow
收藏
评论
共 4 个回答
高赞 时间 活跃

非常感谢niko提供了有关Custom Scalars的技巧。

我对官方的custom_scalar_demo.py感到困惑,因为发生了很多事情,在弄清楚它是如何工作之前,我不得不研究了一段时间。

为了确切显示为现有模型创建自定义标量图需要执行的操作,我整理了以下完整示例:

# + <
# We need these to make a custom protocol buffer to display custom scalars.
# See https://developers.google.com/protocol-buffers/
from tensorboard.plugins.custom_scalar import layout_pb2
from tensorboard.summary.v1 import custom_scalar_pb
#   > 
import tensorflow as tf
from time import time
import re

# Initial values
(x0, y0) = (-1, 1)

# This is useful only when re-running code (e.g. Jupyter).
tf.reset_default_graph()  

# Set up variables.
x = tf.Variable(x0, name="X", dtype=tf.float64)
y = tf.Variable(y0, name="Y", dtype=tf.float64)

# Define loss function and give it a name.
loss = tf.square(x - 3*y) + tf.square(x+y)
loss = tf.identity(loss, name='my_loss')

# Define the op for performing gradient descent.
minimize_step_op = tf.train.GradientDescentOptimizer(0.092).minimize(loss)

# List quantities to summarize in a dictionary 
# with (key, value) = (name, Tensor).
to_summarize = dict(
    X = x,
    Y_plus_2 = y + 2,
)

# Build scalar summaries corresponding to to_summarize.
# This should be done in a separate name scope to avoid name collisions
# between summaries and their respective tensors. The name scope also
# gives a title to a group of scalars in TensorBoard.
with tf.name_scope('scalar_summaries'):
    my_var_summary_op = tf.summary.merge(
        [tf.summary.scalar(name, var) 
            for name, var in to_summarize.items()
        ]
    )

# + <
# This constructs the layout for the custom scalar, and specifies
# which scalars to plot.
layout_summary = custom_scalar_pb(
    layout_pb2.Layout(category=[
        layout_pb2.Category(
            title='Custom scalar summary group',
            chart=[
                layout_pb2.Chart(
                    title='Custom scalar summary chart',
                    multiline=layout_pb2.MultilineChartContent(
                        # regex to select only summaries which 
                        # are in "scalar_summaries" name scope:
                        tag=[r'^scalar_summaries\/']
                    )
                )
            ])
    ])
)
#   >

# Create session.
with tf.Session() as sess:

    # Initialize session.
    sess.run(tf.global_variables_initializer())

    # Create writer.
    with tf.summary.FileWriter(f'./logs/session_{int(time())}') as writer:

        # Write the session graph.
        writer.add_graph(sess.graph) # (not necessary for scalars)

# + <
        # Define the layout for creating custom scalars in terms
        # of the scalars.
        writer.add_summary(layout_summary)
#   >

        # Main iteration loop.
        for i in range(50):
            current_summary = sess.run(my_var_summary_op)
            writer.add_summary(current_summary, global_step=i)
            writer.flush()
            sess.run(minimize_step_op)   

上面的代码由一个“原始模型”组成,并由三个代码块扩展,分别由

# + <
        [code to add custom scalars goes here]
#   >

我的“原始模型”具有以下标量:

在此处输入图片说明

和这个图:

在此处输入图片说明

我修改后的模型具有相同的标量和图形,以及以下自定义标量:

在此处输入图片说明

此自定义标量图只是将原始两个标量图组合在一起的布局。

不幸的是,由于两个值具有相同的颜色,因此难以读取生成的图形。 (它们仅通过标记来区分。)但是,这与TensorBoard的约定一致,即每个日志只有一种颜色。

说明

这个想法如下。您有一些要在单个图表中绘制的变量组。作为前提,TensorBoard应该在“ SCALARS”标题下分别绘制每个变量。 (这是通过为每个变量创建一个标量摘要,然后将这些摘要写入日志来完成的。此处无新内容。)

为了在同一张图表中绘制多个变量,我们告诉TensorBoard将这些摘要中的哪一个组合在一起。然后,将指定的摘要合并到“自定义标量”标题下的单个图表中。我们通过在日志开头写入一次“布局”来完成此操作。 TensorBoard收到布局后,将在更新“常规标量”时自动在“自定义标量”下生成组合图表。

假设您的“原始模型”已经将变量(作为标量摘要)发送到TensorBoard,则唯一必要的修改就是在主迭代循环开始之前注入布局。每个自定义标量图都通过正则表达式选择要绘制的摘要。因此,对于将要绘制在一起的每组变量,将变量的各自摘要放在单独的名称范围中可能很有用。 (这样,您的正则表达式可以简单地选择该名称范围下的所有摘要。)

重要说明:生成变量摘要的操作不同于变量本身。例如,如果我有一个变量ns1/my_var ,则可以创建一个摘要ns2/summary_op_for_myvar 。自定义标量图布局仅关心摘要操作, 而不关心原始变量的名称或范围。

收藏
评论

为了完整起见,从tensorboard 1.5.0开始,这是可能的。

您可以使用自定义标量插件。为此,您需要首先进行张量板布局配置并将其写入事件文件。从张量板示例中:

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()

CategoryChart的组。每个Chart对应一个图,该图一起显示多个标量。 Chart可以绘制简单标量( MultilineChartContent )或填充区域( MarginChartContent ,例如,当您要绘制某个值的偏差时)。 MultilineChartContenttag成员必须是与要在统计图中分组的标量的tag s匹配的正则表达式列表。有关更多详细信息,请检查https://github.com/tensorflow/tensorboard/blob/master/tensorboard/plugins/custom_scalar/layout.proto中对象的原型定义。请注意,如果您有多个FileWriter写入同一目录,则只需在一个文件中写入布局。将其写入单独的文件也可以。

要在TensorBoard中查看数据,您需要打开Custom Scalars选项卡。这是期望的示例图像https://user-images.githubusercontent.com/4221553/32865784-840edf52-ca19-11e7-88bc-1806b1243e0d.png

收藏
评论

我一直在解决的方法是分别使用两个具有不同日志目录的SummaryWriter分别用于训练集和交叉验证集。您将看到类似以下内容:

在此处输入图片说明

收藏
评论

您可以将验证损失和训练损失之间的差异作为其自己的标量摘要来绘制,而不必分别显示两条线,从而可以追踪差异。

这不会在单个图上提供太多信息(与添加两个摘要相比),但是有助于比较多个运行(而不是每次运行不添加多个摘要)。

收藏
评论
新手导航
  • 社区规范
  • 提出问题
  • 进行投票
  • 个人资料
  • 优化问题
  • 回答问题

关于我们

常见问题

内容许可

联系我们

@2020 AskGo
京ICP备20001863号