小白学Tensorflow之TensorBoard
小白学Tensorflow之TensorBoard
AllenOR灵感 发表于5个月前
小白学Tensorflow之TensorBoard
  • 发表于 5个月前
  • 阅读 4
  • 收藏 0
  • 点赞 0
  • 评论 0

新睿云服务器60天免费使用,快来体验!>>>   

TensorBoard 的可视化工具可以帮助你更加方便的理解、调试与优化 TensorFlow 程序。你可以使用 TensorBoard 来展示你的 TensorFlow 图像,绘制图像生成的定量指标图以及附加数据。

当 TensorBoard 设置完成后,它应该是这样子的:


TensorBoard 通过读取 TensorFlow 的时间文件来运行。TensorFlow 的时间文件包括了你会在 TensorFlow 运行中涉及到的主要数据。下面是 TensorBoard 中汇总数据(Summary data)的大体生命周期。

首先,创建你想汇总数据的 TensorFlow 图,然后再选择你想在哪个节点进行汇总(summary)操作。

比如,假设你正在训练一个卷积神经网络,用于识别 MNIST 标签。你可能希望记录学习速率(learning rate)的如何变化,以及目标函数如何变化。也就是说,记录一些单个的数值,零维的标量。我们可以通过向节点附加 scalar_summary 操作来分别输出学习速度和期望误差。然后你可以给每个 scalary_summary 分配一个有意义的 标签,比如 learning rateloss function ,如下代码所示:

with tf.name_scope("loss_function"):
  cost = tf.reduce_mean(tf.pow(y - pred, 2))
  tf.scalar_summary('loss_function', cost)

或者你还希望显示一个特殊层中激活的分布,或者梯度权重的分布,各层网络权重,偏置的分布等。可以通过分别附加histogram_summary 运算来手机权重变量和梯度输出。如下代码所示:

W = tf.Variable(tf.zeros([784, 10]), name = "weights")
b = tf.Variable(tf.zeros([10]), name = "bias")
w_hist = tf.histogram_summary("weights", W)
b_hist = tf.histogram_summary("biases", b)

在 TensorFlow 中,所有的操作只有当你执行,或者另一个操作依赖于它的输出时才会运行。我们刚才创建的这些节点(summary nodes)都围绕着你的图像:没有任何操作依赖于它们的结果。因此,为了生成汇总信息,我们需要运行所有这些节点。这样的手动工作是很乏味的,因此可以使用 tf.merge_all_summaries 来将他们合并为一个操作。

然后你可以执行合并命令,它会依据特点步骤将所有数据生成一个序列化的 Summary protobuf 对象。最后,为了阿静汇总数据写入磁盘,需要将汇总的 protobuf 对象传递给 tf.train.Summarywriter 。

SummaryWriter 的构造函数中包含了参数 logdir 。这个 logdir 非常重要,所有事件都会写到它所指的目录下。此外,SummaryWriter 中还包含了一个可选择的参数 GraphDef 。如果输入了该参数,那么 TensorBoard 也会显示你的图像。如下代码所示:

merged = tf.merge_all_summaries()
writer = tf.train.SummaryWriter("/tmp/mnist_logs", sess.graph_def)

现在已经修改了你的图,也有了 SummaryWriter ,现在就可以运行你的神经网络了!如果你愿意的话,你可以没执行一步然后就执行一次合并汇总,这样你会得到一大堆训练数据。这很有可能超过了你想要的数据量。你也可以每一百步执行一次合并汇总,后者如下面代码里示范的这样:

merged_summary_op = tf.merge_all_summaries()
summary_writer = tf.train.SummaryWriter('/tmp/mnist_logs', sess.graph)
total_step = 0
while training:
  total_step += 1
  session.run(training_op)
  if total_step % 100 == 0:
    summary_str = session.run(merged_summary_op)
    summary_writer.add_summary(summary_str, total_step)

现在已经准备好用 TensorBoard 来可视化这些数据了。

那么我们怎么启动 TensorBoard 呢?可以输入下面的指令来启动 TensorBoard :

python tensorflow/tensorboard/tensorboard.py --logdir=path/to/log-directory

这里的参数 logdir 指向 SummaryWriter 序列化数据的存储路径。如果 logdir 目录的子目录中包含另一次运行时的数据,那么 TensorBoard 会展示所有运行的数据。一旦 TensorBoard 开始运行,你可以通过在浏览器中输入 localhost:6006 来查看 TensorBoard 。

