【TensorBoard简介】
TensorBoard可以有效地展示TensorFlow在运行过程中的计算图、各种指标随着时间的变化趋势以及训练中使用到的图像等信息。TensorBoard是tensorflow的可视化工具,可以通过tensorflow程序运行过程中输出的日志文件可视化tensorflow程序的运行状态。TensorBoard和tensorflow程序跑在不同的进程中,TensorBoard会自动读取最新的tensorflow日志文件,并呈现当前的tensorflow程序运行的最新状态。以下代码展示了一个TensorBoard日志输出的功能。
writer = tf.summary.FileWriter("/path/to/log", tf.get_default_graph())
writer.close()
运行以下命令便可以启动TensorBoard
# 运行TensorBoard,并将日志的地址指向上面程序日志输出的地址
tensorboard --logdir=/path/to/log
运行以上命令会启动一个服务,这个服务的端口默认为6006,通过浏览器打开localhost:6006
【监控指标可视化】
除了graph外,tensorboard界面中还提供了scalars、images、audio、dustributions、histogram和text6个界面来可视化其他的监控指标。以下程序展示了如何将tesorflow程序运行时的信息输出到tensorboard日志文件中
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
SUMMARY_DIR = '/path/to/log'
BATCH_SIZE = 100
TRAIN_STEPS = 3000
# 生成变量监控信息并定义生成监控信息日志的操作,其中var给出了需要记录的张量,name给出了在可视化结果中显示的图表名称,这个名称一般与变量名一致。
def variable_summaries(var, name):
# 将生成监控信息的操作放到同一个命名空间下
with tf.name_scope('summaries'):
# 通过tf.summary.histogram函数记录张量中元素的取值分布,对于给出的图表名称和张量,tf.summary.histogram函数会生成一个summary protocol buffer,将summary卸乳tensorboard日志文件后,在histogram栏和distribution栏下都会出现对应名称的图表,和tensorflow中其他操作相似,tf.summary.histogram函数不会立刻被执行,只有当sess.run函数明确调用这个操作时,tensorflow才会真正生成并输出summary protocol buffer。
tf.summary.histogram(name, var)
# 计算变量的平均值,并定义生成平均值信息日志的操作。记录变量平均值信息的日志标签名为‘/mean’+name,其中mean为命名空间,/是命名空间的分隔符,name则给出了当前监控指标属于哪一个变量
mean = tf.reduce_mean(var)
tf.summary.scalar('mean/' + name, mean)
# 计算变量的标准差,并定义生成其日志的操作
stddev = tf.sqrt(tf.reduce_mean(tf.square(var-mean)))
tf.summary.scalar('stddev/'+name, stddev)
# 生成一层全连接层神经网络
def nn_layer(input_tensor, input_dim, output_dim, layer_name, act=tf.nn.relu):
# 将同一层神经网络放在一个统一的命名空间下
with tf.name_scope(layer_name):
# 声明神经网络边上的权重,并调用生成权重监控信息日志的函数
with tf.name_scope("weights"):
weights = tf.Variable(tf.truncated_normal([input_dim, output_dim], stddev=0.01))
variable_summarys(weights, layer_name + '/weights')
# 声明神经网络的偏置项,并调用生成偏置项监控信息日志的函数
with tf.name_scope("biases"):
biases = tf.Variable(tf.constant(0.0, shape=[output_dim]))
variable_summarys(biases, layer_name + '/biases')
with tf.name_scope("Wx_plus_b"):
preactivate = tf.matmul(input_tensor, weights) + biases
# 记录神经网络输出节点在经过激活函数之前的分布
tf.summary.histogram(layer_name + 'pre_activations', preactivate)
activations = act(preactivate, name='activation')
tf.summary.histogram(layer_name + 'activations', activations)
return activations
def main():
mnist = input_data.read_data_sets("/path/to/mnist_data", one_hot=True)
with tf.name_scope('input'):
x= tf.placeholder(tf.float32, [None,784], name='x-input')
y_= tf.placeholder(tf.float32, [None,10], name='y-input')
# 将输入向量还原成图片的像素矩阵,并通过tf.summary.image函数定义将当前的图片信息写入日志的操作
with tf.name_scope('input_reshape'):
image_shaped_input = tf.reshape(x, [-1,28,28,1])
tf.summary.image('input', image_shaped_input, 10)
hidden1 = nn_layer(x, 784, 500, 'layer1')
y = nn_layer(hidden1, 500, 10, act=tf.identity)
# 计算交叉熵并定义生成交叉熵监控日志的操作
with tf.name_scope('cross_entropy'):
cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(y, y_))
tf.summary.scalar('cross entropy', cross_entropy)
with tf.name_scope('train'):
train_step = tf.train.AdamOptimizer(0.01).minimize(cross_entropy)
# 计算模型在当前给定数据上的正确率,并定义生成正确率监控日志的操作,如果在sess.run时给定的数据时训练batch,那么得到的正确率就是在这个训练数据上batch上的正确率;如果给定的数据为验证或测试数据,那么得到的正确率就是当前模型在验证或测试数据上的正确率
with tf.name_scope('accuracy'):
with tf.name_scope('correct_prediction'):
correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_, 1))
with tf.name_scope('accuracy'):
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
tf.summary.scalar('accuracy', accuracy)
# 因为程序中定义的写日志操作比较多,一一调用比较麻烦,所以tensorflow提供了tf.summary.merge_all函数来整理所有的日志生成操作,在tensorflow程序执行的过程中只需要运行这个操作就可以将代码中定义的所有日志生成操作执行一次,从而将所有日志写入文件
merged = tf.summary.merge_all()
with tf.Session() as sess:
# 初始化写日志的writter。并将当前tensorflow计算图写入日志
summary_writter = tf.summary.FileWriter(SUMMARY_DIR, sess.graph)
tf.global_variable_initializer().run()
for i in range(TRAIN_STEPS):
xs, ys = mnist.train.next_batch(BATCH_SIZE)
# 运行训练步骤及所有的日志生成操作,得到这次运行的日志
summary, _ = sess.run([merged, train_step], feed_dict={x:xs, y_:ys})
# 将所有日志写入文件,tensorboard程序就可以拿到这次运行所对应的运行信息
summary_writter.add_summary(summary, i)
summary_writter.close()
if __name__=='__main__':
tf.app.run()
参考资料:
TensorFlow:实战Google深度学习框架-中国工信出版集团