作者:chen_h
微信号 & QQ:862251340
微信公众号:coderpai
Tensorflow
提供了很强大的可视化功能,今天来学习一下。
当我们导入tensorflow
包的时候,系统已经帮助我们产生了一个默认的图,它被存在_default_graph_stack
中,但是我们没有权限直接进入这个图,我们需要使用tf.get_default_graph()
命令来获取图。
>>> graph = tf.get_default_graph()
tensorflow
中的图上的节点被称之为operations
或者ops
。我们可以使用graph.get_operations()
命令来获取图中的operations
。
>>> graph.get_operations()
# []
现在,因为图中没有操作,所以返回的是[]
。我们可以向图中添加任何的操作,比如我们先定义一个常量input_value
。
>>> input_value = tf.constant(1.0)
现在,这个常量作为一个节点被添加到了图中,作为一个operations
。现在,我们能发现operations
中存在值了。
>>> operations = graph.get_operations()
>>> operations
# [<tensorflow.python.framework.ops.Operation at 0x1185005d0>]
>>> operations[0].node_def
# name: "Const"
# op: "Const"
# attr {
# key: "dtype"
# value {
# type: DT_FLOAT
# }
# }
# attr {
# key: "value"
# value {
# tensor {
# dtype: DT_FLOAT
# tensor_shape {
# }
# float_val: 1.0
# }
# }
# }
Tensorflow
还能做很多非常有意义的事,但是你必须给每个操作都赋予明确的含义,即使只是一个常量。
如果我们查看常量input_value
,我们将能看到它只是一个32位的浮点数类型的tensor
,维度是零维度。
>>> input_value
# <tf.Tensor 'Const:0' shape=() dtype=float32>
可能你注意到了,我们发现这个操作并没有告诉我们input_value
的值是多少。这是为什么呢?因为图graph
只是定义了操作operations
,但是操作operations
只能在session
里面执行,但是graph
和session
是独立创建的。所以,我们上述操作才没有显示input_value
的值是多少。如果,我们想知道input_value
中具体的值是多少,那么我们需要创建一个session
,具体如下:
>>> sess = tf.Session()
>>> sess.run(input_value)
# 1.0
至此,我们已经在图中创建了一个session
。
接下来,我们创建一个神经元。为了简便,我们只创建一个参数变量,在这里我们不使用常量constant
来构建,因为我们希望在后续的计算中,这个权重可以更新,所以我们采用Variable
来构建参数变量。
>>> weight = tf.Variable(0.8)
可能,你会认为,你只是添加了一个Variable
,那么在图中也只会增加一个操作operations
。但是事实上,增加了这个权重,却增加了四个操作。我们能使用以下命令来查看各个operations
的名字。
>>> for op in graph.get_operations():
>>> print op.name
# Const
# Variable/initial_value
# Variable
# Variable/Assign
# Variable/read
我们不会关心每一个操作,但是关心每一个操作的含义是有意义的。
>>> output_value = weight * input_value
现在,你查看图中的操作,发现有六个操作了,其中最后一个操作的名字是mul
。
>>> op = graph.get_operations()[-1]
>>> op.name
# 'mul'
>>> for op_input in op.inputs:
>>> print op_input
# Tensor("Variable/read:0", shape=(), dtype=float32)
# Tensor("Const:0", shape=(), dtype=float32)
这个显示说明了,这个乘法操作的数据来源是哪里。
那么,我们怎么执行这个乘法操作呢?我们必须去run
这个乘法,才能得到output_value
的值。但是,这个操作依赖于一个参数weight
。我们告诉Tensorflow
这个值得初始值是0.8
,但是这个初始化操作还没有在session
中执行,我们需要使用tf.initialize_all_variables()
来初始化参数变量。
>>> init = tf.initialize_all_variables()
>>> sess.run(init)
执行tf.initialize_all_variables()
操作将初始化当前图中的所有参数变量,但是如果你想重新加入一个变量,那么就需要重新执行tf.initialize_all_variables()
操作,因为先前的操作不包括初始化新的参数变量。
现在,我们来打印output_value
操作。
>>> sess.run(output_value)
# 0.80000001
至此,我们已经能简单的描述一个图了。但是,TensorBoard
提供了更加强大的可视化功能,接下来,我们来实现这个可视化功能。
TensorBoard
读取操作operations
中的每一个名字,然后对每个名字进行操作。比如如下操作:
>>> x = tf.constant(1.0, name = 'input')
>>> w = tf.Variable(0.8, name = 'weight')
>>> y = tf.mul(w, x, name = 'output')
TensorBoard
的工作原理是从session
创建的一个目录中读取结果。我们能使用SummaryWriter
函数将output
的结果保存到一个目录下面。
SummaryWriter
函数的第一个参数是输出目录的名字,这个目录如果不存在,那么将会被创建。
>>> summary_writer = tf.train.SummaryWriter('log_simple_graph', sess.graph)
那么,我们可以在终端下面使用这个命令。
$ tensorboard --logdir=log_simple_graph
TensorBoard
运行这个图在本地的6006
端口,即localhost:6006
。
最后附上一个完整代码,以供学习。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import tensorflow as tf
x = tf.constant(1.0, name='input')
w = tf.Variable(0.8, name='weight')
y = tf.mul(w, x, name='output')
y_ = tf.constant(0.0, name='correct_value')
loss = tf.pow(y - y_, 2, name='loss')
train_step = tf.train.GradientDescentOptimizer(0.025).minimize(loss)
for value in [x, w, y, y_, loss]:
tf.scalar_summary(value.op.name, value)
summaries = tf.merge_all_summaries()
sess = tf.Session()
summary_writer = tf.train.SummaryWriter('log_simple_stats', sess.graph)
sess.run(tf.initialize_all_variables())
for i in range(100):
summary_writer.add_summary(sess.run(summaries), i)
sess.run(train_step)