在复杂的问题中,网络往往都是很复杂的。为了方便调试参数以及调整网络结构,我们需要将计算图可视化出来,以便能够更好的进行下一步的决策。Tensorflow提供了一个TensorBoard工具,可以满足上面的需求。
TensorBoard是一个可视化工具,能够有效地展示Tensorflow在运行过程中的计算图、各种指标随着时间的变化趋势以及训练中使用到的数据信息。可以查看TensorBoard Github ReadMe 详细阅读适应方法。
下面通过一个简单的例子来显示一下使用方式,下面的图是一个向量加法的图结构。
import tensorflow as tf
a = tf.constant([1.0,2.0,3.0],name='input1')
b = tf.Variable(tf.random_uniform([3]),name='input2')
add = tf.add_n([a,b],name='addOP')
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
writer = tf.summary.FileWriter("E://TensorBoard//test",sess.graph)
print(sess.run(add))
writer.close()
运行完程序后,图结构将以日志文件的形式保存到给定的路径下。
然后在命令行启动Tensorboard。Tensorboard作为本地的一个服务已经启动,端口号是6006,我们只需要在浏览器下输入127.0.0.1:6006就可以进入TensorBoard。下图分别是Tensorboard的界面,以及上面代码对用的图结构。
tensorboard --logdir=E://TensorBoard//test
我们可以简单对下面的图结构进行解读。图中的椭圆代表操作,阴影代表明明空间,小圆圈代表常量。虚线箭头代表依赖,实线箭头代表数据流。
我们的程序想要完成一个加法操作,首先需要利用random_uniform生成一个3元的向量,输入到input2变量节点中,然后input2变量节点需要依赖init操作来完成变量初始化。input2节点将结果输入到addOP操作节点中,同时常量节点input1也将数据输入到addOP中,最终addOP完成计算。
前面的程序,只是一个简单的加法,但是图结构却十分凌乱,而且整个程序的核心add没有在图结构中突出,反而是一些初始化的操作占据了计算图的主要部分。这样不利于对计算图进行分析。因此,我们需要利用一种方式,将计算图的细节部分隐藏,保留关键部分。 命名空间给我们提供了这种机会。
上面的计算图中,核心部分是两个输入传递给加法操作完成计算,因此,我们需要将其他部分隐藏,只保留核心部分。
import tensorflow as tf
with tf.variable_scope('input1'):
input1 = tf.constant([1.0,2.0,3.0],name='input1')
with tf.variable_scope('input2'):
input2 = tf.Variable(tf.random_uniform([3]),name='input2')
add = tf.add_n([input1,input2],name='addOP')
with tf.Session() as sess:
init = tf.global_variables_initializer()
sess.run(init)
writer = tf.summary.FileWriter("E://TensorBoard//test",sess.graph)
print(sess.run(add))
writer.close()
利用同样的方式,我们可以将MNIST神经网络代码重新进行组织(不知道组织的逻辑结构是否正确)
from tensorflow.examples.tutorials.mnist import input_data
import tensorflow as tf
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
batch_size = 100
hidden1_nodes = 200
with tf.name_scope('Input'):
x = tf.placeholder(tf.float32,shape=(None,784))
y = tf.placeholder(tf.float32,shape=(None,10))
with tf.name_scope('Inference'):
w1 = tf.Variable(tf.random_normal([784,hidden1_nodes],stddev=0.1))
w2 = tf.Variable(tf.random_normal([hidden1_nodes,10],stddev=0.1))
b1 = tf.Variable(tf.random_normal([hidden1_nodes],stddev=0.1))
b2 = tf.Variable(tf.random_normal([10],stddev=0.1))
hidden = tf.nn.relu(tf.matmul(x,w1)+b1)
y_predict = tf.nn.relu(tf.matmul(hidden,w2)+b2)
with tf.name_scope('Loss'):
cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y, logits=y_predict))
with tf.name_scope('Train'):
train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)
with tf.name_scope('Accuracy'):
correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_predict, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for i in range(10000):
batch_xs, batch_ys = mnist.train.next_batch(batch_size)
sess.run(train_step, feed_dict={x: batch_xs, y: batch_ys})
if i%1000==0:
print ('Phase'+str(i/1000+1)+':',sess.run(accuracy, feed_dict={x: mnist.test.images, y: mnist.test.labels}))
writer = tf.summary.FileWriter("./mnist_nn_log",sess.graph)
writer.close()