一、一个简单例子
执行如下代码片段,可在定义的目录中生成日志文件,如下:
import tensorflow as tf
#simple demo
# 定义一个计算图,实现两个向量的加法
# 定义两个输入,a为常量,b为随机值
a=tf.constant([10.0, 20.0, 40.0], name='a')
b=tf.Variable(tf.random_uniform([3]), name='b') # 从均匀分布中输出随机值,[3]代表张量尺寸
output=tf.add_n([a,b], name='add') #Add all input tensors element wise
with tf.Session() as sess:
# 生成一个具有写权限的日志文件操作对象,将当前命名空间的计算图写进日
writer=tf.summary.FileWriter('D:\\tf_dir\\tensorboard_study', sess.graph)
sess.run(tf.global_variables_initializer())
f=sess.run(output)
print(f)
writer.close()
pass
执行"tensorboard --logdir=D:\tf_dir\tensorboard_study",然后在http://localhost:6006/#graphs&run=tensorboard_study 中便可以查看到如下图形:加法的graph
二、组件介绍组件名称说明
三、栏目介绍
3.0 graphs
此栏目下展示网络的结构,相应的组件作用可以参考“二、组件介绍”部分。
一般我们可以定义子命名空间,便可以达到整理节点,使可视化信息更加清晰的目的。具体语法为:"with tf.name_scope("layer_0"):"。
tensorboard除了可以展示计算图的结构外,还有其他功能:结点基本信息、运行时间、运行时消耗的内存、各结点的运行设备。
1)结点基本信息
通过左键单击节点,便可在右上角展示其基本信息。如下图:
双击节点则可以查看节点细节内容,再次双击则可以把细节内容收起。如下图:
2)运行时间、消耗内存、运行设备
import tensorflow as tf
a=tf.constant([10.0, 20.0, 40.0], name='a')
b=tf.Variable(tf.random_uniform([3]), name='b') # 从均匀分布中输出随机值,[3]代表张量尺寸
output=tf.add_n([a,b], name='add') #Add all input tensors element wise
with tf.Session() as sess:
writer=tf.summary.FileWriter('D:\\tf_dir\\tensorboard_study', sess.graph)
# tf.RunOptions.FULL_TRACE代表所有的信息
run_options = tf.RunOptions(trace_level=tf.RunOptions.FULL_TRACE)
#运行时记录运行信息的proto,pb是用来序列化数据的
run_metadata = tf.RunMetadata()
sess.run(tf.global_variables_initializer())
f=sess.run(output,options=run_options, run_metadata=run_metadata)
print(f)
writer.add_run_metadata(run_metadata, 'metadata')
writer.close()
pass
通过选择session便可以查看相应迭代轮数下的各项指标表现。如下图:
3.1 scalars
tensorboard的标量仪表盘,统计tensorflow中的标量随着迭代轮数的变化情况(如:学习率、loss、auc)。通过tf.summary.scalar()把标量值存入日志文件,tensorboard读取日志文件在SCALARS栏目显示。
1) scalar页面功能说明p1:是否显示数据下载链接。
p2:图表平滑过程中是否忽略异常点。
p3:控制每个run点信息的显示顺序。
p4:代表平滑系数,值越大平滑越多。
p5:横坐标刻度值。STEP:默认选项,横轴显示的是训练迭代次数。RELATIVE:这个相对指的是相对时间,相对于训练开始的时间,也就是说训练用时 ,单位是小时。WALL:指训练的绝对时间。
p6:选择要显示的内容,此处支持正则表达式。
p7:查看大图。
p8:是否对y轴进行对数化处理。
p9:如果拖动或缩放了坐标轴,点击后回到原始位置。
p10:下载显示的数据。
补充:在标量图中拉一个矩形,则把矩形内的数据放大展示。
2)注册一个标量的完整过程
第一步:定义要收集的指标,如:metric_loss = tf.summary.scalar("loss", loss)。
第二步:调用merge_all或merge把summary信息保存到磁盘,以便tensorboard展示。如:merged = tf.summary.merge_all()。
第三步:变量初始化,参见“4.4 变量初始化“;同时定义FileWriter,如:writer = tf.summary.FileWriter('./graph',sess.graph)。
第四步:调用session.run(),计算本次迭代(global_step)的标量值。如:result = sess.run(merged, feed_dict={X: batchX, Y: batchY})。
第五步:把每个step计算好的summary写入日志文件中。如:writer.add_summary(result , global_step)。 关于此部分也可参考"参考资料-5"。
3.2 images
图像仪表盘,显式通过tf.summary.image()函数来保存png图片文件,将png图片放到summary中,写入日志文件。tensorboard读取日志文件,在IMAGES栏目下可以展示。
3.3 audio
音频仪表盘,可嵌入音频小文件。可以播放通过tf.summary.audio()函数保存的音频。
3.4 histograms
tensorboard的张量仪表盘,统计tensorflow中的张量随着迭代轮数的变化情况。通过tf.summary.histogram进行记录。
3.5 distributions
tensorboard的张量仪表盘,用另一种直方图展示从tf.summary.histogram()函数记录的数据规律。它显示了一些分发的高级统计信息。
3.6 projector
嵌入式投影仪表盘,可以把高维的embedding通过PCA降维的方式投影到3维空间中,从而进行高维的数据分析。tensorboard从模型运行过程中保存的checkpoint文件中读取数据,与此同时也可以选择另外一种投影方式,如:T-SNE。
3.7 text
文本仪表盘,显示通过tf.summary.text()函数保存的文本片段,包括超链接、列表和表格在内的Markdown支持的功能。
3.8 pr curves
PR CURVES仪表盘显示的是随时间变化的PR曲线,其中precision为横坐标,recall为纵坐标。训练模型时,经常需要在查准率和查全率之间权衡,PR曲线能够帮助我们找到这个权衡点。
3.9 profile
tensorboard的配置文件仪表盘,该仪表盘上包含了一套TPU工具,可以帮助我们调试、优化tensorflow代码,以便更好地利用TPU资源。目前只有在Google Cloud TPU上有访问权限的人才能使用配置文件仪表盘上的工具。
注:summary也是个op,所以也需要sess.run()才能获取真实结果。
四、重要基础功能
4.1 tf.summary.FileWriter
指定一个文件用来保存图。
格式为:tf.summary.FileWriter(logdir, graph=None, flush_secs=120, max_queue=10)。
可以调用其add_summary()方法将训练过程数据保存在filewriter指定的文件中。
tf.summary.scalar('accuracy',acc)
merge_summary = tf.summary.merge_all()
train_writer = tf.summary.FileWriter(dir,sess.graph)
for step in xrange(training_step): #训练循环
train_summary = sess.run(merge_summary,feed_dict = {...})
train_writer.add_summary(train_summary,step)
如果要显示多次训练的结果,就需要在每次训练过程中给FileWriter设置不同的目录。
4.2 tf.summary.merge_all
merge_all可以将定义的所有summary都保存在日志中,以便tensorboard进行显示。如果没有特殊需要,一般都采用这种方法收集所有要显示的信息。
格式为:tf.summaries.merge_all(key='summaries'),应用大多数情况下括号中啥也不写。
4.3 tf.summary.merge
如果是有选择性地保存summary信息,则要用到merge方法。其格式为:
tf.summary.merge(inputs, collections=None, name=None)
其中inputs参数可以直接用列表表示或者用tf.get_collection()来表示。
4.4 变量初始化
tf.global_variablesinitializer():用于初始化全局变量(GraphKeys.GLOBALVARIABLES),并返回一个初始化所有全局变量的操作。一般在模型构建完毕并在会话中加载后,执行此初始化操作。当然也可通过feed_dict初始化,不过这样只初始化feed_dict列表中的变量。
tf.local_variables_initializer():返回一个初始化所有局部变量(GraphKeys.LOCAL_VARIABL)的操作。局部变量指的是被添加到图中,但未被储存的变量。
五、常见问题汇总
Q1:在auc曲线上出现了小回路,如下图:
解决办法:一般是时间线错乱导致的,如中断训练之后没有从最近的checkpoint处开始。
Q2:jupyter执行脚本,tensorboard可视化展示多个graph比较乱?
解决办法:清空日志目录,重启kernel并执行,刷新tensorboard页面即可看到最新graph。
Q3:训练过程中的AUC指标如何正常展示?
# 补充描述:如果同时执行auc_value,auc_op则auc_value为0
auc_value, auc_op = tf.metrics.auc(label_tensor, prediction_tensor)
self.merged = tf.summary.merge([auc_value, auc_op ])
summary = sess.run([self.merged], feed_dict={})
解决办法:1)初始化局部变量 2)先执行auc_op操作,再执行auc_value才是正确姿势。
# 1)初始化局部变量的说明
"""
tf.metrics.auc()内部调用了_confusion_matrix_at_thresholds方法
而_confusion_matrix_at_thresholds方法内部有四个局部变量,因为需要局部变量初始化。
详情可看:https://github.com/tensorflow/tensorflow/blob/a6d8ffae097d0132989ae4688d224121ec6d8f35/tensorflow/python/ops/metrics_impl.py#L481
注意:初始化以后如果不再重新初始化的话,则局部变量的值则会被一直复用。所以一般在epoch结束时,会重新初始化局部变量。这样是对一批数据的完整评估。
"""
# 2)先执行auc_op操作,再执行auc_value才是正确姿势
"""
tf.metrics.auc()有两个返回值分别为:auc_value, update_op。auc_value只是update_op操作执行后的一种快速引用方式。
auc_value,auc_op分别依赖于values,auc_ops。这两个值由_confusion_matrix_at_thresholds生成。部分代码如下:
"""
values = {} #line1
update_ops = {} #line2
update_ops['tp'] = state_ops.assign_add(true_p,math_ops.reduce_sum(is_true_positive, 1)) #line3
values['tp'] = true_p #line4
# 说明:line3把增量加到true_p中,把相应的操作赋值给update_ops。line4中的true_p是指前述更新过的true_p,此处只不过定义一种快速引用方式。
# 对快速访问有疑问的朋友可以参考:https://github.com/tensorflow/tensorflow/blob/a6d8ffae097d0132989ae4688d224121ec6d8f35/tensorflow/python/ops/state_ops.py#L164。
[参考资料]