TensorFlow计算图功能强大但复杂。图表可视化可以帮助您理解和调试它们。这是一个可视化工作的例子:
可视化TensorFlow图形。
要查看您自己的图形,请运行TensorBoard并将其指向作业的日志目录,单击顶部窗格上的图形选项卡,然后使用左上角的菜单选择适当的运行。有关如何运行TensorBoard并确保记录的深入信息,请参阅TensorBoard:可视化学习。
命名范围和节点
典型的TensorFlow图可以有成千上万个节点 – 太多的节点很难一次看到,甚至无法使用标准的图形工具进行布局。为简化起见,变量名可以有作用域,可视化使用这些信息来定义图中节点上的层次结构。默认情况下,只显示该层次结构的顶部。下面是一个定义三个操作的例子:
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名称:
hidden/alpha
hidden/weights
hidden/biases
默认情况下,可视化将把所有三个都折叠成标记的节点hidden
。额外的细节不会丢失。你可以double-click,或点击右上角的橙色+
展开节点,然后您会看到三个子节点alpha
,weights
和biases
。
这是一个在初始和扩展状态下更复杂节点的例子。
top-level名称范围的初始视图pool_1 。点击右上角的橙色+ 按钮或者节点本身的double-clicking会将其展开。 |
展开的视图pool_1 名称范围。点击右上角的橙色- 按钮或节点上的double-clicking本身将折叠名称范围。 |
按名称范围对节点进行分组对于制作清晰的图形至关重要。如果您正在构建模型,则名称范围可以控制生成的可视化。你的名字范围越好,你的可视化就越好。
TensorFlow图有两种连接:数据依赖和控制依赖。数据依赖显示两个操作符之间的张量流,并显示为实线箭头,而控制依赖使用虚线。在展开的视图(上图右侧)中,除CheckNumerics
和control_dependency
是虚线连接外,所有连接均为数据依赖。
还有一个简化布局的技巧。大多数TensorFlow图有几个与其他节点连接的节点。例如,许多节点可能对初始化步骤具有控制依赖性。绘制init
节点及其依赖关系之间的所有边会造成非常混乱的视图。
为了减少混乱,可视化将所有high-degree节点分隔出来放到右侧的辅助区域,并不画线来表示它们的边,而是画小节点图标表示连接。分离出辅助节点通常不会去除关键信息,因为这些节点通常与记录函数相关。见交互:如何在主图和辅助区之间移动节点。
节点conv_1 连接到save 。注意在其右侧的save 节点图标。 |
save 具有很高的度,会作为辅助节点。跟conv_1 的连接在其左侧显示为一个节点图标。为了进一步减少混乱,因为save 有很多的连接,我们展示前5个,并缩写为其他... 12 more 。 |
最后一个结构简化是序列折叠。对于连续的图案 – 也就是说,名称在数量上有所不同,并且具有同构结构的节点 – 被折叠成一个堆节点,如下所示。对于长序列的网络,这大大简化了视图。与分层节点一样,double-clicking展开系列。见交互了解如何为特定的一组节点禁用/启用序列折叠。
节点序列的折叠视图。 | double-click之后的一小段扩展视图。 |
最后,作为易读性的最后一个帮助,可视化对常量和汇总节点使用特殊的图标。总结一下,下面是一个节点符号表:
符号 | 含义 |
---|---|
High-level代表名称范围的节点。 Double-click展开这个high-level节点。 | |
没有相互连接编号节点序列。 | |
有相互连接的编号节点序列。 | |
一个单独的操作节点。 | |
一个常数。 | |
摘要节点。 | |
边,表示操作之间的数据流。 | |
边,表示操作之间的控制依赖关系。 | |
引用边,表示传出操作节点可以改变传入张量。 |
交互
通过平移和缩放导航图形。点击拖动可以平移,使用滚动手势可以进行缩放。 Double-click一个节点,或者点击它的+
按钮,展开代表一组操作的名称范围。为了在放大和平移时轻松跟踪当前视点,右下角会有一个小Map。
要关闭一个打开的节点,double-click或再次点击它-
按钮。您也可以单击一次以选择一个节点。它会变成一个较深的颜色,关于它的详细信息以及它所连接的节点将出现在可视化对象右上角的信息卡中。
显示详细信息的信息卡conv2 名称范围。输入和输出由名称范围内的操作节点的输入和输出组合而成。对于名称范围,不显示任何属性。 |
显示详细信息的信息卡DecodeRaw 操作节点。除输入和输出外,卡片还显示设备和与当前操作相关的属性。 |
TensorBoard提供了几种方法来改变图形的视觉布局。这并不会改变图的计算语义,但它可以让网络的结构更清晰。通过右键单击某个节点或按该节点信息卡底部的按钮,可以对其布局进行以下更改:
- 节点可以在主图表和辅助区域之间移动。
- 可以将一系列节点取消分组,使得该系列中的节点不会出现在一起。未分组的系列也可以重新组合。
选择对于理解high-degree节点也是有帮助的。选择任何high-degree节点,其他连接的相应节点图标也将被选中。例如,这可以很容易地看到哪些节点正在保存,哪些不是。
点击信息卡中的节点名称将选择它。如有必要,视点将自动平移,以便节点可见。
最后,您可以使用图例上方的颜色菜单为图形选择两种配色方案。默认结构视图显示结构:当两个high-level节点具有相同的结构时,它们显示为与彩虹相同的颜色。结构独特的节点是灰色的。还有第二个视图,它显示了不同操作运行的设备。名称范的围着色比例与其内部操作的设备一致。
下面的图片给出了一张real-life图的图示。
结构视图:灰色节点具有独特的结构。橙色conv1 和conv2 节点具有相同的结构,类似于其他颜色的节点。 |
设备视图:名称范围与其内部操作节点的设备比例成比例。在这里,紫色是指GPU,绿色是CPU。 |
张量形状信息
当序列化的GraphDef
包括张量形状,那么图形可视化器使用张量维度来标记边,边宽度反映总张量大小。下面的图片显示了具有张量形状信息的CIFAR-10模型:
张量形状信息的CIFAR-10模型。 |
运行时统计
收集运行时元数据通常是非常有用的,例如内存使用总量,总计算时间和节点的张量形状。下面的代码示例是一个修改简单的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并转到Graph选项卡时,您将看到”Session runs”下的选项,这些选项对应于添加运行元数据的步骤。选择其中一个运行将显示在该步骤的网络快照,淡出未使用的节点。在左侧的控件中,您可以通过总内存或总计算时间对节点着色。此外,单击节点将显示确切的总内存、计算时间和张量输出大小。