import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
INPUT_NODE = 28*28
NODE1 = 500
NODE2= 10
BATCH_SIZE = 100
BASE_LEARNING_RATE = 0.8
DECAY_RATE = 0.999
TRAIN_STEPS = 30000
# 生成变量监控信息并定义生成监控信息日志,其中var是需要记录的变量,name给出了在可视化结果中显示的图表名称,一般与变量名一致
def summary_variable(var, name):
# 将生成监控信息的操作放到同一个命名空间下
with tf.name_scope('summaries'):
# 通过tf.summary.histogram()函数会记录张量中元素的取值分布,对于给出的图表名称和张量,tf.summary.histogram函数会
# 生成一个Summary protocol buffer. 将Summary写入tensorboard日志文件后,在HISTOGRAMS栏和DISTRIBUTION栏下都会
# 出现对应名称的图表. 和其它操作类似,tf.summary.histogram函数不会立刻执行只有当sess.run函数明确调用该操作后tensorflow
# 才会真正生成并输出Summary protocol buffer
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)
def get_weights(shape):
weight = tf.get_variable('weight',shape,tf.float32,initializer=tf.truncated_normal_initializer(mean=0.0, stddev=0.5))
tmp = tf.contrib.layers.l2_regularizer(0.001)(weight)
tf.add_to_collection(tf.GraphKeys.LOSSES,tmp)
return weight
def inference(input_tensor):
with tf.variable_scope('layer1'):
weight = get_weights([INPUT_NODE,NODE1])
bias = tf.get_variable('bias',[NODE1])
layer1 = tf.nn.relu(tf.matmul(input_tensor, weight) + bias)
summary_variable(weight, weight.name)
summary_variable(bias, bias.name)
tf.summary.histogram(layer1.name, layer1)
with tf.variable_scope('layer2'):
weight = get_weights([NODE1,NODE2])
bias = tf.get_variable('bias',[NODE2])
layer2 = tf.matmul(layer1,weight) + bias
summary_variable(weight, weight.name)
summary_variable(bias, bias.name)
tf.summary.histogram(layer2.name, layer2)
return layer2
def train(mnist):
x = tf.placeholder(tf.float32,[None, INPUT_NODE],name='x-input')
y_gt = tf.placeholder(tf.float32,[None,NODE2], name='y-input')
# 将输入向量还原成图片的像素矩阵,并通过tf.summary.image()函数将当前图片信息写入日志
with tf.name_scope('input_reshape'):
image_x = tf.reshape(x,[-1,28,28,1])
tf.summary.image('image_x', image_x, 10)
y_pred = inference(x)
loss = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(labels=tf.argmax(y_gt,1),logits=y_pred))
regular_loss = tf.add_n(tf.get_collection(tf.GraphKeys.LOSSES))
loss = loss + regular_loss
# 和TensorFlow计算图可视化结果不同的是,SCALARS,IMAGES,AUDIO,TEXT,HISTOGRAMS,DISTRIBUTIONS栏只会对最高层的命名空间进行整合
tf.summary.scalar('namespace/loss', loss)
accuracy = tf.reduce_mean(tf.cast(tf.equal(tf.argmax(y_pred,1), tf.argmax(y_gt,1)),tf.float32))
tf.summary.scalar('namespace/accu', accuracy)
merged_summaries = tf.summary.merge_all()
global_step = tf.Variable(0,trainable=False)
learning_rate = tf.train.exponential_decay(BASE_LEARNING_RATE,global_step,mnist.train.num_examples/BATCH_SIZE,DECAY_RATE)
train_step = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss,global_step)
saver = tf.train.Saver()
with tf.Session() as sess:
summary_writer = tf.summary.FileWriter('./log', sess.graph)
sess.run(tf.global_variables_initializer())
# 配置运行时需要记录的信息
run_options = tf.RunOptions(trace_level=tf.RunOptions.SOFTWARE_TRACE)
# 运行时记录运行信息的proto
run_metadata = tf.RunMetadata()
for i in range(TRAIN_STEPS):
xs,ys = mnist.train.next_batch(BATCH_SIZE)
if i % 1000 == 0:
# 将配置信息和记录运行信息的proto传入运行的过程,从而记录运行时每一个节点的实时间、内存开销
step,_,acc,loss_, summary_ = sess.run([global_step, train_step, accuracy, loss, merged_summaries], \
feed_dict={x: xs, y_gt:ys},options=run_options, run_metadata=run_metadata)
summary_writer.add_summary(summary_,step)
# 将节点在运行时的信息写入日志文件
summary_writer.add_run_metadata(run_metadata,'step%03d'%step)
saver.save(sess,'./model/model')
print('step: %d, loss: %f, accuarcy: %f' % (step,loss_, acc))
else:
sess.run([train_step], feed_dict={x: xs, y_gt:ys})
summary_writer.close()
def main():
mnist = input_data.read_data_sets('./MNIST_data',one_hot=True)
train(mnist)
if __name__ == '__main__':
main()
图1保存的变量
图2训练/测试过程中的图像
图3选择Session runs可以查看Compute time或Memory来看哪些运算占用的资源多耗费时间长
图4保存的指定变量的数据分布
HISTOGRAMS中不同轮数中参数的取值是通过不同的平面来表示的,颜色越深的平面表示迭代轮数越小的取值分布。
图5保存的指定变量的直方图变化情况