TensorFlow学习笔记(3)-TensorBoard学习笔记

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/kabuto_hui/article/details/86579290


  Tensorflow提供了一个可视化工具TensorBoard。TensorBoard可以有效的展示TensorFlow在运行过程中的计算图、各种指标随时间的变化趋势以及训练中使用到的图像等信息。

1. 命名空间

  在TensorFlow的默认视图中,TensorFlow计算图中同一个命名空间下的所有节点会被缩成一个节点,只有顶层命名空间中的节点才会被显示在TensorBoard的可视化效果图上。其中命名空间可以由两个函数来管理:tf.variable_scope()tf.name_scope()。两者的区别在tf.get_variable()的使用上。
tf.variable_scope()中:

with tf.variable_scope('foo'):
    a = tf.get_variable('a', [1])
    b = tf.get_variable('b', [1])
    print(a.name, b.name)

with tf.variable_scope('goo'):
    a = tf.get_variable('a', [1])
    b = tf.get_variable('b', [1])
    print(a.name, b.name)

通过tf.get_variable()函数可以获取名为a,b的变量,且在不同的命名空间下获取相同的变量并不冲突,因为他们 都会带上命名空间的前缀:

foo/a:0 foo/b:0
goo/a:0 goo/b:0

而在tf.name_scope()中:

with tf.name_scope('c'):
    a = tf.get_variable('a', [1])
    b = tf.get_variable('b', [1])
    print(a.name, b.name)

with tf.name_scope('d'):
    a = tf.get_variable('a', [1])
    b = tf.get_variable('b', [1])
    print(a.name, b.name)

则会报错:

ValueError: Variable a already exists, disallowed. Did you mean to set reuse=True or reuse=tf.AUTO_REUSE in VarScope?

所以不能在tf.name_scope()管理的命名空间下使用tf.name_scope()获取相同的名称的变量。除此之外,其余的功能都差不多。

2. 如何开启TensorBoard

  我们想要在TensorBoard中查看我们建立的模型结构图。首先我们需要先定义一个图,然后生成这个图,最后开启服务。如下所示:

import tensorflow as tf
# 定义变量
with tf.name_scope('a'):
    a = tf.Variable([1., 2.], dtype=tf.float32, name='a-variable')
with tf.name_scope('b'):
    b = tf.Variable([3., 4.], dtype=tf.float32, name='b-variable')
# 定义操作
with tf.name_scope('a_add_b'):
    result = a + b
# 初始化变量
op_init = tf.global_variables_initializer()
# 开启会话
with tf.Session() as sess:
    writer = tf.summary.FileWriter('logs/', sess.graph)
    sess.run(op_init)
    sess.run(result)

从上面的代码可以看出,我们对于每个我们关注的变量也好、操作也好,我们把他们放到了一个命名空间下面,这就相当于把他们装进了一个“盒子”中,最后在TensorBoard中呈现出来的就是这些“盒子”之间的一个”流程图“。所以在上面的代码中,我们猜测图应该会是盒子a与盒子b输入到盒子a_add_b中。
**生成图最关键的步骤: **

扫描二维码关注公众号,回复: 5181705 查看本文章
writer = tf.summary.FileWriter('logs/', sess.graph)

这句话将图生成一个文件,保存在logs/这个目录下面,程序运行完成之后,你会发现这个文件目录下面多了一个:events.out.tfevents.XXXXXXXX。到这里就成功了一半了。

然后我们打开命令窗口,进入到跟logs一级的目录中,输入tensorboard --logdir=logs/

E:\python_project\TensroflowProject\06-TensorBoard>tensorboard --logdir=logs/
TensorBoard 1.12.2 at http://XXXXXXXXX:6006 (Press CTRL+C to quit)

这条命令会在你的电脑中启动一个服务,这个服务默认的端口为6006,然后复制这个网站到浏览器中,就可以打开TensorBoard了:
在这里插入图片描述
果然跟我们之前的猜测一样!

3. 一个简单的神经网络应用TensorBoard

  接下来搭建一个简单的神经网络,并在TensorBoard中查看图、损失函数变化曲线、权值的更新曲线等。

import tensorflow as tf
import numpy as np

# 生成训练数据
x_data = np.linspace(-1, 1, 300)[:, np.newaxis]  # 创建从-1到1之间的300个数据,并转换为列向量
noise = np.random.normal(0, 0.05, x_data.shape)  # 生成噪声
y_data = np.square(x_data) - 0.5 + noise  # x^2-0.5 + noise

# 定义输入与输出层
with tf.name_scope('inputs'):
    xs = tf.placeholder(tf.float32, [None, 1], name='x-input')
    ys = tf.placeholder(tf.float32, [None, 1], name='y-input')

