Tensorboard作为tensorflow的可视化工具,目的就是为了方便tensorflow程序的理解、调试和优化。TensorBoard通过读取Tensorflow 的事件文件来运行。Tensorflow的事件文件中包括运行中涉及到的主要数据。
使用TensorBoard展示数据,需要在执行Tensorflow的计算图中,将各种类型的数据汇总并记录到日志文件中。然后使用TensorBoard读取这些日志文件,解析数据并生产数据可视化的Web页面,让我们可以在浏览器中观察各种汇总数据。
# 记录和汇总标量数据,如学习率,损失函数 tf.summary.scalar(tags, values, collections=None, name=None) # example 对交叉熵结果进行统计汇总 tf.summary.scalar('cross_entropy', cross_entropy) # 记录变量var的直方图,输出带直方图的汇总的protobuf,如各层网络权重,偏置的分布 tf.summary.histogram(tag, values, collections=None, name=None) # example w_1 = tf.summary.histogram('weights_1', w1) # 输出带图像的probuf, 汇总数据的图像的形式如下:‘tag/image/0’,'tag/image/1'... # tensor,必须是4维,格式为[batch_size, height, width, channels] tf.summary.image(tag, tensor, max_images=3, collections=None, name=None) # 将上述几种类型的汇总再进行一次合并,具体合并哪些由inputs指定 tf.summary.merge(inputs, collections=None, name=None) # 将之前定义的所有sumamy_op汇总到一起,以便后面执行 tf.summary.merge_all(key='summaries') # 创建一个file writer用来向硬盘写summary数据 train_writer = tf.summary.FileWriter(your_dir, session.graph)
我写了一个小程序练习,人工地生成了一些线性数据,初始化参数,算出预测值,计算预测值与真实值之间的L1范数作为损失值,训练更新参数。参数比较简单,就是一元线性直线的斜率。
import tensorflow as tf
import numpy as np
import os
NUM_DATA = 10000
BATCH = 100
iteration = 1000
learning_rate = 0.0001
def _init():
# 构建数据
x_data = np.arange(NUM_DATA) / 100
true_slope = 2
y_data = x_data * true_slope
return x_data, y_data
def train(x_data, y_data):
with tf.name_scope('inputs'):
x = tf.placeholder(tf.float32, [None], name='x_input')
y = tf.placeholder(tf.float32, [None], name='y_input')
with tf.name_scope('weights'):
m = tf.Variable(tf.random_normal([1],stddev=0.1, dtype=tf.float32), name='slope')
tf.summary.histogram('weights', m)
# 输出预测值
y_output = tf.multiply(m, x)
# 损失函数
with tf.name_scope('loss_function'):
loss = tf.reduce_mean(tf.abs(y_output - y), name='L1_loss')
tf.summary.scalar('loss_value', loss)
with tf.name_scope('train_step'):
optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss)
merged_op = tf.summary.merge_all()
with tf.Session() as session:
session.run(tf.global_variables_initializer())
train_writer = tf.summary.FileWriter('F:\\Code\\logs', session.graph)
if not os.path.exists('logs'):
os.makedirs('logs')
for i in range(iteration):
batch_index = np.random.choice(NUM_DATA, size=BATCH, replace=False)
batch_x, batch_y = x_data[batch_index], y_data[batch_index]
_, train_loss, summary = session.run([optimizer, loss, merged_op],
feed_dict={x: batch_x, y: batch_y})
# print('step:', i, train_loss)
train_writer.add_summary(summary, i)
train_writer.close()
def main(argv=None):
x_data, y_data = _init()
train(x_data, y_data)
if __name__ == '__main__':
tf.app.run()
运行程序后,your_dir目录下就有最新的日志文件,接下来,启动tensorboard。
在cmd中,按照网上教程是输入命令tensorboard --logdir=your_dir,ENTER后最后一行会出现一个网址链接http://your_computer_name:6006,复制链接,在google浏览器(推荐)中粘贴链接地址,当时网页并不能显示,给出错误‘拒绝请求’,‘找不到ip地址’等等一系列错误,查了好久的解决方案,大部分皆是说可以输入http://localhost:6006或者http://127.0.0.1:6006,然而还是不能显示网页,纠结了好久,最后找到救星,解决方案为:输入tensorboard -- logdir==training:your_log_dir --host=127.0.0.1,接下来就可以在浏览器中输入http://127.0.0.1:6006,就出现如下界面,说明成功打开。如果日志目录下包含程序多次运行的数据(多个event),那么tensorboard会展示所有的数据,然后图形就会显得很杂乱。
下图是训练的流程图,当然这个图还可以再展开,里面有更详细的流动。建议使用命名空间美化计算图,命名空间会使得可视化效果图更加具有层次感。可以通过tf.name_scope()或者tf.variable_scope()来实现。
上图是训练过程中的损失函数值。可以从上图中看出,损失值在前400步之前,呈下降趋势,逐渐减少,后面600步几乎不变,趋近于零。如下图所示,相应的斜率参数也在前400步呈递增趋势,在后面600步时趋近于2,真实的斜率,说明学习正确。
从上图中,就可以看出,运行500步就可以得到接近于真实斜率的斜率m。
结语:
用到大型复杂的神经网络,就能可视化网络的结构,是如何训练的,从而更好地调试并优化程序。
在此,提供一个卷积神经网络CNN应用在数据集CIFAR-10上的分类代码,https://github.com/skloisMary/CIFAR-10.git,此代码是在官方文档中给出的代码基础上进行修改,仅仅在一块GPU上进行运算,代码相对简洁了许多,但是我加入自己的理解和注释。训练迭代了50000次(epochs),准确率在85%~90%之间,验证集的准确率为82.1%