前面学习的cifar10项目虽小,但却五脏俱全。全面理解该项目非常有利于进一步的学习和提高,也是走向更大型项目的必由之路。因此,summary依然要从cifar10项目说起,通俗易懂的理解并运用summary是本篇博客的关键。

先不管三七二十一,列出cifar10中定义模型和训练模型中的summary的代码:

# Display the training images in the visualizer.
tf.summary.image('images', images)
def _activation_summary(x):
"""Helper to create summaries for activations. Creates a summary that provides a histogram of activations.
Creates a summary that measure the sparsity of activations. Args:
x: Tensor
Returns:
nothing
"""
# Remove 'tower_[0-9]/' from the name in case this is a multi-GPU training
# session. This helps the clarity of presentation on tensorboard.
tensor_name = re.sub('%s_[0-9]*/' % TOWER_NAME, '', x.op.name)
tf.summary.histogram(tensor_name + '/activations', x)
tf.summary.scalar(tensor_name + '/sparsity', tf.nn.zero_fraction(x))
_activation_summary(conv1)
_activation_summary(conv2)
_activation_summary(local3)
_activation_summary(local4)
_activation_summary(softmax_linear)
def _add_loss_summaries(total_loss):
"""Add summaries for losses in CIFAR-10 model. Generates moving average for all losses and associated summaries for
visualizing the performance of the network. Args:
total_loss: Total loss from loss().
Returns:
loss_averages_op: op for generating moving averages of losses.
"""
# Compute the moving average of all individual losses and the total loss.
loss_averages = tf.train.ExponentialMovingAverage(0.9, name='avg')
losses = tf.get_collection('losses')
loss_averages_op = loss_averages.apply(losses + [total_loss]) # Attach a scalar summary to all individual losses and the total loss; do the
# same for the averaged version of the losses.
for l in losses + [total_loss]:
# Name each loss as '(raw)' and name the moving average version of the loss
# as the original loss name.
tf.summary.scalar(l.op.name +' (raw)', l)
tf.summary.scalar(l.op.name, loss_averages.average(l)) return loss_averages_op
tf.summary.scalar('learning_rate', lr)
# Add histograms for trainable variables.
for var in tf.trainable_variables():
tf.summary.histogram(var.op.name, var)
# Add histograms for gradients.
for grad, var in grads:
if grad is not None:
tf.summary.histogram(var.op.name + '/gradients', grad)
# Build the summary operation based on the TF collection of Summaries.
summary_op = tf.summary.merge_all() summary_writer = tf.summary.FileWriter(FLAGS.train_dir, sess.graph) if step % 100 == 0:
summary_str = sess.run(summary_op)
summary_writer.add_summary(summary_str, step)

通过观察,聪明的大家不禁发现以下问题:

  1. 函数_activation_summary可以为每一层激活值创建summary,而无任何返回值,既然没有返回值,也就说明没有数据的流动,也就是并非有意义的节点;
  2. summary类包含histogram和scalar两种类型,而且似乎这两种类型是有严格划分的:为什么这么说呢?代码中可以看到,学习率就是scalar类型,梯度值就是histogram类型;
  3. summary类在cifar10项目中普遍存在,包含学习率、梯度值、激活值、变量、loss等,而这些似乎都是在深度学习过程中,我们比较关心的量,这似乎让人无限遐想。

带着这些发现,我们又不禁产生下列疑问:

  1. summary如果都不是节点,那它在会话中起到什么作用,又执行了什么操作?
  2. summary类包含的数据类型有哪些,它们之间是如何划分的?
  3. 我们可以为哪些量创建summary,除了上述函数,summary类中还包含哪些常见的函数?

带着这些问题,打开官方的tutorial、API教程,这里是中文版。纯粹点说,summary和TensorBoard有关,也就是和tf的可视化有关。

上面列出的代码实际上给我们列出了一个过程,就是使用summary或者可视化tensorboard的过程,具体来说:

  1. 为你需要可视化记录的量创建summary,summary其实就相当于一个监测器,你让它监测谁就监测谁,附加在你想监测的量上,如果没有它,也就无从谈起tensorboard可视化,根本不知道可视化什么量;
  2. 收集汇总图中所有创建的summary,如果不汇总,相互之间就没有关联,需要一个一个在会话中运行,麻烦费事;
  3. 把收集的数据写入指定的文件,summary本身并不能可视化,保存数据则是为了tensorboard的可视化;