# ---------------- 定义隐藏层 ---------------------
# 定义一个隐藏层, 神经元个数为10
with tf.name_scope('hidden_layer'):
    # 定义权值w,并随机初始化
    with tf.name_scope('weights'):
        Weights1 = tf.Variable(tf.random_normal([1, 10]))
        tf.summary.histogram('hidden_layer/weights', Weights1)

    # 定义偏置b
    with tf.name_scope('bias'):
        bias1 = tf.Variable(tf.zeros([1, 10]) + 0.1)
        tf.summary.histogram('hidden_layer/bias', bias1)

    with tf.name_scope('wx_plus_b'):
        Wx_plus_b1 = tf.matmul(xs, Weights1) + bias1

    # 激活函数为relu
    with tf.name_scope('hidden_layer/outputs'):
        hidden_outputs = tf.nn.relu(Wx_plus_b1)
        tf.summary.histogram('hidden_layer/outputs', hidden_outputs)

# ---------------- 定义输出层 ---------------------
with tf.name_scope('output_layer'):
    # 定义权值w,并随机初始化
    with tf.name_scope('weights1'):
        Weights2 = tf.Variable(tf.random_normal([10, 1]))
        tf.summary.histogram('output_layer/weights', Weights2)

    # 定义偏置b
    with tf.name_scope('bias1'):
        bias2 = tf.Variable(tf.zeros([1, 1]) + 0.1)
        tf.summary.histogram('output_layer/bias', bias2)

    with tf.name_scope('predict'):
        predict = tf.matmul(hidden_outputs, Weights2) + bias2
        tf.summary.histogram('output_layer/predict', predict)

# ---------------- 定义损失函数 ---------------------
with tf.name_scope('loss'):
    loss = tf.reduce_mean(tf.reduce_sum(tf.square(ys - predict), reduction_indices=[1]))
    tf.summary.scalar('loss', loss)
with tf.name_scope('train'):
    train = tf.train.GradientDescentOptimizer(0.3).minimize(loss)

# 初始化变量
init = tf.global_variables_initializer()

# ---------------- 开启会话开始训练 ---------------------
with tf.Session() as sess:
    merged = tf.summary.merge_all()
    writer = tf.summary.FileWriter('logs/', sess.graph)
    sess.run(init)
    for step in range(1000): # 开始训练,迭代1000轮
        sess.run(train, feed_dict={xs: x_data, ys: y_data})
        if step % 50 == 0:
            print(step, 'loss=', sess.run(loss, feed_dict={xs: x_data, ys: y_data})) #
            result = sess.run(merged, feed_dict={xs: x_data, ys: y_data})
            writer.add_summary(result, step)
    writer.close()

其实关于中间层参数的初始化,可以参考我上一篇文章TensorFlow学习笔记(2)-构建神经网络及其可视化中的函数。这里我将其展开了,所以程序就显得冗长了。

几个需要特别说明的点是:
1. tf.summary.histogram(name, values)
用于监视values为任意shape的数字型tensor。添加直方图用于观察数据的分布。我们在每个参数的定义的时候都添加了这条语句。最后在TensorBoard中会生成每个参数的Distribution和Histogram,方便观察这些参数的变化趋势。

2. tf.summary.scalar(name, tensor)
用于监视tensor为单一的标量如loss,学习率等。

3. tf.summary.merge_all()
合并默认图中所有的summaries。summary的操作对于整个图来说相当于是外设,因为tensorflow是由结果驱动的,而图的结果并不依赖于summary操作,所以summary操作需要被run。整个图经常需要检测许许多多的值,也就是许多值需要summary operation,一个个去run来启动太麻烦了,tensorflow为我们提供了这个函数,把图中所有的summary数据合并在一起,一个run就能启动所有的summary operations。

4. writer.add_summary(summary, global_step=None)
把每一次run的信息和得到的数据加到writer里面。

最后打开TensorBoard,就可以看到图、变量的分布、变化曲线,loss的变化曲线:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4. 其他summary函数

tf.summary.scalar(name, tensor, collections=None, family=None)tensor为单一的标量。
tf.summary.histogram(name, values, collections=None, family=None)values为任意shape的数字型tensor。
tf.summary.image(name, tensor, max_outputs=3, collections=None, family=None) tensor的shape为[batch_size, height, width, channels],其中channels=1表示灰度图,3表示RGB,4表示RGBA。注意max_outputs默认为3表示每轮默认显示三张图。
tf.summary.audio( name, tensor, sample_rate, max_outputs=3, collections=None, family=None) tensor为3D shape [batch_size, frames, channels],或者2D shape [batch_size, frames];sample_rate表示声音类型信号tensor的采样率,大小在[-1.0,1.0]之间。
tf.summary.text(name, tensor, collections=None) 将文本数据转换为string类型的tensor。
tf.summary.merge(inputs, collections=None, name=None) 将inputs里面的summary汇集在一起,其中inputs为string类型tensor的列表。
tf.summary.merge_all( key=tf.GraphKeys.SUMMARIES, scope=None) 把所有的summary汇集在一起。
tf.summary.FileWriter(logdir, sess.graph) 把summary protocol buffers 写进 tfevents文件里。
tf.summary.tensor_summary( name, tensor, summary_description=None, collections=None, summary_metadata=None, family=None, display_name=None)将任意shape和类型的tensor序列化,并返回一个string类型的tensor。

参考资料

通俗易懂之Tensorflow summary类 & 初识tensorboard
TensorFlow 实战Google深度学习框架

猜你喜欢

转载自blog.csdn.net/kabuto_hui/article/details/86579290
今日推荐