官方介绍:https://tensorflow.google.cn/guide/summaries_and_tensorboard
一、关于tensorboard的问题
通过pip安装tensorflow的时候会自动安装tensorboard,如果后续出现版本不对的情况,需要根据安装的tensorflow的版本来安装对应的tensorboard。
TensorBoard 通过读取 TensorFlow 的事件文件来运行,事件文件可以通过tf.summary.FileWrite类来创建,TensorFlow 的事件文件包含运行 TensorFlow 时生成的总结数据,总结数据可以用tf.summary模块中的方法来创建。
在事件文件创建好之后,要在终端模式中启动tensorbaord,例如windows系统中在cmd中用命令:tensorboard --logdir=path ,其中path为事件文件所在的目录的地址,具体如下图:
然后通过返回的网址http://DESKTOP-4K4SA9I:6006,在浏览器中输入对应的网址即可,建议用google浏览器,最后退出可视化的时候需要关闭终端的tensorboard运行。
来看一下tf.summary.FileWriter的构造函数:
tf.summary.FileWriter.__init__(self,logdir,graph=None,max_queue=10,flush_secs=120,graph_def=None):
Creates a `FileWriter` and an event file.
Args:
logdir: A string. Directory where event file will be written.(指定事件文件的地址)
graph: A `Graph` object, such as `sess.graph`.(指定是那个图的的事件)
max_queue: Integer. Size of the queue for pending events and summaries.
flush_secs: Number. How often, in seconds, to flush the pending events and summaries to disk.
graph_def: DEPRECATED: Use the `graph` argument instead.
tf.summary.FileWriter有一个方法FileWriter.add_summary,可以将训练过程数据保存在filewriter指定的文件中。
二、结合命名空间来使用tensorboard构建网络图
1、未使用命名空间的tensorboard可视化
为使用命名空间的可视化效果会比较乱,这里先来看一下,这里只在正常代码中加入了writer=tf.summary.FileWriter(r'C:\Users\EDZ\.PyCharm2019.1\config\scratches\tf_board',sess.graph)。
代码:
import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data #读取手写字数据 mnist=input_data.read_data_sets(r'C:\Users\EDZ\.PyCharm2019.1\config\scratches\MNIST_data',one_hot=True) #设定每次迭代的数据大小 batch_size=100 n_batch=mnist.train.num_examples//batch_size #站位符号 x=tf.placeholder(tf.float32) y=tf.placeholder(tf.float32) #第一层输入784输出为10 w1=tf.Variable(tf.truncated_normal([784,10]),name='w1') b1=tf.Variable(tf.zeros([1,10])+0.001) z1=tf.matmul(x,w1)+b1 input1=tf.nn.softmax(z1) #代价函数 loss=tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y,logits=input1)) #Adam梯度下降优化训练loss train=tf.train.AdamOptimizer(0.001,0.9,0.999).minimize(loss) #初始化 init=tf.global_variables_initializer() #结果存放在bool型列表汇总 correct_prediction=tf.equal(tf.argmax(y,1),tf.argmax(input1,1)) #计算准确度 accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) with tf.Session() as sess: sess.run(init) #储存事件文件到指定位置 writer=tf.summary.FileWriter(r'C:\Users\EDZ\.PyCharm2019.1\config\scratches\tf_board',sess.graph) #训练10代 for epoch in range(10): # 每代对数据进行一轮minibatch for batch in range(n_batch): batch_x, batch_y = mnist.train.next_batch(batch_size) # 每个循环读取batch_size大小批次的数据 sess.run(train, feed_dict={x: batch_x, y: batch_y}) acc = sess.run(accuracy, feed_dict={x: mnist.test.images, y: mnist.test.labels}) # 用测试数据计算准确度 if batch%99==0: print('第%d代%d批次,准确率为%.6f' % (epoch + 1, batch + 1, acc))
启动tensorboard:
在浏览器中打开:
可以看到虽然每个节点的详细内容都有展现,但是非常的乱,这就是没有使用命名空间的缺陷。
2、使用命名空间的tensorboard可视化
代码:
import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data #读取手写字数据 mnist_data=input_data.read_data_sets(r'C:\Users\EDZ\.PyCharm2019.1\config\scratches\MNIST_data',one_hot=True) #设定每次迭代的数据大小 batch_size=100 n_batch=mnist_data.train.num_examples//batch_size #站位符号 x=tf.placeholder(tf.float32) y=tf.placeholder(tf.float32) #第一层输入784输出为10 with tf.name_scope(name='layer1'): w1=tf.Variable(tf.truncated_normal([784,10]),name='w1') b1=tf.Variable(tf.zeros([1,10])+0.001) z1=tf.matmul(x,w1)+b1 input1=tf.nn.softmax(z1) #代价函数 with tf.name_scope(name='loss'): loss=tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y,logits=input1)) #Adam梯度下降优化训练loss train=tf.train.AdamOptimizer(0.001,0.9,0.999).minimize(loss) #初始化 init=tf.global_variables_initializer() #结果存放在bool型列表汇总 correct_prediction=tf.equal(tf.argmax(y,1),tf.argmax(input1,1)) #计算准确度 accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) with tf.Session() as sess: sess.run(init) #储存事件文件到指定位置 writer=tf.summary.FileWriter(r'C:\Users\EDZ\.PyCharm2019.1\config\scratches\tf_board',sess.graph) #训练10代 for epoch in range(10): # 每代对数据进行一轮minibatch for batch in range(n_batch): batch_x, batch_y = mnist_data.train.next_batch(batch_size) # 每个循环读取batch_size大小批次的数据 sess.run(train, feed_dict={x: batch_x, y: batch_y}) acc = sess.run(accuracy, feed_dict={x: mnist_data.test.images, y: mnist_data.test.labels}) # 用测试数据计算准确度 if batch%99==0: print('第%d代%d批次,准确率为%.6f' % (epoch + 1, batch + 1, acc))
启动tensorboard:
在浏览器中打开:
可见在在配合命名空间使用之后,整个图层变得更加的简洁,因为命名空间把分散的节点组合在一起,同时点击组合起来的部分也能看到里面的细节。
三、tensorflow的总结指令
1、总结指令的作用
第二节讲了如果用tensorboard来可视化网络图,如果我们正在训练一个卷积神经网络,用于识别 MNIST 数据,我们可能希望记录随着时间的推移,学习速度如何变化,以及目标函数如何变化,这就需要用到tensorflow的总结指令了,我们这里主要使用总结指令中的tf.summary.scaclar、tf.summary.histogram函数。
2、函数介绍
tf.summary.scaclar(name,values,collections=None,family=None)
- name:名称。
- values:一个数值tensor,用来在直方图中构建直方图。
作用:将记录的标量数据用来构建折线图。
tf.summary.histogram(name,values,collections=None,family=None)
- name:名称。
- values:一个数值tensor,用来在直方图中构建分布直方图。
作用:将记录的tensor数据用来构建分布直方图。
3、注意事项
当创建好总结指令后,如果我们要运行这些指令才能获得对应总结节点总结数据,如果我们的总结节点多,要一个一个运行会很麻烦,所以一般用tf.summary.merge_all函数将所有的节点合并成一个节点,然后只要运行一次该节点即可。
注意,节点每次只能记录或添加一个数据,当我们要画出准确度折线图的时候,我们需要在不同的迭代步数中都运行一次总结指令,这样才可以记录不同迭代步数的总结数据,然后才能画出对应的图。
4、代码示例
代码说明:
这里只在loss和accuracy中添加了总结指令,用tf.summary.merge_all合并,最后用FileWriter.add_summary添加到指定的时间文件中。
代码:
import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data # 读取手写字数据 mnist_data = input_data.read_data_sets(r'C:\Users\EDZ\.PyCharm2019.1\config\scratches\MNIST_data', one_hot=True) # 设定每次迭代的数据大小 batch_size = 100 n_batch = mnist_data.train.num_examples // batch_size # 站位符号 x = tf.placeholder(tf.float32) y = tf.placeholder(tf.float32) # 创建总结函数,用来记录总结数据 def variable_summaries(var): mean = tf.reduce_mean(var) tf.summary.scalar('mean', mean) # 总结平均值 tf.summary.scalar('stddev', tf.sqrt(tf.reduce_mean(tf.square(var - mean)))) # 总结方差 tf.summary.histogram('histogram', var) # 总结分布直方图数据 # 第一层输入784输出为10 with tf.name_scope(name='layer1'): w1 = tf.Variable(tf.truncated_normal([784, 10]), name='w1') b1 = tf.Variable(tf.zeros([1, 10]) + 0.001) z1 = tf.matmul(x, w1) + b1 input1 = tf.nn.softmax(z1) # 代价函数,并加入总结总结指令 with tf.name_scope(name='loss'): loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y, logits=input1)) variable_summaries(loss) # 加入总结中 # Adam梯度下降优化训练loss with tf.name_scope(name='train'): train = tf.train.AdamOptimizer(0.001, 0.9, 0.999).minimize(loss) # 初始化 init = tf.global_variables_initializer() # 结果存放在bool型列表汇总 correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(input1, 1)) # 计算准确度,并加入到总结指令 with tf.name_scope(name='accuracy'): accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) variable_summaries(accuracy) merge_all = tf.summary.merge_all() with tf.Session() as sess: sess.run(init) # 储存事件文件到指定位置 writer = tf.summary.FileWriter(r'C:\Users\EDZ\.PyCharm2019.1\config\scratches\tf_board', sess.graph) # 训练20代 for epoch in range(20): # 每代对数据进行一轮minibatch for batch in range(n_batch): batch_x, batch_y = mnist_data.train.next_batch(batch_size) # 每个循环读取batch_size大小批次的数据 # 每次迭代中同时执行merge_all与train,表示每一步迭代训练都进行总结, # 因为run有两个节点,所以会返回对应两个节点的结果值,而我们只要merge_all的值所以另一个用占位符_代替 summaries, _ = sess.run([merge_all, train], feed_dict={x: batch_x, y: batch_y}) # acc = sess.run(accuracy, feed_dict={x: mnist_data.test.images, y: mnist_data.test.labels}) # 用测试数据计算准确度 # if batch % 99 == 0: # print('第%d代%d批次,准确率为%.6f' % (epoch + 1, batch + 1, acc)) # 每个epoch迭代完之后将总结数据加入到事件文件中 writer.add_summary(summaries, epoch)
启动tensorboard:
在浏览器中打开:
scalar图是总计记录的标量画出来的折线图,实线为平滑之后的曲线,虚线为真实曲线,平滑程度可以通过左侧的Smoothing来调节。注意:如果loss数据波动较大,可能是学习率过大造成的。
DISTRIBUTIONS
主要用来展示网络中各参数随训练步数的增加的变化情况,可以说是 多分位数折线图 的堆叠。一般是用来观测权重weight与偏置biase的。
histogram是分布直方图,用来观测数据的分布变化的。