在TensorFlow中,最常用的可视化方法有三种途径,分别为TensorFlow与OpenCv的混合编程、利用Matpltlib进行可视化、利用TensorFlow自带的可视化工具TensorBoard进行可视化。这三种方法中,TensorFlow中最重要的可视化方法是通过tensorBoard、tf.summary和tf.summary.FileWriter这三个模块相互合作来完成的。
TensorBoard是TensorFlow官方推出的可视化工具,它可以将模型训练过程中的各种汇总数据展示出来,包括标量(Scalar)、图片(Images)、音频(Audio)、计算图(Graphs)、数据分布(Distributions)、直方图(Histograms)和嵌入向量(Embeddings)。在训练大型深度学习神经网络时,中间计算过程非常复杂,为了理解调试和优化我们设计的网络,我们可以使用TensorBoard观察训练过程中各种可视化数据。如果要使用TensorBoard展示数据,我们需要在执行TensorFlow计算图的过程中,将各种类型的数据汇总并记录到日志文件中。然后使用TensorBoard读取这些日志文件,解析数据并生成可视化的Web界面,让我们可以在浏览器中观察各种汇总的数据。
(1)tf.summary.scalar():用来显示标量信息,其格式为:
tf.summary.scalar(name, tensor, collections=None)
例如:tf.summary.scalar('mean', mean)
一般在画loss,accuary时会用到这个函数。
(2)tf.summary.histogram():用来显示直方图信息,其格式为:
tf.summary.histogram(tags, values, collections=None, name=None)
例如: tf.summary.histogram('histogram', var)
一般用来显示训练过程中变量的分布情况
(3)tf.summary.distribution():分布图,一般用于显示weights分布
(4)tf.summary.text ():可以将文本类型的数据转换为tensor写入summary中:
例如:
text = """/a/b/c\\_d/f\\_g\\_h\\_2017"""
summary_op0 = tf.summary.text('text', tf.convert_to_tensor(text))
(5)tf.summary.image():输出带图像的probuf
汇总数据的图像的的形式如下: ’ tag /image/0’, ’ tag /image/1’…,如:input/image/0等。
格式:tf.summary.image(name, tensor, max_outputs=3, collections=None)
(6)tf.summary.audio():展示训练过程中记录的音频
(7)tf.summary.merge_all():merge_all 可以将所有summary全部保存到磁盘,以便tensorboard显示。
如果没有特殊要求,一般用这一句就可一显示训练时的各种信息了。
格式:tf.summaries.merge_all(key='summaries')
(8)tf.summary.FileWriter():指定一个文件用来保存图。
格式:tf.summary.FileWritter(path,sess.graph)
可以调用其add_summary()方法将训练过程数据保存在filewriter指定的文件中
Tensorflow Summary 用法示例:
tf.summary.scalar('accuracy',acc) #生成准确率标量图
merge_summary = tf.summary.merge_all()
train_writer = tf.summary.FileWriter(dir,sess.graph)#定义一个写入summary的目标文件,dir为写入文件地址
......(交叉熵、优化器等定义)
for step in xrange(training_step): #训练循环
train_summary = sess.run(merge_summary,feed_dict = {...})#调用sess.run运行图,生成一步的训练过程数据
train_writer.add_summary(train_summary,step)#调用train_writer的add_summary方法将训练过程以及训练步数保存
此时到日志的目录下启动CMD,开启tensorborad:tensorboard –logdir=./
便能看见accuracy曲线了。另外,如果我不想保存所有定义的summary信息,也可以用tf.summary.merge方法有选择性地保存信息
(9)tf.summary.merge():有选择性地保存信息
格式:tf.summary.merge(inputs, collections=None, name=None)
一般选择要保存的信息还需要用到tf.get_collection()函数
示例:
tf.summary.scalar('accuracy',acc) #生成准确率标量图
merge_summary = tf.summary.merge([tf.get_collection(tf.GraphKeys.SUMMARIES,'accuracy'),...(其他要显示的信息)])
train_writer = tf.summary.FileWriter(dir,sess.graph)#定义一个写入summary的目标文件,dir为写入文件地址
......(交叉熵、优化器等定义)
for step in xrange(training_step): #训练循环
train_summary = sess.run(merge_summary,feed_dict = {...}) #调用sess.run运行图,生成一步的训练过程数据
train_writer.add_summary(train_summary,step) #调用train_writer的add_summary方法将训练过程以及训练步数保存
使用tf.get_collection函数筛选图中summary信息中的accuracy信息,这里的tf.GraphKeys.SUMMARIES 是summary在collection中的标志。当然,也可以直接:
acc_summary = tf.summary.scalar('accuracy',acc) #生成准确率标量图
merge_summary = tf.summary.merge([acc_summary ,...(其他要显示的信息)]) #这里的[]不可省
#coding=utf-8
import tensorflow as tf
import pickle
import numpy as np
max_steps=1000 # 最大迭代次数
learning_rate=0.001 # 学习率
dropout=0.9 # dropout概率
log_dir="E:/testdata/mnist_log" # 保存训练日志的目录,给TensorBoard使用
# 定义一个mnist数据集的类
class mnistReader():
def __init__(self,mnistPath,onehot=True):
self.mnistPath=mnistPath
self.onehot=onehot
self.batch_index=0
print ('read:',self.mnistPath)
fo = open(self.mnistPath, 'rb')
self.train_set,self.valid_set,self.test_set = pickle.load(fo,encoding='bytes')
fo.close()
self.data_label_train=list(zip(self.train_set[0],self.train_set[1]))
np.random.shuffle(self.data_label_train)
# 获取下一个训练集的batch
def next_train_batch(self,batch_size=100):
if self.batch_index < len(self.data_label_train)/batch_size:
print ("batch_index:",self.batch_index )
datum=self.data_label_train[self.batch_index*batch_size:(self.batch_index+1)*batch_size]
self.batch_index+=1
return self._decode(datum,self.onehot)
else:
self.batch_index=0
np.random.shuffle(self.data_label_train)
datum=self.data_label_train[self.batch_index*batch_size:(self.batch_index+1)*batch_size]
self.batch_index+=1
return self._decode(datum,self.onehot)
# 获取测试集的数据
def test_data(self):
tdata,tlabel=self.test_set
data_label_test=list(zip(tdata,tlabel))
return self._decode(data_label_test,self.onehot)
# 把一个batch的训练数据转换为可以放入模型训练的数据
def _decode(self,datum,onehot):
rdata=list() # batch训练数据
rlabel=list()
if onehot:
for d,l in datum:
rdata.append(np.reshape(d,[784])) # 转变形状为:一维向量
hot=np.zeros(10)
hot[int(l)]=1 # label设为100维的one-hot向量
rlabel.append(hot)
else:
for d,l in datum:
rdata.append(np.reshape(d,[784]))
rlabel.append(int(l))
return rdata,rlabel
sess=tf.InteractiveSession()
# 定义占位符,x是训练数据,y_是label
with tf.name_scope('input'):
x=tf.placeholder(tf.float32,[None,784],name='x-input')
y_=tf.placeholder(tf.float32,[None,10],name='y-input')
# 对输入图像转换形状为一通道
with tf.name_scope('input_reshape'):
image_reshaped_input=tf.reshape(x,[-1,28,28,1])
tf.summary.image('input',image_reshaped_input,10) # 图片汇总给TensorBoard,写入10张图片
# 权重初始化函数
def weight_variable(shape):
initial=tf.truncated_normal(shape,stddev=0.1)
return tf.Variable(initial)
# 偏置初始化函数
def bias_variable(shape):
initial=tf.constant(0.1,shape=shape)
return tf.Variable(initial)
# 变量的数据汇总函数:均值、方差、最大值、最小值、直方图
def variable_summaries(var):
with tf.name_scope('summaries'):
mean=tf.reduce_mean(var)
tf.summary.scalar('mean',mean)
with tf.name_scope('stddev'):
stddev=tf.sqrt(tf.reduce_mean(tf.square(var-mean)))
tf.summary.scalar('stddev',stddev)
tf.summary.scalar('max',tf.reduce_max(var))
tf.summary.scalar('min',tf.reduce_min(var))
tf.summary.histogram('histogram',var)
# 定义多层感知机,对权重、偏置、激活前、激活后数据进行汇总
def nn_layer(input_tensor,input_dim,output_dim,layer_name,act=tf.nn.relu):
with tf.name_scope(layer_name):
with tf.name_scope('weights'):
weights=weight_variable([input_dim,output_dim])
variable_summaries(weights)
with tf.name_scope('biases'):
biases=bias_variable([output_dim])
variable_summaries(biases)
with tf.name_scope('Wx_plus_b'):
preactivate=tf.matmul(input_tensor,weights)+biases
tf.summary.histogram('pre_activations',preactivate)
activations=act(preactivate,name='activation')
tf.summary.histogram('activations',activations)
return activations
# 定义第一个隐藏层
hidden1=nn_layer(x,784,500,'layer1')
# 定义Dropout层并汇总Dropout
with tf.name_scope('dropout'):
keep_prob=tf.placeholder(tf.float32)
tf.summary.scalar('dropout_keep_probability',keep_prob)
dropped=tf.nn.dropout(hidden1,keep_prob)
# 定义全连接层
y=nn_layer(dropped,500,10,'layer2',act=tf.identity)
# 定义交叉熵并汇总
with tf.name_scope('cross_entropy'):
diff=tf.nn.softmax_cross_entropy_with_logits(logits=y,labels=y_)
with tf.name_scope('total'):
cross_entropy=tf.reduce_mean(diff)
tf.summary.scalar('cross_entropy',cross_entropy)
# 定义优化器
with tf.name_scope('train'):
train_step=tf.train.AdamOptimizer(learning_rate).minimize(cross_entropy)
# 定义准确率并汇总
with tf.name_scope('accuracy'):
with tf.name_scope('correct_prediction'):
correct_prediction=tf.equal(tf.argmax(y,1),tf.argmax(y_,1))
with tf.name_scope('accuracy'):
accuracy=tf.reduce_mean(tf.cast(correct_prediction,tf.float32))
tf.summary.scalar('accuracy',accuracy)
# 把所有的汇总信息进行合并
merged=tf.summary.merge_all()
# 定义训练和测试的日志文件写入器
train_writer=tf.summary.FileWriter(log_dir+'/train',sess.graph)
test_writer=tf.summary.FileWriter(log_dir+'/test')
mnist=mnistReader(mnistPath="E:/testdata/mnist.pkl")
tf.global_variables_initializer().run()
# 定义填充真数据字典的函数
def feed_dict(train):
if train:
xs,ys=mnist.next_train_batch()
k=dropout
else:
xs,ys=mnist.test_data()
k=1.0
return {x:xs,y_:ys,keep_prob:k}
# 保存训练结果的saver
saver=tf.train.Saver()
# 开始训练
for i in range(max_steps):
# 每10次计算一次准确率
if i%10==0:
summary,acc=sess.run([merged,accuracy],feed_dict=feed_dict(False))
test_writer.add_summary(summary,i)
print ('accuracy at step %s:%s'%(i,acc))
else:
# 每100次保存一次训练结果
if i%100==99:
run_options=tf.RunOptions(trace_level=tf.RunOptions.FULL_TRACE)
run_metadata=tf.RunMetadata()
summary,_=sess.run([merged,train_step],feed_dict=feed_dict(True),options=run_options,run_metadata=run_metadata)
train_writer.add_summary(summary,i)
saver.save(sess,log_dir+'/model.ckpt',i)
print ('adding run metedata for ',i)
else:
summary,_=sess.run([merged,train_step],feed_dict=feed_dict(True))
train_writer.add_summary(summary,i)
train_writer.close()
test_writer.close()
接下来启动TensorBoard,在E:/testdata/mnist_log目录下启动命令行CMD:tensorboard –logdir=./
然后在浏览器输入地址:http://Lenovo-495:6006
参考:https://blog.csdn.net/hongxue8888/article/details/79753679
https://www.tensorflow.org/programmers_guide/summaries_and_tensorboard