再从表面上来看,训练cifar10模型,得到的文件问下:

归纳一下就是:

  • checkpoint文件。打开该文件,内容如下:
model_checkpoint_path: "model.ckpt-1000"
all_model_checkpoint_paths: "model.ckpt-0"
all_model_checkpoint_paths: "model.ckpt-1000"

可见,该文件是记录中间保存模型的位置的,第一行表明最新的模型,其他行是保存的其它模型,随迭代次数从低到高排列。

  • tfevents文件。该文件是保存的summary日志文件,比如cifar10项目是每隔100次进行更新,代码如下:
if step % 100 == 0:
summary_str = sess.run(summary_op)
summary_writer.add_summary(summary_str, step)

里面就记录着整个汇总summary监测的数据以及模型图。这个文件是要在tensorboard可视化中要用到的。

  • model data文件。该文件保存了所有训练变量所在迭代次数时的值。比如上面的0和1000次。
  • model index文件。该文件保存了所有训练变量的名称。
  • model meta文件。该文件保存在模型图的结构。

上述三个model文件data和index是结合在一起确定变量的,meta是模型网络的结构,这和变量的加载联系起来,就会发现,加载时data和index是必须的,因此可以只加载变量不加载图结构,或者都加载,下面的例子是cifar10_eval.py中的例子,显然这是属于第一种,只加载了变量没有加载图结构而使用了默认图。

tf.app.flags.DEFINE_string('checkpoint_dir', 'cifar10_train/',
"""Directory where to read model checkpoints.""") def eval_once(saver, summary_writer, top_k_op, summary_op):
"""Run Eval once. Args:
saver: Saver.
summary_writer: Summary writer.
top_k_op: Top K op.
summary_op: Summary op.
"""
with tf.Session() as sess:
ckpt = tf.train.get_checkpoint_state(FLAGS.checkpoint_dir)
if ckpt and ckpt.model_checkpoint_path:
# Restores from checkpoint
saver.restore(sess, ckpt.model_checkpoint_path)
# Assuming model_checkpoint_path looks something like:
# /my-favorite-path/cifar10_train/model.ckpt-0,
# extract global_step from it.
global_step = ckpt.model_checkpoint_path.split('/')[-1].split('-')[-1]
else:
print('No checkpoint file found')
return
def evaluate():
"""Eval CIFAR-10 for a number of steps."""
with tf.Graph().as_default():

也可以都加载,例如:

tf.app.flags.DEFINE_string('checkpoint_dir', 'cifar10_train/',
"""Directory where to read model checkpoints.""")
ckpt = tf.train.get_checkpoint_state(FLAGS.checkpoint_dir)
saver = tf.train.import_meta_graph(ckpt.model_checkpoint_path +'.meta')
with tf.Session() as sess:
saver.restore(sess,ckpt.model_checkpoint_path)

那如何用summary保存的训练日志启动tensorboard呢?

只需要tensorboard --logdir=cifar10_train,注意cifar10_train是日志所在的文件夹,同时请在cifar10_train所在目录下执行该命令,可得:

请用IE浏览器,或者其它高级的浏览器(chrome、Firefox)打开图片中出现的网址即可:http://DESKTOP-HMQ55PS:6006

到此为止,在表面上对summary类有了一定的认识,那接下来可以回答上述的三个疑问。

  • summary如果都不是节点,那它在会话中起到什么作用,又执行了什么操作?

:summary类是tensorboard可视化训练过程和图结构的基础,它相当于一个监测器,在哪加就说明想要监测哪,summary类没有执行任何实质性操作,tf就是这样,如果不建立会话启动的话,一切都是静态的,当然,summary类只是监测动态性,因此无实质性操作,只能说不同的函数有不同的功能和目的,这将在第三问探讨。

  • summary类包含的数据类型有哪些,它们之间是如何划分的?

