TensorFlow入门:(九)TensorFlow可视化

    在TensorFlow中,最常用的可视化方法有三种途径,分别为TensorFlow与OpenCv的混合编程、利用Matpltlib进行可视化、利用TensorFlow自带的可视化工具TensorBoard进行可视化。这三种方法中,TensorFlow中最重要的可视化方法是通过tensorBoard、tf.summary和tf.summary.FileWriter这三个模块相互合作来完成的。

1、TensorBoard简介

    TensorBoard是TensorFlow官方推出的可视化工具,它可以将模型训练过程中的各种汇总数据展示出来,包括标量(Scalar)、图片(Images)、音频(Audio)、计算图(Graphs)、数据分布(Distributions)、直方图(Histograms)和嵌入向量(Embeddings)。在训练大型深度学习神经网络时,中间计算过程非常复杂,为了理解调试和优化我们设计的网络,我们可以使用TensorBoard观察训练过程中各种可视化数据。如果要使用TensorBoard展示数据,我们需要在执行TensorFlow计算图的过程中,将各种类型的数据汇总并记录到日志文件中。然后使用TensorBoard读取这些日志文件,解析数据并生成可视化的Web界面,让我们可以在浏览器中观察各种汇总的数据。

2、Summary方法详解:

  (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 ,...(其他要显示的信息)])  #这里的[]不可省

3、实例:用MLP训练mnist数据集

#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

猜你喜欢

转载自blog.csdn.net/MOU_IT/article/details/80776137