#训练过程的可视化 ,TensorBoard的应用
#导入模块并下载数据集
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data

#设置超参数
max_step=1000
learning_rate=0.001
dropout=0.9

# 用logdir明确标明日志文件储存路径
#训练过程中的数据储存在E:\\MNIST_data\\目录中,通过这个路径指定--log_dir
data_dir='E:\\MNIST_data\\'
log_dir='E:\\mnist_with_summaries\\'
mnist=input_data.read_data_sets(data_dir,one_hot=True)
sess=tf.InteractiveSession()

#本句的含义是使图可视化,sess.graph是对图的定义
#使用以上指定的路径创建摘要的文件写入符(FileWrite)
file_write=tf.summary.FileWriter(log_dir,sess.graph)

def variable_summaries(var, name):
    """对每一个张量添加多个摘要描述"""
    with tf.name_scope('summaries'):
        tf.summary.histogram(name, var)
        mean = tf.reduce_mean(var)
        #均值
        tf.summary.scalar('mean/' + name, mean) 
        stddev = tf.sqrt(tf.reduce_mean(tf.square(var - mean)))
        #标准差
        tf.summary.scalar('stddev/' + name, 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):
        """为确保计算图中各个层的分组,给每一层添加一个name_scope"""
        with tf.name_scope('weights'):
            weights = tf.Variable(tf.truncated_normal([input_dim, output_dim], stddev=0.1))
            variable_summaries(weights, layer_name + '/weights')
        with tf.name_scope('biases'):
            biases = tf.Variable(tf.constant(0.0, shape=[output_dim]))
            variable_summaries(biases, layer_name + '/biases')
        with tf.name_scope('Wx_plus_b'):
            preactivate = tf.matmul(input_tensor, weights) + biases
            # 激活前的直方图
            tf.summary.histogram(layer_name + '/pre_activations', preactivate) 
        activations = act(preactivate, name='activation')
        # 记录神经网络节点输出在经过激活函数之后的分布。
        # 激活后的直方图
        tf.summary.histogram(layer_name + '/activations', activations) 
        return activations
    
#构建回归模型,输入原始真实值(group truth),采用sotfmax函数拟合,并定义损失函数和优化器
#定义回归模型
x = tf.placeholder(tf.float32, [None, 784])
activations = nn_layer(x,784,10,"x")
#训练模型
#使用InteractiveSession()创建交互式上下文tf会话,这里的会话是默认
#在tf.Tensor.eval 和tf.Operation.run中都可以使用该会话来运行操作(OP)
sess = tf.InteractiveSession()
#注意:之前的版本中使用的是 tf.initialize_all_variables 作为初始化全局变量,已被弃用,更新后的采用一下命令
tf.global_variables_initializer().run()

for _ in range(1000):
    batch_xs, batch_ys = mnist.train.next_batch(100)
    sess.run(activations, feed_dict={x: batch_xs})
    
#运行tensorboard命令,打开浏览器,查看模型训练过程中的可视化结果,
#在终端输入下命令:
#tensorboard --logdir=E:\\mnist_with_summaries\\