參考:
① Tensorflow的可視化工具Tensorboard的初步使用
Link: https://blog.csdn.net/sinat_33761963/article/details/62433234?utm_source=copy
Tensorboard 可視化
可以記錄的數(shù)據(jù)類(lèi)型
(1) scalar
(2) Graph
(3) Distribution
...
可視化的過(guò)程
(1) 建立graph
(2) 確定在哪些節(jié)點(diǎn)放置summary operations記錄信息
這里的summary操作也是operations
tf.summary.scalar 用來(lái)記錄標(biāo)量
tf.summary.distributation 用來(lái)記錄數(shù)據(jù)分布圖
tf.summary.image 用來(lái)記錄圖像數(shù)據(jù)
(3)我們需要的summary可能很多,這里的summary作為operations自然需要去run, 但是這些operations并沒(méi)有被其他的operation 所依賴(lài), 所以每個(gè)operation需要手動(dòng)的去run, 為了方便,使用了tf.summary.merge_all()來(lái)將所有的summary節(jié)點(diǎn)合并成為一個(gè)節(jié)點(diǎn), 只要運(yùn)行這個(gè)節(jié)點(diǎn),就能獲得之前設(shè)置的summary data。
(4) 使用tf.summary.FileWriter將運(yùn)行后的數(shù)據(jù)全部的寫(xiě)入到磁盤(pán)中。
(5) tensorboard --logdir=xxx
Code
# -*- coding: utf-8 -*-
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
max_step = 1000
learning_rate = 0.001
dropout = 0.9
data_dir = "/tmp/mnist"
# log_dir下將會(huì)分為兩個(gè)目錄, train, test,分別存放了train, test的summary
log_dir = "/tmp/tensorflow"
mnist = input_data.read_data_sets(data_dir, one_hot=True)
config = tf.ConfigProto()
config.gpu_options.allow_growth = True
session = tf.Session(config=config)
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_shape"):
image_shape_input = tf.reshape(x, [-1, 28, 28, 1])
tf.summary.image("input", image_shape_input, 10) # 命名,數(shù)據(jù), 顯示10張
# 初始化參數(shù)
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("bias"):
biases = bias_variable([output_dim, ])
variable_summaries(biases)
with tf.name_scope("linear_compute"):
preactivate = tf.matmul(input_tensor, weights) + biases
tf.summary.histogram("linear", preactivate)
activations = act(preactivate, name="activation")
tf.summary.histogram("activations", activations)
return activations
hidden1 = nn_layer(x, 784, 500, "layer_1")
with tf.name_scope("dropout"):
keep_prob = tf.placeholder(tf.float32) # 這里使用了一個(gè)placeholder, 可以使用variable, assign代替
tf.summary.scalar("dropout_keep_probability", keep_prob)
dropped = tf.nn.dropout(hidden1, keep_prob)
# predict
y = nn_layer(dropped, 500, 10, "layer_2", act=tf.identity)
with tf.name_scope("loss"):
diff = tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=y)
with tf.name_scope("total"):
cross_entropy = tf.reduce_mean(diff)
tf.summary.scalar("loss", 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_pridiction"):
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", session.graph)
test_writer = tf.summary.FileWriter(log_dir+"/test")
session.run(tf.global_variables_initializer())
def feed_dict(train):
if train:
xs, ys = mnist.train.next_batch(1000)
k = dropout
else:
xs, ys = mnist.test.images, mnist.test.labels
k = 1.0
return {x: xs, y_: ys, keep_prob: k}
for i in range(max_step):
if i % 10 == 0:
summary, acc = session.run([merged, accuracy], feed_dict=feed_dict(False))
test_writer.add_summary(summary, i)
else:
if i % 100 == 99:
pass
else:
# summary的類(lèi)型為string, session.run(tensor) 返回類(lèi)型可能是由tensor決定的
summary, _ = session.run([merged, train_step], feed_dict=feed_dict(train=True))
train_writer.add_summary(summary, i)
summaries:
image
variable (mean(var)| stddev(var)| max(var)| min(var)| var)
preactive
activation
keep_prob
entropy_loss
accuracy
-
image
tf.summary.image('input', image_shape_input, 10)
由于在input_shape這個(gè)name_scope下, 所以圖片的標(biāo)識(shí)為input_shape/input/image/0,這里的image猜測(cè)是tensorflow自己加的。
imageinput.png accuracy
accuracy = tf.reduce_sum(tf.cast(correction_prediction, tf.float32)
tf.summary.scalar("accuracy", accuracy)

merged = tf.summary.merge_all()
summary, _ = session.run([merged, train_step], feed_dict=feed_dict(train=True))
merged集合所有的summary, 這里的summary類(lèi)型為Image, scalar, histogram。session.run的返回值summary為 string, writer.add_summary相當(dāng)于將這個(gè)string寫(xiě)入到文件中。summary格式很復(fù)雜, 因?yàn)槠湟芏嗟母袷降臄?shù)據(jù)。例如這里的summary包含了scalar, image, histogram。二進(jìn)制數(shù)據(jù)與文本數(shù)據(jù)混合。
??
?input_shape/input/image/0"??????"???PNG
?
???9????}?6????B?H?????o/????Q?4k?5O?nz???_?F???f?T???????"u?w??8h\??qbM@?x?<?B???9{?<??????2tP? XH IEND?B`?
??
?input_shape/input/image/1"??????"???PNG
?
???O????a?4?r??4W{???}?? ?~ ??>?U???[??[??u??s8R}?
???d??|o? ?&^?J?d?g?? XY??i??? ????g1? ?;??l?dhs? ?????SrZ;?|?`2??????p?P?????0??f]z??? ?/????5Z???????U~]?????y??mc;? IEND?B`?
??
?input_shape/input/image/2"??????"???PNG
?
IHDR ? Wf?H ?&IDAT(?c`?H0??,?????+J???? ?_?&????????????o??0?I??E??pa&?????)(???????1??v??<???Y??????? ?????????aF$%?er{/K>?rM3S??0'??E?????g?????`?*?d```?7????w?k?J??????????Y!?????0?H#x???(#Ir?3!?L???c???????!?l???'??a``? i?c???)?To0000??c???Qc`???$U?o~?A??Er??D?f,?zV*???????_?^????? "????$`? IEND?B`?
??
對(duì)于session.run(), 傳入的參數(shù)為可以為Tensor, Operation(eg: train_step).
"""
def run(self, fetches, feed_dict=None, options=None, run_metadata=None):
The `fetches` argument may be a single graph element, or an arbitrarily
nested list, tuple, namedtuple, dict, or OrderedDict containing graph
elements at its leaves. A graph element can be one of the following types:
* An @{tf.Operation}.
The corresponding fetched value will be `None`.
* A @{tf.Tensor}.
The corresponding fetched value will be a numpy ndarray containing the
value of that tensor.
* A @{tf.SparseTensor}.
The corresponding fetched value will be a
@{tf.SparseTensorValue}
containing the value of that sparse tensor.
* A `get_tensor_handle` op. The corresponding fetched value will be a
numpy ndarray containing the handle of that tensor.
* A `string` which is the name of a tensor or operation in the graph.
"""
Tensor & Operation Name屬性
with tf.name_scope("accuracy"):
with tf.name_scope("correct_pridiction"):
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))
這里得到的兩個(gè)變量accuracy, correct_prediction,分別為accuracy/accuracy/Mean:0和 accuracy/correct_pridiction/Equal:0, 那么這里Tensor的名稱(chēng)在name_scope的基礎(chǔ)上再一步添加了Mean:0以及Equal:0, 表示了得到這個(gè)Tensor所進(jìn)行的操作。
Tensorflow為何要使用這么多的name_scope, Operation來(lái)作為這里的Tensor的名稱(chēng)呢。為了方便debug么。
,
