TensorBoard: Graph Visualization

TensorFlow计算图功能强大但复杂。 图表可视化可以帮助您理解和调试它们。 这是可视化工作的一个例子。

Visualization of a TensorFlow graph 可视化TensorFlow图形。

要查看您自己的图形,请运行TensorBoard将其指向作业的日志目录,单击顶部窗格上的图形选项卡,然后使用左上角的菜单选择适当的运行。 有关如何运行TensorBoard并确保记录所有必要信息的深入信息,请参阅TensorBoard:可视化学习

Name scoping and nodes

典型的TensorFlow图可以有成千上万个节点 - 太多了,无法一次轻松查看,甚至无法使用标准图形工具进行布局。 为了简化,变量名称可以作用域,可视化使用这些信息来定义图形节点上的层次结构。 默认情况下,仅显示此层次结构的顶部。 Here is an example that defines three operations under the hidden name scope using tf.name_scope:

import tensorflow as tf

with tf.name_scope('hidden') as scope:
  a = tf.constant(5, name='alpha')
  W = tf.Variable(tf.random_uniform([1, 2], -1.0, 1.0), name='weights')
  b = tf.Variable(tf.zeros([1]), name='biases')

这导致了以下三个op名称:

默认情况下,可视化文件将全部折叠为标记为隐藏的节点。 额外的细节不会丢失。 您可以双击或点击右上角的橙色+标志展开节点,然后您会看到alpha的三个子节点,权重偏差

这是一个在其初始和扩展状态下更复杂的节点的真实例子。

Unexpanded name scope Expanded name scope
顶级名称范围pool_1的初始视图。 单击右上角的橙色+按钮或双击节点本身将展开它。 展开pool_1名称范围的视图。 点击右上角的橙色 - 按钮或双击节点本身将折叠名称范围。

按名称范围对节点进行分组对于制作清晰的图形至关重要。 如果您正在构建模型,则名称范围可让您控制生成的可视化。 你的名字范围越好,你的可视化就越好。

上图说明了可视化的第二个方面。 TensorFlow图有两种连接:数据依赖性和控制依赖性。 数据依赖关系显示两个操作符之间的张量流,并显示为实线箭头,而控制依赖关系使用虚线。 在扩展视图(上图右侧)中,除了连接CheckNumericscontrol_dependency的虚线外,所有连接都是数据依赖关系。

还有一个简化布局的技巧。 大多数TensorFlow图有几个与其他节点有很多连接的节点。 例如,许多节点可能对初始化步骤具有控制依赖性。 绘制init节点及其依赖关系之间的所有边将创建一个非常混乱的视图。

为了减少混乱,可视化将所有高度节点分隔到右侧的辅助区域,并且不绘制线条来表示它们的边缘。 我们绘制小节点图标来代替连线。 分离出辅助节点通常不会删除关键信息,因为这些节点通常与簿记功能相关。 有关如何在主图表和辅助区域之间移动节点,请参阅交互

conv_1 is part of the main graph save is extracted as auxiliary node
节点conv_1已连接到save 请注意右侧的save节点图标。 save具有较高的程度,并且会显示为辅助节点。 conv_1的连接在其左侧显示为一个节点图标。 为了进一步减少混乱,由于save有很多连接,我们显示前5个并将其他缩写为... 12 more

最后的结构简化是系列崩溃 顺序图案 - 也就是说,名称相差最后一个数字并具有同构结构的节点 - 会折叠成一个节点的单个堆栈,如下所示。 对于长序列的网络,这大大简化了视图。 与分层节点一样,双击可扩展该系列。 有关如何为特定节点集禁用/启用系列折叠,请参见Interaction

Sequence of nodes Expanded sequence of nodes
节点序列的折叠视图。 双击后展开的视图的一小部分。

最后,作为易读性的最后一个帮助,可视化对常量和汇总节点使用特殊图标。 总而言之,下面是一个节点符号表:

符号 含义
Name scope 表示名称范围的高级节点。 双击以展开高级节点。
Sequence of unconnected nodes 没有相互连接的编号节点序列。
Sequence of connected nodes 相互连接的编号节点序列。
Operation node 一个单独的操作节点。
Constant node 一个常数。
Summary node 摘要节点。
Data flow edge 边缘显示操作之间的数据流。
Control dependency edge 边缘显示操作之间的控制依赖关系。
Reference edge 显示传出操作节点可以改变传入张量的参考边沿。

Interaction

通过平移和缩放浏览图形。 点击并拖动以平移,并使用滚动手势进行缩放。 双击某个节点,或者单击其+按钮,展开一个代表一组操作的名称范围。 为了在放大和平移时轻松跟踪当前视点,右下角会有一个小地图。