但如果你是通过 pip 安装了 Tensorflow,那么你可以通过执行更为简单的明亮来访问 TensorBoard ,如下:

tensorboard --logdir=/path/to/log-directory

进入 TensorBoard 的界面时,你会在右上角看到导航选项卡,每一个选项卡将展现一组可视化的序列化数据集 。对于你查看的每一个选项卡,如果 TensorBoard 中没有数据与这个选项卡相关的话,则会显示一条提示信息指示你如何序列化相关数据。

接下来,我们谈谈名称域(Name scoping)和节点(Node)。

典型的 TensorFlow 可以有数以千计的节点,如此多而难以一下全部看到,甚至无法使用标准图表工具来展示。为简单起见,我们为变量名划定范围,并且可视化把该信息用于在图表中的节点上定义一个层级。默认情况下, 只有顶层节点会显示。下面这个例子使用 tf.name_scope 在 hidden 命名域下定义了三个操作:

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

结果是得到了下面是三个操作名:

  • hidden/alpha
  • hidden/weights
  • hidden/biases

默认地,三个操作名会折叠为一个节点并标注为 hidden 。其额外细节并没有丢失,你可以双击,或点击右上方橙色的 + 来展开节点,然后就会看到三个子节点 alphaweightsbiases了。

这有一个生动的例子,例中有一个更复杂的节点,节点处于其初始和展开状态。


通过名称域把节点分组来得到可读性高的图表很关键的。如果你在构建一个模型,名称域就可以用来控制可视化结果。你的名称域越好,可视性就越好。

上面的图像例子说明了可视化的另一方面, TensorFlow 图表有两种连接关系:数据依赖和控制依赖。数据依赖显示两个操作之间的tensor流程,用实心箭头指示,而控制依赖用点线表示。在已展开的视图(上面的右图)中,除了用点线连接的CheckNumericscontrol_dependency 之外,所有连接都是数据依赖的。

至此,你已经学完了基本的 TensorBoard ,而且可以读懂图的意思了。

实验代码如下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import tensorflow as tf 
import numpy as np 
import input_data


mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
sess = tf.InteractiveSession()

# create the model
# name -> the graph representation
x = tf.placeholder(tf.float32, [None, 784], name = "x-input")
W = tf.Variable(tf.zeros([784, 10]), name = "weights")
b = tf.Variable(tf.zeros([10]), name = "bias")

# use a name_scope to organize nodes in the graph visualizer
# tf.name_scope -> the graph representation
with tf.name_scope("Wx_b") as scope:
    y = tf.nn.softmax(tf.matmul(x, W) + b)

# add summary ops to collect data
# historam summary
w_hist = tf.histogram_summary("weights", W)
b_hist = tf.histogram_summary("biases", b)
y_hist = tf.histogram_summary("y", y)

# define loss and optimizer
y_ = tf.placeholder(tf.float32, [None, 10], name = "y-input")

# more name scopes will clean up the graph representation
with tf.name_scope("xent") as scoep:
    cross_entropy = -tf.reduce_sum(y_ * tf.log(y))
    ce_sum = tf.scalar_summary("cross entropy", cross_entropy)

with tf.name_scope("train") as scope:
    train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)

with tf.name_scope("test") as scope:
    correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
    accuracy_summary = tf.scalar_summary("accuracy", accuracy)

# merge all the summaries and write them out to /tmp/mnist_logs
merged = tf.merge_all_summaries()
writer = tf.train.SummaryWriter("/tmp/mnist_logs", sess.graph_def)
tf.initialize_all_variables().run()

# train the model, and feed in test data and reord summaries every 10 steps
for i in xrange(100):
    if i % 10 == 0:
        feed = {x: mnist.test.images, y_: mnist.test.labels}
        result = sess.run([merged, accuracy], feed_dict = feed)
        summary_str = result[0]
        acc = result[1]
        writer.add_summary(summary_str, i)
        print i, acc
    else:
        batch_xs, batch_ys = mnist.train.next_batch(100)
        feed = {x: batch_xs, y_: batch_ys}
        sess.run(train_step, feed_dict = feed)
print accuracy.eval({x: mnist.test.images, y_: mnist.test.labels})

TensorBoard 图如下:





Reference:

极客学院

  • 打赏
  • 点赞
  • 收藏
  • 分享
共有 人打赏支持
粉丝 6
博文 2139
码字总数 82983
×
AllenOR灵感
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: