本次的代码内容完全在上次的基础上增加,建议对照两次的源码一起看:
上次推送对应源码:
https://github.com/SaoYan/LearningTensorflow/blob/master/exp4_CNN_mnist.py
https://github.com/SaoYan/LearningTensorflow/blob/master/exp7_TensorBoard.py
中文文档参考内容:
(1) http://www.tensorfly.cn/tfdoc/how_tos/summaries_and_tensorboard.html
(2) http://www.tensorfly.cn/tfdoc/how_tos/graph_viz.html
GitHub README:
https://github.com/tensorflow/tensorboard/blob/master/README.md
Tensorboard可视化效果
在开始介绍代码之前,首先看一下最终效果。
1. Computational Graph
计算图的可视化可以用来非常直观的检验模型结构是否是你预想的那样。
本次代码构造的计算图如下:
请大致记住每个模块的名字,它们都是可以在代码中随意定制的,所以后面请注意代码和计算图的对应关系。
选中其中一个模块,右上角会显示这个模块输入、输出的Tensor结构。
现在双击hidden_1,将其展开,可以看到内部更加详细的细节(最基本的卷积、池化、Relu操作等)。
2. Learning Curve
随着训练的进行,loss、分类准确率等如何变化的?
你可以将任意你想观测的内容添加进Tensorboard。
左侧会显示图例。在Tensorboard载入的目录下有两个子目录 “test”和“train”
各个子目录会自动分开载入,各自可视化。因此图例就是:
分类准确率变化曲线:
可以选择进行平滑:
可以zoom in:
3. Images
在MNIST这个例子里面,可视化图像似乎没有什么用。但是试想一些其他任务:GAN作图像生成;深度学习图像降噪。这时候观测图像的变化就很有用了。
本例程中的可视化效果如下:
4. Distribution
每一层卷积都有一组filters,有很多的权值,这些值的分布情况也可以进行可视化。
这部分可视化其实就是将很多Tensor(权值)对象加入Tensorboard里面,那么我们可以很自然地想到,如果将每一层梯度的分布可视化出来,可以检测梯度爆炸/消失的情况。
本例程只简单可视化了权值。Tensorboard会用两中方式显示分布的可视化:
第一种:最常见的直方图
第二种:
我也不知道应该给第二种图起什么名字。选其中一个来解释一下这个图的含义:
忽略填色,可以看到图中其实有九条曲线,他们分别反映了这组数据中9个统计特征值的变化:[maximum, μ+1.5σ, μ+σ, μ+0.5σ, μ, μ-0.5σ, μ-σ, μ-1.5σ, minimum]。
然后再来看填色区域,总中间那条曲线(μ)往两侧看,区域宽度分别是σ, 2σ, 3σ。
这幅图的统计含义不需要我再多说了把。
如何沟通Tensorboard?
我们用到的核心类是:tf.summary
添加learning curve:tf.summary.scalar
添加图像:tf.summary.image
添加distribution:tf.summary.histogram
大致的步骤是:
1. 调用tf.summary将目标添加到Tensorboard。这个步骤在计算图的定义过程实现。
2. 汇总全部的summary。第一步会导致你添加目标的代码分散在各处,如果将它们一个个记录,会十分繁琐,还容易遗漏。Tensorflow很贴心的提供了一个函数:tf.summary.merge_all()。直接用它的返回值进行后续操作就可以同时处理代码中添加进summary的全部对象。
3. 用Session运行,并且将结果写入文件
接下来,我们将在上一次推送的代码基础上做修改,完成对Tensorboard的配置。
模型定义部分
上次推送中,网路结构定义部分是这样的:
前面展示了计算图的可视化效果,并且提示了大家要注意看代码和图的对应关系:
要构造这样一幅计算图图,我们需要将网络结构分成若干模块,也就是把各个层划分开。
input_data模块
这里定义了输入数据的placeholder对象。我们需要将输入数据添加到Tensorboard的图像可视化部分。
with tf.name_scope('input_data')
这句代码就是让计算图模块化的关键,计算图各个模块显示的名称与代码相对应。
tf.summary.image('input', x_image, max_outputs=10)
这句代码将输入的图像数据添加到了summary之中,并且一批数据最多添加10张图。它们将显示在Tensorboard中。
hidden_1模块
这是第一个卷积层,我们需要将权值添加到Tensorboard的distribution可视化部分。
其余的卷积层、全连接层都类似。总体的代码就成了这个样子:
loss function和优化器定义部分
上次推送中,这部分代码是这样的:
现在,我们依然把它们模块化,并且将loss和accuracy添加进Tensorboard(learning curve)。
运行Session
这部分主要添加的代码是这两部分:
(1)汇总全部summary,并定义写入summary的文件
(2)将每一步结果写入文件
和其他部分一样,这里的placeholder也需要用具体数据补全。(对Tensorflow基本代码结构生疏的同志们可以去看前面几期推送)
载入Tensorboard
使用以上代码训练完成后,会产生一下层级结构的文件夹:
/MNIST_logs/train/
/MNIST_logs/test/
这两个路径里面分别是在训练集、测试集上的结果,在Tensorboard里面会分别显示,并用不同颜色的图例区分开。
现在,在MNIST_logs文件夹的父路径打开命令行,输入以下命令:
tensorboard --logdir MNIST_logs
结果如下:
在浏览器里打开这里给出的地址(http://sao:6006)就进入到了Tensorboard,代码中指定的全部内容都会在这里显示。
一点总结
这次推送没有对代码内容做太多的解读,因为全部针对Tensorboard补充的代码都是很模式化的,只要按照规则写就行,没有过多灵活的变化。
只看本次推送肯定无法获取全部信息,建议亲自跑一跑代码,打开Tensorboard体验一下它的交互界面。
Tensorboard的设计十分友好,在机器学习的调试中又能助力不少。可以说,是Tensorflow相比于其他所有框架的一个主要优势之一。
说一句题外话:其他热门框架,例如PyTorch,都有开源社区贡献的脚本可以沟通Tensorboard,但是功能都是“阉割”过的。例如主页菌至今没有找到可视化PyTorch计算图的好方法。
领取专属 10元无门槛券
私享最新 技术干货