:从tensorboard可视化的截图中可以发现,summary类包含的数据类型有:scalar、image、graph、histogram、audio。其中前四种在本项目中都出现了,只有audio类型没有出现。那它们是如何划分的呢?显然是按照类型划分的......scalar表示标量,image表示图片,graph表示网络节点模型图,histogram表示变量的直方图,audio表示音频数据,具体内容参考上述代码,也很容易明白,scalar通常表示单一的量,例如学习率、loss、AP等,而histogram表示的是统计信息,比如梯度、激活值等。graph通过summary_writer = tf.summary.FileWriter(FLAGS.train_dir, sess.graph)代码中的sess.graph得到。注意除此之外,tensorboard还有两个统计信息,一个是distributions,统计权值、偏置和梯度的分布,另一个是projector,包含T-SNE和PCA。

  • 我们可以为哪些量创建summary,除了上述函数,summary类中还包含哪些常见的函数?

答:通常意义上只要符合上述5类的都可以创建summary,但是常用的有意义的量就上述常见的那些。summary类中常见的函数上面写得也很全了,但是问题的焦点是很多网上的博客包括一些中文社区都没有及时对最新版本的API内容进行更新,无意之间却带来了误导,因此,我们必须看官方提供的API,请看这里

大致总结一下就是:

  1. tf.summary.scalar(name, tensor, collections=None,  family=None) tensor为单一的标量。
  2. tf.summary.histogram(name, values, collections=None,  family=None) values为任意shape的数字型tensor。
  3. tf.summary.image(name, tensor, max_outputs=3, collections=None,  family=None) tensor的shape为[batch_size, height, width, channels],其中channels=1表示灰度图,3表示RGB,4表示RGBA。注意max_outputs默认为3表示每轮默认显示三张图。
  4. tf.summary.audio( name, tensor, sample_rate, max_outputs=3, collections=None,  family=None) tensor为3D shape [batch_size, frames, channels],或者2D shape [batch_size, frames];sample_rate表示声音类型信号tensor的采样率,大小在[-1.0,1.0]之间。
  5. tf.summary.text(name, tensor, collections=None) 将文本数据转换为string类型的tensor。
  6. tf.summary.merge(inputs, collections=None, name=None) 将inputs里面的summary汇集在一起,其中inputs为string类型tensor的列表。
  7. tf.summary.merge_all( key=tf.GraphKeys.SUMMARIES, scope=None) 把所有的summary汇集在一起。
  8. tf.summary.FileWriter(logdir, sess.graph) 把summary protocol buffers 写进 tfevents文件里。
  9. tf.summary.tensor_summary( name, tensor, summary_description=None, collections=None, summary_metadata=None, family=None, display_name=None) 将任意shape和类型的tensor序列化,并返回一个string类型的tensor。

总结:通过上面的试验,其实tensorboard是一个日志展示系统,因此首先用户需要对各种类型的单个数据提出监测(记录日志),并在session中运算图时,将各种类型的数据汇总并输出到日志文件中。而后启动tensorboard服务,读取这些记录的日志文件,开启6006端口在Web上实时监测用户汇总的数据。

人人都说,创作需要灵感,甚至需要一些情愫,感动的、真诚的、又或是善意的,这就是生活,如果我们能把工作和学习当作是创作一样,又有什么遗憾呢?

