Tensorboard教程:Tensorflow命名空间与计算图可视化
Tensorflow命名空间与计算图可视化
觉得有用的话,欢迎一起讨论相互学习~




参考文献
强烈推荐Tensorflow实战Google深度学习框架
实验平台:
Tensorflow1.4.0
python3.5.0
- Tensorflow可视化得到的图并不仅是将Tensorflow计算图中的节点和边直接可视化,它会根据每个Tensorflow计算节点的命名空间来整理可视化得到效果图,使得神经网络的整体结构不会被过多的细节所淹没。除了显示Tensorflow计算图的结构,Tensorflow还可以展示Tensorflow计算节点上的信息进行描述统计,包括频数统计和分布统计。
- 为了更好的组织可视化效果图中的计算节点,Tensorboard支持通过Tensorflow命名空间来整理可视化效果图上的节点。在Tensorboard的默认视图中,Tensorflow计算图中同一个命名空间下的所有节点会被缩略为一个节点,而顶层命名空间的节点才会被显示在Tensorboard可视化效果图中。
tf.variable_scope和tf.name_scope函数区别
- tf.variable_scope和tf.name_scope函数都提供了命名变量管理的功能,这两个函数在大部分情况下是等价的,唯一的区别在于使用tf.get_variable函数时:
import tensorflow as tf
# 不同的命名空间
with tf.variable_scope("foo"):
# 在命名空间foo下获取变量"bar",于是得到的变量名称为"foo/bar"
a = tf.get_variable("bar", [1])
print(a.name)
# foo/bar:0
with tf.variable_scope("bar"):
# 在命名空间bar下获取变量"bar",于是得到的变量名称为"bar/bar".此时变量在"bar/bar"和变量"foo/bar"并不冲突,于是可以正常运行
b = tf.get_variable("bar", [1])
print(b.name)
# bar/bar:0
# tf.Variable和tf.get_variable的区别。
with tf.name_scope("a"):
# 使用tf.Variable函数生成变量时会受到tf.name_scope影响,于是这个变量的名称为"a/Variable"
a = tf.Variable([1])
print(a.name)
# a/Variable: 0
# tf.get_variable函数不受头tf.name_scope函数的影响,于是变量并不在a这个命名空间中
a = tf.get_variable("b", [1])
print(a.name)
# b:0
# with tf.name_scope("b"):
# 因为tf.get_variable不受tf.name_scope影响,所以这里将试图获取名称为"a"的变量。然而这个变量已经被声明了,于是这里会报重复声明的错误。
# tf.get_variable("b",[1])
- 通过对变量命名空间进行管理,使用Tensorboard查看模型的结构时更加清晰
import tensorflow as tf
with tf.name_scope("input1"):
input1 = tf.constant([1.0, 2.0, 3.0], name="input2")
with tf.name_scope("input2"):
input2 = tf.Variable(tf.random_uniform([3]), name="input2")
output = tf.add_n([input1, input2], name="add")
writer = tf.summary.FileWriter("log/simple_example.log", tf.get_default_graph())
writer.close()
- 这样程序中定义的加法运算都被清晰的展示出来,并且变量初始化等基本操作都被折叠起来。

- 点击input2上的加号按钮,能够看到关于input2变量初始化的全过程。