要关闭打开的节点,请再次双击它或单击其 - 按钮。 您也可以单击一次以选择一个节点。 它会变成较暗的颜色,并且关于它的详细信息及其连接的节点将显示在可视化对象右上角的信息卡中。

Info card of a name scope Info card of operation node
信息卡显示conv2名称范围的详细信息。 输入和输出由名称范围内的操作节点的输入和输出组合而成。 对于名称范围,不显示任何属性。 信息卡显示DecodeRaw操作节点的详细信息。 除输入和输出外,卡片还显示设备和与当前操作相关的属性。

TensorBoard提供了几种方法来改变图形的视觉布局。 这不会改变图的计算语义,但它可以为网络的结构带来一些清晰。 通过右键单击某个节点或按该节点信息卡底部的按钮,可以对其布局进行以下更改:

选择对于理解高度节点也很有帮助。 选择任何高度节点,并且其他连接的相应节点图标也将被选中。 例如,这可以很容易地查看哪些节点正在保存 - 哪些不是。

单击信息卡中的节点名称将选中它。 如有必要,视点将自动平移,以便节点可见。

最后,您可以使用图例上方的颜色菜单为图形选择两种配色方案。 默认的结构视图显示了结构:当两个高层节点具有相同的结构时,它们显示为与彩虹相同的颜色。 结构独特的节点是灰色的。 还有第二个视图,它显示了不同操作运行的设备。 名称范围与其内部操作的设备比例成比例地着色。

下面的图片给出了一张真实生活图的插图。

Color by structure Color by device
结构视图:灰色节点具有独特的结构。 橙色的conv1conv2节点具有相同的结构,类似于其他颜色的节点。 设备视图:名称范围与其内部操作节点的设备比例成比例地着色。 在这里,紫色代表GPU,绿色代表CPU。

Tensor shape information

当序列化的GraphDef包含张量形状时,图形可视化器会将张量标注为张量维度,并且边缘厚度会反映总张量大小。 若要在GraphDef中包含张量形状,则在序列化图形时将实际图形对象(如sess.graph)传递给FileWriter 下面的图片显示了具有张量形状信息的CIFAR-10模型:
CIFAR-10 model with tensor shape information
具有张量形状信息的CIFAR-10模型。

Runtime statistics

通常为运行收集运行时元数据非常有用,例如总内存使用量,总计算时间和节点的张量形状。 下面的代码示例是修改简单MNIST教程的训练和测试部分的一个片段,其中我们记录了摘要和运行时统计信息。 有关如何记录汇总的详细信息,请参阅汇总教程 完整的源代码在这里

  # Train the model, and also write summaries.
  # Every 10th step, measure test-set accuracy, and write test summaries
  # All other steps, run train_step on training data, & add training summaries

  def feed_dict(train):
    """Make a TensorFlow feed_dict: maps data onto Tensor placeholders."""
    if train or FLAGS.fake_data:
      xs, ys = mnist.train.next_batch(100, fake_data=FLAGS.fake_data)
      k = FLAGS.dropout
    else:
      xs, ys = mnist.test.images, mnist.test.labels
      k = 1.0
    return {x: xs, y_: ys, keep_prob: k}

  for i in range(FLAGS.max_steps):
    if i % 10 == 0:  # Record summaries and test-set accuracy
      summary, acc = sess.run([merged, accuracy], feed_dict=feed_dict(False))
      test_writer.add_summary(summary, i)
      print('Accuracy at step %s: %s' % (i, acc))
    else:  # Record train set summaries, and train
      if i % 100 == 99:  # Record execution stats
        run_options = tf.RunOptions(trace_level=tf.RunOptions.FULL_TRACE)
        run_metadata = tf.RunMetadata()
        summary, _ = sess.run([merged, train_step],
                              feed_dict=feed_dict(True),
                              options=run_options,
                              run_metadata=run_metadata)
        train_writer.add_run_metadata(run_metadata, 'step%d' % i)
        train_writer.add_summary(summary, i)
        print('Adding run metadata for', i)
      else:  # Record a summary
        summary, _ = sess.run([merged, train_step], feed_dict=feed_dict(True))
        train_writer.add_summary(summary, i)

此代码将为从步骤99开始的每第100步发出运行时统计信息。

当启动tensorboard并转到图表选项卡时,您现在将在“会话运行”下看到与添加运行元数据的步骤相对应的选项。 选择其中一个运行将显示该步骤中的网络快照,淡出未使用的节点。 在左侧的控件中,您将能够通过总内存或总计算时间为节点着色。 此外,单击节点将显示确切的总内存,计算时间和张量输出大小。

Color by compute time Run metadata graph Run metadata info card