通俗易懂之Tensorflow summary类 & 初识tensorboard的更多相关文章

  1. TensorFlow深度学习笔记 Tensorboard入门

    转载请注明作者:梦里风林 Github工程地址:https://github.com/ahangchen/GDLnotes 欢迎star,有问题可以到Issue区讨论 官方教程: https://ww ...

  2. Tensorflow Summary用法

    本文转载自:https://www.cnblogs.com/lyc-seu/p/8647792.html Tensorflow Summary用法 tensorboard 作为一款可视化神器,是学习t ...

  3. JDK1.8新特性之Stream类初识

    JDK1.8新特性之Stream类初识 import java.util.Arrays; import java.util.List; import java.util.Optional; impor ...

  4. 第七节,TensorFlow编程基础案例-TensorBoard以及常用函数、共享变量、图操作(下)

    这一节主要来介绍TesorFlow的可视化工具TensorBoard,以及TensorFlow基础类型定义.函数操作,后面又介绍到了共享变量和图操作. 一 TesnorBoard可视化操作 Tenso ...

  5. 初识Tensorboard

    1.什么是Tensorboard? PPT设计原则中有这样一条,叫"文不如表,表不如图",可见图表在表达中更为直观.明确.程序设计中也是一样,我们经常用图表来描述程序的结构和流程, ...

  6. TensorFlow框架(2)之TensorBoard详解

    为了更方便 TensorFlow 程序的理解.调试与优化,TensorFlow发布了一套叫做 TensorBoard 的可视化工具.你可以用 TensorBoard 来展现你的 TensorFlow ...

  7. 【TensorFlow篇】--Tensorflow框架可视化之Tensorboard

    一.前述 TensorBoard是tensorFlow中的可视化界面,可以清楚的看到数据的流向以及各种参数的变化,本文基于一个案例讲解TensorBoard的用法. 二.代码 设计一个MLP多层神经网 ...

  8. TensorFlow基础笔记(9) Tensorboard可视化显示以及查看pb meta模型文件的方法

    参考: http://blog.csdn.net/l18930738887/article/details/55000008 http://www.jianshu.com/p/19bb60b52dad ...

  9. 超简单tensorflow入门优化程序&&tensorboard可视化

    程序1 任务描述: x = 3.0, y = 100.0, 运算公式 x×W+b = y,求 W和b的最优解. 使用tensorflow编程实现: #-*- coding: utf-8 -*-) im ...

随机推荐

  1. 第十八次ScrumMeeting博客

    第十八次ScrumMeeting博客 本次会议于12月8日(五)22时整在3公寓725房间召开,持续20分钟. 与会人员:刘畅.辛德泰.张安澜.赵奕.方科栋. 1. 每个人的工作(有Issue的内容和 ...

  2. 20135337朱荟潼 Linux第七周学习总结——可执行程序的装载

    朱荟潼 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 第七周 Linu ...

  3. wordpress学习四: 一个简单的自定义主题

    在学习三里分析了自带的一个例子,本节我们就自己仿照他做个简单的吧,重点是调用wordpress封装好的函数和类,css和html可以稍好在调整. 将wp带的例子复制一份处理,重新名个名字. 清空ind ...

  4. C#回调函数的简单讲解与应用例子(最简单讲解,大神绕道)

    本博客一直以来的宗旨就是:用最简单的方式讲清楚不复杂的问题. 因为本人也很菜所以也没法讲太复杂HHHHHH...... 所以如果哪天某个大神看到了觉得讲的有问题欢迎指出. 话不多说进入正题.. ——— ...

  5. # 蜗牛慢慢爬 LeetCode 21. Merge Two Sorted Lists [Difficulty: Easy]

    题目 Merge two sorted linked lists and return it as a new list. The new list should be made by splicin ...

  6. [转帖]Windows 内置端口转发功能

    如何在Windows中使用netsh命令进行端口转发 https://www.freebuf.com/articles/system/176889.html 早上自己做了下实验,的确可以.linux下 ...

  7. [转帖]你们知道LTE Cat.1到Cat.10 那Cat.0呢?

    你们知道LTE Cat.1到Cat.10 那Cat.0呢? https://network.pconline.com.cn/638/6389637_all.html#content_page_3 1大 ...

  8. const和typedef的常见用法详解

    一.说说const 一般而言,const主要是用来防止定义的对象再次被修改,定义对象变量时要初始化变量. 常见用法如下: 1.用于定义常量变量,这样这个变量在后面就不可以再被修改 const int ...

  9. 通过动态包含和Ajax机制抽取Web应用的公共页面

    在Java Web应用开发中,经常遇到的一种情况是,许多的页面中都包含着“公共页面”,这部分动态页面的特征是:访问量大,会带来较大的性能压力.功能设计上会动态地改变自身的元素.比如在登录前和登录后所展 ...

  10. python 实现二叉树的深度 & 广度优先遍历

    什么是树 在计算器科学中,树(英语:tree)是一种抽象数据类型(ADT)或是实现这种抽象数据类型的数据结构,用来模拟具有树状结构性质的数据集合.它是由n(n>0)个有限节点组成一个具有层次关系 ...