可视化MNIST程序
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
# mnist_inference中定义的常量和前向传播的函数不需要改变,因为前向传播已经通过
# tf.variable_scope实现了计算节点按照网络结构的划分
import mnist_inference
# #### 1. 定义神经网络的参数。
BATCH_SIZE = 100
LEARNING_RATE_BASE = 0.8
LEARNING_RATE_DECAY = 0.99
REGULARIZATION_RATE = 0.0001
TRAINING_STEPS = 3000
MOVING_AVERAGE_DECAY = 0.99
# #### 2. 定义训练的过程并保存TensorBoard的log文件。
def train(mnist):
# 将处理输入数据的计算都放在名字为"input"的命名空间中
with tf.name_scope('input'):
x = tf.placeholder(tf.float32, [None, mnist_inference.INPUT_NODE], name='x-input')
y_ = tf.placeholder(tf.float32, [None, mnist_inference.OUTPUT_NODE], name='y-input')
regularizer = tf.contrib.layers.l2_regularizer(REGULARIZATION_RATE)
y = mnist_inference.inference(x, regularizer)
global_step = tf.Variable(0, trainable=False)
# 将处理滑动平均相关的计算都放在名为moving average 的命名空间下。
with tf.name_scope("moving_average"):
variable_averages = tf.train.ExponentialMovingAverage(MOVING_AVERAGE_DECAY, global_step)
variables_averages_op = variable_averages.apply(tf.trainable_variables()) # 对可训练变量集合使用滑动平均
# 将计算损失函数相关的计算都放在名为loss function 的命名空间下。
with tf.name_scope("loss_function"):
cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=y, labels=tf.argmax(y_, 1))
cross_entropy_mean = tf.reduce_mean(cross_entropy)
# 将交叉熵加上权值的正则化
loss = cross_entropy_mean + tf.add_n(tf.get_collection('losses'))
# 将定义学习率、优化方法以及每一轮训练需要执行的操作都放在名字为"train_step"的命名空间下。
with tf.name_scope("train_step"):
learning_rate = tf.train.exponential_decay(
LEARNING_RATE_BASE,
global_step,
mnist.train.num_examples/BATCH_SIZE, LEARNING_RATE_DECAY,
staircase=True)
train_step = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss, global_step=global_step)
# 在反向传播的过程中更新变量的滑动平均值
with tf.control_dependencies([train_step, variables_averages_op]):
train_op = tf.no_op(name='train')
# 将结果记录进log文件夹中
writer = tf.summary.FileWriter("log", tf.get_default_graph())
# 训练模型。
with tf.Session() as sess:
tf.global_variables_initializer().run()
for i in range(TRAINING_STEPS):
xs, ys = mnist.train.next_batch(BATCH_SIZE)
if i%1000 == 0:
# 配置运行时需要记录的信息。
run_options = tf.RunOptions(trace_level=tf.RunOptions.FULL_TRACE)
# 运行时记录运行信息的proto。
run_metadata = tf.RunMetadata()
# 将配置信息和记录运行信息的proto传入运行的过程,从而记录运行时每一个节点的时间空间开销信息
_, loss_value, step = sess.run(
[train_op, loss, global_step], feed_dict={x: xs, y_: ys},
options=run_options, run_metadata=run_metadata)
writer.add_run_metadata(run_metadata=run_metadata, tag=("tag%d"%i), global_step=i)
print("After %d training step(s), loss on training batch is %g."%(step, loss_value))
else:
_, loss_value, step = sess.run([train_op, loss, global_step], feed_dict={x: xs, y_: ys})
writer.close()
# #### 3. 主函数。
def main(argv=None):
mnist = input_data.read_data_sets("../../datasets/MNIST_data", one_hot=True)
train(mnist)
if __name__ == '__main__':
main()
可视化效果图
input节点代表了训练神经网络需要的输入数据,这些输入数据会提供给神经网络的第一层layer1.然后神经网络第一层layerl的结果会被传到第二层layer2,经过layer2的计算得到前向传播的结果.loss function节点表示计算损失函数的过程,这个过程既依赖于前向传播的结果来计算交叉熵(layer2到loss_function的边,又依赖于每一层中所定义的变量来计算L2 正则化损失(layer1和layer2到loss_function的边).loss_function 的计算结果会提供给神经网络的优化过程,也就是图中位train_step 所代表的节点。
发现节点之间有两种不同的边。一种边是通过实线表示的,这种边刻画了数据传输,边上箭头方向表达了数据传输的方向。比如layerl和layer2之间的边表示了layer1的输出将会作为layer2的输入。TensorBoard 可视化效果图的边上还标注了张量的维度信息。
从图中可以看出,节点input和layer1之间传输的张量的维度为*784。这说明了训练时提供的batch大小不是固定的(也就是定义的时候是None),输入层节点的个数为784。当两个节点之间传输的张量多于1时,可视化效果图上将只显示张量的个数。效果图上边的粗细表示的是两个节点之间传输的标量维度的总大小,而不是传输的标量个数。比如layer2和train_step之间虽然传输了6个张量,但其维度都比较小,所以这条边比layerl和moving_average之间的边(只传输了4个张量〉还要细。当张量的维度无法确定时,TensorBoard会使用最细的边来表示。比如layer1与layer2之间的边。
Tensor Board可视化效果图上另外一种边是通过虚线表示的,比如图中所示的moving_ average 和train_step 之间的边.虚边表达了计算之间的依赖关系,比如在程序中,通过tf.control_dependencies函数指定了更新参数滑动平均值的操作和通过反向传播更新变量的操作需要同时进行,于是moving_average 与train_step 之间存在一条虚边.
除了手动的通过TensorFlow中的命名空间来调整TensorBoard的可视化效果图,TensorBoard也会智能地调整可视化效果图上的节点.TensorFlow中部分计算节点会有比较多的依赖关系,如果全部画在一张图上会便可视化得到的效果图非常拥挤.于是TensorBoard将TensorFlow计算图分成了主图(Main Graph)和辅助图(Auxiliary nodes)两个部分来呈现。TensorBoard 会自动将连接比较多的节点放在辅助图中,使得主图的结构更加清晰。
除了自动的方式,TensorBoard也支持手工的方式来调整可视化结果。右键单击可视化效果图上的节点会弹出一个选项,这个选项可以将节点加入主图或者从主图中删除。左键选择一个节点并点击信息框下部的选项也可以完成类似的功能。注意TensorBoard 不会保存用户对计算图可视化结果的手工修改,页面刷新之后计算图可视化结果又会回到最初的样子。


Tensorboard教程:Tensorflow命名空间与计算图可视化的更多相关文章
- Tensorboard教程:监控指标可视化
Tensorflow监控指标可视化 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考文献 强烈推荐Tensorflow实战Google深度学习框架 实验平台: Tensorflow1.4. ...
- Tensorboard教程:高维向量可视化
Tensorflow高维向量可视化 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考文献 强烈推荐Tensorflow实战Google深度学习框架 实验平台: Tensorflow1.4. ...
- TensorFlow计算模型—计算图
TensorFlow是一个通过计算图的形式来表述计算的编程系统.其中的Tnesor,代表它的数据结构,而Flow代表它的计算模型.TensorFlow中的每一个计算都是计算图上的一个节点,而节点之间的 ...
- XAML实例教程系列 - 命名空间(NameSpace) 三
XAML实例教程系列 - 命名空间(NameSpace) 2012-05-28 14:14 by jv9, 2205 阅读, 10 评论, 收藏, 编辑 上一篇曾提及XAML中,每个对象元素的声明是对 ...
- 吴裕雄 python 神经网络——TensorFlow 训练过程的可视化 TensorBoard的应用
#训练过程的可视化 ,TensorBoard的应用 #导入模块并下载数据集 import tensorflow as tf from tensorflow.examples.tutorials.mni ...
- tensorboard实现tensorflow可视化
1.工程目录 2.data.input_data.py的导入 在tensorflow更新之后可以进行直接的input_data的导入 # from tensorflow.examples.tutori ...
- Tensorboard教程:显示计算图中节点信息
Tensorboard显示计算图节点信息 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考文献 强烈推荐Tensorflow实战Google深度学习框架 实验平台: Tensorflow1 ...
- Tensorflow机器学习入门——网络可视化TensorBoard
一.在代码中标记要显示的各种量 tensorboard各函数的作用和用法请参考:https://www.cnblogs.com/lyc-seu/p/8647792.html import tensor ...
- Tensorflow计算模型 —— 计算图
转载自:http://blog.csdn.net/john_xyz/article/details/69053626 Tensorflow是一个通过计算图的形式来表述计算的编程系统,计算图也叫数据流图 ...
随机推荐
- sqlserver-查阻塞
模拟阻塞: 打开两个窗口: 窗口一: BEGIN TRANSACTION--开始事务 --等待1分钟 WAITFOR DELAY '00:1'; 窗口二: 查询阻塞:(当前被阻塞的进程id,不 ...
- 20181113-3 Beta阶段贡献分配规则
此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2382 在新成员加入后,我们经过商讨,决定沿用alpha阶段贡献分分配规则 ...
- 1.12Linux下软件安装(学习过程)
实验介绍 介绍 Ubuntu 下软件安装的几种方式,及 apt,dpkg 工具的使用. 一.Linux 上的软件安装 通常 Linux 上的软件安装主要有三种方式: 在线安装 从磁盘安装deb软件包 ...
- POJ 2392 Space Elevator 贪心+dp
题目链接: http://poj.org/problem?id=2392 题意: 给你k类方块,每类方块ci个,每类方块的高度为hi,现在要报所有的方块叠在一起,每类方块的任何一个部分都不能出现在ai ...
- javascript方法扩展
String.prototype.startWith = function(str){ return str.indexOf(str) == 0; }; var str = "abc&quo ...
- BZOJ 2118 墨墨的等式(最短路)
很开拓眼界的题.. 题意:给出一个n元一次方程形如a1*x1+a2*x2...+an*xn=B,求满足解集为非负整数的B值在[L,R]范围内的种数.(n<=12,ai<=5e5,L< ...
- BZOJ4923 K小值查询(splay)
容易想到建一棵平衡树,修改时打上标记即可.但是修改会导致平衡树结构被破坏.注意到实际上只有[k+1,2k)这一部分数在平衡树中的位置会被改变,所以对这一部分暴力修改,因为每次都会使其至少减小一半,复杂 ...
- Educational Codeforces Round 33 (Rated for Div. 2) 题解
A.每个状态只有一种后续转移,判断每次转移是否都合法即可. #include <iostream> #include <cstdio> using namespace std; ...
- C++中关于new及动态内存分配的思考
如何实现一个malloc? malloc_tutorial.pdf ———————————————————————————————————— 我们知道,使用malloc/calloc等分配内存的函数时 ...
- 【BZOJ1001】狼抓兔子(平面图转对偶图,最短路)
[BZOJ1001]狼抓兔子(平面图转对偶图,最短路) 题面 BZOJ 洛谷 题解 这题用最小割可以直接做 今天再学习了一下平面图转对偶图的做法 大致的思路如下: 1.将源点到汇点中再补一条不与任何线 ...