TensorBoard可視化

0. 寫在前面

參考書python

《TensorFlow:實戰Google深度學習框架》(第2版)react

工具git

python3.5.1,pycharm瀏覽器

1. TensorBoard簡介

一個簡單的TensorFlow程序,在這個程序中完成了TensorBoard日誌輸出的功能。網絡

#!/usr/bin/env python # -*- coding: UTF-8 -*- # coding=utf-8 """ @author: Li Tian @contact: 694317828@qq.com @software: pycharm @file: tensorboard_test1.py @time: 2019/5/10 9:27 @desc: TensorBoard簡介。一個簡單的TensorFlow程序,在這個程序中完成了TensorBoard日誌輸出的功能。 """ import tensorflow as tf # 定義一個簡單的計算圖,實現向量加法的操做。 input1 = tf.constant([1.0, 2.0, 3.0], name="input1") input2 = tf.Variable(tf.random_uniform([3], name="input2")) output = tf.add_n([input1, input2], name="add") # 生成一個寫日誌的writer,並將當前的TensorFlow計算圖寫入日誌。TensorFlow提供了 # 多種寫日誌文件的API,在後面詳細介紹。 writer = tf.summary.FileWriter('./log/', tf.get_default_graph()) writer.close()

運行以後輸入:tensorboard --logdir=./log查看TensorBoard。app

 

img

而後在瀏覽器中輸入下面的網址。框架

img

2. TensorFlow計算圖可視化

2.1 命名空間與TensorBoard圖上節點

tf.variable_scope與tf.name_scope函數的區別dom

#!/usr/bin/env python # -*- coding: UTF-8 -*- # coding=utf-8 """ @author: Li Tian @contact: 694317828@qq.com @software: pycharm @file: tensorboard_test2.py @time: 2019/5/10 10:26 @desc: tf.variable_scope與tf.name_scope函數的區別 """ import tensorflow as tf with tf.variable_scope("foo"): # 在命名空間foo下獲取變量"bar",因而獲得的變量名稱爲「foo/bar」。 a = tf.get_variable("bar", [1]) # 輸出:foo/bar: 0 print(a.name) with tf.variable_scope("bar"): # 在命名空間bar下獲取變量「bar」,因而獲得的變量名稱爲「bar/bar」。此時變量 # 「bar/bar」和變量「foo/bar」並不衝突,因而能夠正常運行。 b = tf.get_variable("bar", [1]) # 輸出:bar/bar:0 with tf.name_scope("a"): # 使用tf.Variable函數生成變量會受到tf.name_scope影響,因而這個變量的名稱爲「a/Variable」。 a = tf.Variable([1]) # 輸出:a/Variable:0 print(a.name) # tf.get_variable函數不受tf.name_scope函數的影響。 # 因而變量並不在a這個命名空間中。 a = tf.get_variable("b", [1]) # 輸出:b:0 print(a.name) with tf.name_scope("b"): # 由於tf.get_variable不受tf.name_scope影響,因此這裏試圖獲取名稱爲 # 「a」的變量。然而這個變量已經被聲明瞭,因而這裏會報重複聲明的錯誤 tf.get_variable("b", [1]) 

 

對不起,這一段代碼,我知道做者想要表達什麼意思。。。但我實在是以爲不知所云。ide

img

改進向量相加的樣例代碼函數

#!/usr/bin/env python # -*- coding: UTF-8 -*- # coding=utf-8 """ @author: Li Tian @contact: 694317828@qq.com @software: pycharm @file: tensorboard_test3.py @time: 2019/5/10 10:41 @desc: 改進向量相加的樣例代碼 """ import tensorflow as tf # 將輸入定義放入各自的命名空間中,從而使得TensorBoard能夠根據命名空間來整理可視化效果圖上的節點。 with tf.name_scope("input1"): input1 = tf.constant([1.0, 2.0, 3.0], name="input1") with tf.name_scope("input2"): input2 = tf.Variable(tf.random_uniform([3]), name="input2") output = tf.add_n([input1, input2], name="add") writer = tf.summary.FileWriter("./log", tf.get_default_graph()) writer.close() 

 

獲得改進後的圖:

img\

展開input2節點的可視化效果圖:

img

可視化一個真實的神經網絡結構圖

我是真的佛了。。。這裏原諒我真的又要噴。。。首先是用以前的mnist_inference文件就已經炸了,而後下面還有一句跟前面同樣的方式訓練神經網絡。。。我特麼。。。。你你聽,這說的是人話嗎?我已經無力吐槽了。。。這本書用來做爲個人TensorFlow啓蒙書,真的是後悔死了。。。

下面的代碼,依然是我本身憑藉本身的理解,改後的,這本書是真的垃圾。

#!/usr/bin/env python # -*- coding: UTF-8 -*- # coding=utf-8 """ @author: Li Tian @contact: 694317828@qq.com @software: pycharm @file: tensorboard_test4.py @time: 2019/5/10 11:06 @desc: 可視化一個真實的神經網絡結構圖。 """ import tensorflow as tf import os from tensorflow.examples.tutorials.mnist import input_data # mnist_inference中定義的常量和前向傳播的函數不須要改變,由於前向傳播已經經過 # tf.variable_scope實現了計算節點按照網絡結構的劃分。 import BookStudy.book2.mnist_inference as mnist_inference INPUT_NODE = 784 OUTPUT_NODE = 10 LAYER1_NODE = 500 # 配置神經網絡的參數。 BATCH_SIZE = 100 LEARNING_RATE_BASE = 0.8 LEARNING_RATE_DECAY = 0.99 REGULARAZTION_RATE = 0.0001 TRAINING_STEPS = 30000 MOVING_AVERAGE_DECAY = 0.99 # 模型保存的路徑和文件名。 MODEL_SAVE_PATH = './model/' MODEL_NAME = 'model.ckpt' def train(mnist): # 將處理輸入數據的計算都放在名字爲「input」的命名空間下。 with tf.name_scope('input'): x = tf.placeholder(tf.float32, [None, mnist_inference.INPUT_NODE], name='x-input') y_ = tf.placeholder(tf.float32, [None, mnist_inference.OUTPUT_NODE], name="y-input") regularizer = tf.contrib.layers.l2_regularizer(REGULARAZTION_RATE) y = mnist_inference.inference(x, regularizer) global_step = tf.Variable(0, trainable=False) # 將處理滑動平均相關的計算都放在名爲moving_average的命名空間下。 with tf.name_scope("moving_average"): variable_averages = tf.train.ExponentialMovingAverage(MOVING_AVERAGE_DECAY, global_step) variable_averages_op = variable_averages.apply(tf.trainable_variables()) # 將計算損失函數相關的計算都放在名爲loss_function的命名空間下。 with tf.name_scope("loss_function"): cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=y, labels=tf.argmax(y_, 1)) cross_entropy_mean = tf.reduce_mean(cross_entropy) loss = cross_entropy_mean + tf.add_n(tf.get_collection('losses')) # 將定義學習率、優化方法以及每一輪訓練須要訓練的操做都放在名字爲「train_step」的命名空間下。 with tf.name_scope("train_step"): learning_rate = tf.train.exponential_decay( LEARNING_RATE_BASE, global_step, mnist.train.num_examples / BATCH_SIZE, LEARNING_RATE_DECAY, staircase=True ) train_step = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss, global_step=global_step) with tf.control_dependencies([train_step, variable_averages_op]): train_op = tf.no_op(name='train') # 初始化Tensorflow持久化類。 saver = tf.train.Saver() with tf.Session() as sess: tf.global_variables_initializer().run() # 在訓練過程當中再也不測試模型在驗證數據上的表現,驗證和測試的過程將會有一個獨立的程序來完成。 for i in range(TRAINING_STEPS): xs, ys = mnist.train.next_batch(BATCH_SIZE) _, loss_value, step = sess.run([train_op, loss, global_step], feed_dict={x: xs, y_: ys}) # 每1000輪保存一次模型。 if i % 1000 == 0: # 輸出當前的訓練狀況。這裏只輸出了模型在當前訓練batch上的損失函數大小。經過損失函數的大小能夠大概瞭解到 # 訓練的狀況。在驗證數據集上的正確率信息會有一個獨立的程序來生成。 print("After %d training step(s), loss on training batch is %g." % (step, loss_value)) # 保存當前的模型。注意這裏給出了global_step參數,這樣可讓每一個被保存的模型的文件名末尾加上訓練的輪數, # 好比「model.ckpt-1000」 表示訓練1000輪以後獲得的模型。 saver.save(sess, os.path.join(MODEL_SAVE_PATH, MODEL_NAME), global_step=global_step) # 將當前的計算圖輸出到TensorBoard日誌文件。 writer = tf.summary.FileWriter("./log", tf.get_default_graph()) writer.close() def main(argv = None): mnist = input_data.read_data_sets("D:/Python3Space/BookStudy/book2/MNIST_data", one_hot=True) train(mnist) if __name__ == '__main__': tf.app.run() 

 

運行以後:

img

召喚tensorboard:

img

改進後的MNIST樣例程序TensorFlow計算圖可視化效果圖:

img

2.2 節點信息

修改前面的代碼,將不一樣迭代輪數的每一個TensorFlow計算節點的運行時間和消耗的內存寫入TensorBoard的日誌文件中。

果真。。。此次又是隻給出一部分代碼。。。而且這個train_writer是什麼啊,在哪裏定義也沒看到,拿來就用,真的是服了。。。(寫的也太爛了,佛了,刷完這本書我就燒了。。。)

#!/usr/bin/env python # -*- coding: UTF-8 -*- # coding=utf-8 """ @author: Li Tian @contact: 694317828@qq.com @software: pycharm @file: tensorboard_test5.py @time: 2019/5/10 21:13 @desc: 修改前面的代碼,將不一樣迭代輪數的每一個TensorFlow計算節點的運行時間和消耗的內存寫入TensorBoard的日誌文件中。 """ import tensorflow as tf import os from tensorflow.examples.tutorials.mnist import input_data # mnist_inference中定義的常量和前向傳播的函數不須要改變,由於前向傳播已經經過 # tf.variable_scope實現了計算節點按照網絡結構的劃分。 import BookStudy.book2.mnist_inference as mnist_inference INPUT_NODE = 784 OUTPUT_NODE = 10 LAYER1_NODE = 500 # 配置神經網絡的參數。 BATCH_SIZE = 100 LEARNING_RATE_BASE = 0.8 LEARNING_RATE_DECAY = 0.99 REGULARAZTION_RATE = 0.0001 TRAINING_STEPS = 30000 MOVING_AVERAGE_DECAY = 0.99 # 模型保存的路徑和文件名。 MODEL_SAVE_PATH = './model/' MODEL_NAME = 'model.ckpt' def train(mnist): # 將處理輸入數據的計算都放在名字爲「input」的命名空間下。 with tf.name_scope('input'): x = tf.placeholder(tf.float32, [None, mnist_inference.INPUT_NODE], name='x-input') y_ = tf.placeholder(tf.float32, [None, mnist_inference.OUTPUT_NODE], name="y-input") regularizer = tf.contrib.layers.l2_regularizer(REGULARAZTION_RATE) y = mnist_inference.inference(x, regularizer) global_step = tf.Variable(0, trainable=False) # 將處理滑動平均相關的計算都放在名爲moving_average的命名空間下。 with tf.name_scope("moving_average"): variable_averages = tf.train.ExponentialMovingAverage(MOVING_AVERAGE_DECAY, global_step) variable_averages_op = variable_averages.apply(tf.trainable_variables()) # 將計算損失函數相關的計算都放在名爲loss_function的命名空間下。 with tf.name_scope("loss_function"): cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=y, labels=tf.argmax(y_, 1)) cross_entropy_mean = tf.reduce_mean(cross_entropy) loss = cross_entropy_mean + tf.add_n(tf.get_collection('losses')) # 將定義學習率、優化方法以及每一輪訓練須要訓練的操做都放在名字爲「train_step」的命名空間下。 with tf.name_scope("train_step"): learning_rate = tf.train.exponential_decay( LEARNING_RATE_BASE, global_step, mnist.train.num_examples / BATCH_SIZE, LEARNING_RATE_DECAY, staircase=True ) train_step = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss, global_step=global_step) with tf.control_dependencies([train_step, variable_averages_op]): train_op = tf.no_op(name='train') # 初始化Tensorflow持久化類。 saver = tf.train.Saver() # 將當前的計算圖輸出到TensorBoard日誌文件。 train_writer = tf.summary.FileWriter("./log", tf.get_default_graph()) with tf.Session() as sess: tf.global_variables_initializer().run() # 在訓練過程當中再也不測試模型在驗證數據上的表現,驗證和測試的過程將會有一個獨立的程序來完成。 for i in range(TRAINING_STEPS): xs, ys = mnist.train.next_batch(BATCH_SIZE) # 每1000輪保存一次模型。 if i % 1000 == 0: # 配置運行時須要記錄的信息。 run_options = tf.RunOptions(trace_level=tf.RunOptions.FULL_TRACE) # 運行時記錄運行信息的proto。 run_metadata = tf.RunMetadata() # 將配置信息和記錄運行信息的proto傳入運行的過程,從而記錄運行時每個節點的時間、空間開銷信息。 _, loss_value, step = sess.run([train_op, loss, global_step], feed_dict={x: xs, y_: ys}, options=run_options, run_metadata=run_metadata) # 將節點在運行時的信息寫入日誌文件。 train_writer.add_run_metadata(run_metadata, 'step%03d' % i) # 輸出當前的訓練狀況。這裏只輸出了模型在當前訓練batch上的損失函數大小。經過損失函數的大小能夠大概瞭解到 # 訓練的狀況。在驗證數據集上的正確率信息會有一個獨立的程序來生成。 print("After %d training step(s), loss on training batch is %g." % (step, loss_value)) # 保存當前的模型。注意這裏給出了global_step參數,這樣可讓每一個被保存的模型的文件名末尾加上訓練的輪數, # 好比「model.ckpt-1000」 表示訓練1000輪以後獲得的模型。 saver.save(sess, os.path.join(MODEL_SAVE_PATH, MODEL_NAME), global_step=global_step) else: _, loss_value, step = sess.run([train_op, loss, global_step], feed_dict={x: xs, y_: ys}) train_writer.close() def main(argv = None): mnist = input_data.read_data_sets("D:/Python3Space/BookStudy/book2/MNIST_data", one_hot=True) train(mnist) if __name__ == '__main__': tf.app.run() 

 

運行後:

img

啓動TensorBoard,這樣就能夠可視化每一個TensorFlow計算節點在某一次運行時所消耗的時間和空間。

img

img

img

TensorBoard左側的Color欄中Compute和Memory這兩個選項將能夠被選擇。

img

img

顏色越深的節點,時間和空間的消耗越大。

img

  1. 空心的小橢圓對應了TensorFlow計算圖上的一個計算節點。
  2. 一個矩形對應了計算圖上的一個命名空間。

3. 監控指標可視化

將TensorFlow程序運行時的信息輸出到TensorBoard日誌文件中。

#!/usr/bin/env python # -*- coding: UTF-8 -*- # coding=utf-8 """ @author: Li Tian @contact: 694317828@qq.com @software: pycharm @file: tensorboard_test6.py @time: 2019/5/11 15:27 @desc: 將TensorFlow程序運行時的信息輸出到TensorBoard日誌文件中。 """ import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data SUMMARY_DIR = './log' BATCH_SIZE = 100 TRAIN_STEPS = 3000 # 生成變量監控信息並定義生成監控信息日誌的操做。其中var給出了須要記錄的張量,name給出了 # 在可視化結果中顯示的圖標名稱,這個名稱通常與變量名一致。 def variable_summaries(var, name): # 將生成監控信息的操做放到同一個命名空間下。 with tf.name_scope('summaries'): # 經過tf.summary.histogram函數記錄張量中元素的取值分佈。對於給出的圖表 # 名稱和張量,tf.summary.histogram函數會生成一個Summary protocol buffer。 # 將Summary寫入TensorBoard日誌文件後,在HISTOGRAMS欄和DISTRIBUTION欄 # 下都會出現對應名稱的圖標。和TensorFlow中其餘操做相似。tf.summary.histogram # 函數不會馬上被執行,只有當sess.run函數明確調用這個操做時,TensorFlow纔會真正 # 生成並輸出Summary protocol buffer。下文將更加詳細地介紹如何理解HISTOGRAMS欄 # 和DISTRIBUTION欄下的信息。 tf.summary.histogram(name, var) # 計算變量的平均值,並定義間生成平均值信息日誌的操做。記錄變量平均值信息的日誌標籤名 # 爲'mean/' + name,其中mean爲命名空間,/是命名空間的分隔符。從圖中能夠看出,在相同 # 命名空間中的監控指標會被整合到同一欄中。name則給出了當前監控指標屬於哪個變量。 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 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 = 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') # 記錄神經網絡輸出節點在通過激活函數以後的分佈。在圖中,對於layer1,由於 # 使用了ReLU函數做爲激活函數,因此全部小於0的值都被設爲了0。因而在激活後的 # layer1/activations圖上全部的值都是大於0的。而對於layer2,由於沒有使用 # 激活函數,因此layer2/activations和layer2/pre_activations同樣。 tf.summary.histogram(layer_name + '/activations', activations) return activations def main(_): mnist = input_data.read_data_sets('D:/Python3Space/BookStudy/book2/MNIST_data', one_hot=True) # 定義輸出 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') # 將輸入向量還原成圖片的像素矩陣,並經過tf.summary.image函數定義將當前的圖片信息寫入日誌的操做。 with tf.name_scope('input_reshape'): image_shaped_input = tf.reshape(x, [-1, 28, 28, 1]) tf.summary.image('input', image_shaped_input, 10) hidden1 = nn_layer(x, 784, 500, 'layer1') y = nn_layer(hidden1, 500, 10, 'layer2', act=tf.identity) # 計算交叉熵並定義生成交叉熵監控日誌的操做。 with tf.name_scope('cross_entropy'): cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=y, labels=y_)) tf.summary.scalar('cross entropy', cross_entropy) with tf.name_scope('train'): train_step = tf.train.AdamOptimizer(0.001).minimize(cross_entropy) # 計算模型在當前給定數據上的正確率,並定義生成正確率監控日誌的操做。若是在sess.run時 # 給定的數據是訓練batch,那麼獲得的正確率就是在這個訓練batch上的正確率;若是給定的 # 數據爲驗證或者測試數據,那麼獲得的正確率就是在當前模型在驗證或者測試數據上的正確率。 with tf.name_scope('accuracy'): with tf.name_scope('correct_prediction'): correct_prediction = tf.equal(tf.arg_max(y, 1), tf.arg_max(y_, 1)) with tf.name_scope('accuracy'): accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) tf.summary.scalar('accuracy', accuracy) # 和其餘TensorFlow中其餘操做相似,tf.summary.scalar、tf.summary.histogram和 # tf.summary.image函數都不會當即執行,須要經過sess.run來明確調用這些函數。 # 由於程序中定義的寫日誌操做比較多,一一調用很是麻煩,因此TensorFlow提供了 # tf.summary.merge_all函數來整理全部的日誌生成操做。在TensorFlow程序執行的 # 過程當中只須要運行這個操做就能夠將代碼中定義的全部日誌生成操做執行一次,從而將全部日誌寫入文件。 merged = tf.summary.merge_all() with tf.Session() as sess: # 初始化寫日誌的writer,並將當前TensorFlow計算圖寫入日誌 summary_writer = tf.summary.FileWriter(SUMMARY_DIR, sess.graph) tf.global_variables_initializer().run() for i in range(TRAIN_STEPS): xs, ys = mnist.train.next_batch(BATCH_SIZE) # 運行訓練步驟以及全部的日誌生成操做,獲得此次運行的日誌。 summary, _ = sess.run([merged, train_step], feed_dict={x: xs, y_: ys}) # 將全部日誌寫入文件,TensorBoard程序就能夠拿到此次運行所對應的運行信息。 summary_writer.add_summary(summary, i) summary_writer.close() if __name__ == '__main__': tf.app.run() 

 

運行以後打開tensorboard:

img

點擊IMAGES欄能夠可視化當前輪訓練使用的圖像信息。

img

TensorBoard的DISTRIBUTION一欄提供了對張量取值分佈的可視化界面,經過這個界面能夠直觀地觀察到不一樣層神經網絡中參數的取值變化。

img

爲了更加清晰地展現參數取值分佈和訓練迭代輪數之間的關係,TensorBoard提供了HISTOGRAMS視圖。

img

顏色越深的平面表明迭代輪數越小的取值分佈。

點擊「OVERLAY」後,能夠看到以下效果:

img

4. 高維向量可視化

使用MNIST測試數據生成PROJECTOR所須要的兩個文件。(一個sprite圖像,一個tsv文件)

#!/usr/bin/env python # -*- coding: UTF-8 -*- # coding=utf-8 """ @author: Li Tian @contact: 694317828@qq.com @software: pycharm @file: tensorboard_test7.py @time: 2019/5/12 20:45 @desc: 使用MNIST測試數據生成PROJECTOR所須要的兩個文件。(一個sprite圖像,一個tsv文件) """ import matplotlib.pyplot as plt import tensorflow as tf import numpy as np import os from tensorflow.examples.tutorials.mnist import input_data # PROJECTOR須要的日誌文件名和地址相關參數。 LOG_DIR = './log2' SPRITE_FILE = 'mnist_sprite.jpg' META_FILE = "mnist_meta.tsv" # 使用給出的MNIST圖片列表生成sprite圖像。 def create_sprite_image(images): if isinstance(images, list): images = np.array(images) img_h = images.shape[1] img_w = images.shape[2] # sprite圖像能夠理解成是全部小圖片拼成的大正方形矩陣,大正方形矩陣中的每個 # 元素就是原來的小圖片。因而這個正方形的邊長就是sqrt(n),其中n爲小圖片的數量。 # np.ceil向上取整。np.floor向下取整。 m = int(np.ceil(np.sqrt(images.shape[0]))) # 使用全1來初始化最終的大圖片。 sprite_image = np.ones((img_h*m, img_w*m)) for i in range(m): for j in range(m): # 計算當前圖片的編號 cur = i * m + j if cur < images.shape[0]: # 將當前小圖片的內容複製到最終的sprite圖像。 sprite_image[i*img_h: (i+1)*img_h, j*img_w: (j+1)*img_w] = images[cur] return sprite_image # 加載MNIST數據。這裏指定了one_hot=False,因而獲得的labels就是一個數字,表示當前圖片所表示的數字。 mnist = input_data.read_data_sets('D:/Python3Space/BookStudy/book2/MNIST_data', one_hot=False) # 生成sprite圖像 to_visualise = 1 - np.reshape(mnist.test.images, (-1, 28, 28)) sprite_image = create_sprite_image(to_visualise) # 將生成的sprite圖像放到相應的日誌目錄下。 path_for_mnist_sprites = os.path.join(LOG_DIR, SPRITE_FILE) plt.imsave(path_for_mnist_sprites, sprite_image, cmap='gray') plt.imshow(sprite_image, cmap='gray') # 生成每張圖片對應的標籤文件並寫到相應的日誌目錄下。 path_for_mnist_metadata = os.path.join(LOG_DIR, META_FILE) with open(path_for_mnist_metadata, 'w') as f: f.write('Index\tLabel\n') for index, label in enumerate(mnist.test.labels): f.write("%d\t%d\n" % (index, label)) 

 

這裏寫點小tips關於np.ceil、np.floor、enumerate:

np.ceil:向上取整。

np.floor:向下取整。

enumerate:該函數用於將一個可遍歷的數據對象(如列表、元組或字符串)組合爲一個索引序列,同時列出數據和數據下標。

img

回到正題,運行代碼以後能夠獲得兩個文件,一個是sprite圖,一個是mnist_meta.csv文件。

img

img


在生成好輔助數據以後,如下代碼展現瞭如何使用TensorFlow代碼生成PROJECTOR所須要的日誌文件來可視化MNIST測試數據在最後的輸出層向量。

#!/usr/bin/env python # -*- coding: UTF-8 -*- # coding=utf-8 """ @author: Li Tian @contact: 694317828@qq.com @software: pycharm @file: tensorboard_test8.py @time: 2019/5/13 9:34 @desc: 在生成好輔助數據以後,如下代碼展現瞭如何使用TensorFlow代碼生成PROJECTOR所須要的日誌文件來可視化MNIST測試數據在最後的輸出層向量。 """ import tensorflow as tf from BookStudy.book2 import mnist_inference import os # 加載用於生成PROJECTOR日誌的幫助函數。 from tensorflow.contrib.tensorboard.plugins import projector from tensorflow.examples.tutorials.mnist import input_data # 和前面中相似地定義訓練模型須要的參數。這裏咱們一樣是複用mnist_inference過程。 BATCH_SIZE = 100 LEARNING_RATE_BASE = 0.8 LEARNING_RATE_DECAY = 0.99 REGULARAZTION_RATE = 0.0001 # 能夠經過調整這個參數來控制訓練迭代輪數。 TRAINING_STEPS = 10000 MOVING_AVERAGE_DECAY = 0.99 # 和日誌文件相關的文件名及目錄地址。 LOG_DIR = './log3' SPRITE_FILE = 'D:/Python3Space/BookStudy/book2/tensorboard_test/log2/mnist_sprite.jpg' META_FILE = 'D:/Python3Space/BookStudy/book2/tensorboard_test/log2/mnist_meta.tsv' TENSOR_NAME = 'FINAL_LOGITS' # 訓練過程和前面給出的基本一致,惟一不一樣的是這裏還須要返回最後測試數據通過整個 # 神經網絡獲得的輸出矩陣(由於有不少張測試圖片,每張圖片對應了一個輸出層向量, # 因此返回的結果是這些向量組成的矩陣。 def train(mnist): # 輸入數據的命名空間。 with tf.name_scope('input'): x = tf.placeholder(tf.float32, [None, mnist_inference.INPUT_NODE], name='x-input') y_ = tf.placeholder(tf.float32, [None, mnist_inference.OUTPUT_NODE], name='y-input') regularizer = tf.contrib.layers.l2_regularizer(REGULARAZTION_RATE) y = mnist_inference.inference(x, regularizer) global_step = tf.Variable(0, trainable=False) # 處理滑動平均的命名空間。 with tf.name_scope("moving_average"): variable_averages = tf.train.ExponentialMovingAverage(MOVING_AVERAGE_DECAY, global_step) variable_averages_op = variable_averages.apply(tf.trainable_variables()) # 計算損失函數的命名空間。 with tf.name_scope("loss_function"): cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=y, labels=tf.argmax(y_, 1)) cross_entropy_mean = tf.reduce_mean(cross_entropy) loss = cross_entropy_mean + tf.add_n(tf.get_collection('losses')) # 定義學習率、優化方法及每一輪執行訓練操做的命名空間。 with tf.name_scope("train_step"): learning_rate = tf.train.exponential_decay( LEARNING_RATE_BASE, global_step, mnist.train.num_examples / BATCH_SIZE, LEARNING_RATE_DECAY, staircase=True ) train_step = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss, global_step=global_step) with tf.control_dependencies([train_step, variable_averages_op]): train_op = tf.no_op(name='train') # 訓練模型 with tf.Session() as sess: tf.global_variables_initializer().run() for i in range(TRAINING_STEPS): xs, ys = mnist.train.next_batch(BATCH_SIZE) _, loss_value, step = sess.run([train_op, loss, global_step], feed_dict={x: xs, y_: ys}) if i % 1000 == 0: print("After %d training step(s), loss on training batch is %g." % (i, loss_value)) # 計算MNIST測試數據對應的輸出層矩陣。 final_result = sess.run(y, feed_dict={x: mnist.test.images}) # 返回輸出層矩陣的值。 return final_result # 生成可視化最終輸出層向量所須要的日誌文件。 def visualisation(final_result): # 使用一個新的變量來保存最終輸出層向量的結果。由於embedding是經過TensorFlow中 # 變量完成的,因此PROJECTOR可視化的都是TensorFlow中的變量。因而這裏須要新定義 # 一個變量來保存輸出層向量的取值。 y = tf.Variable(final_result, name=TENSOR_NAME) summary_writer = tf.summary.FileWriter(LOG_DIR) # 經過projector.ProjectorConfig類來幫助生成日誌文件。 config = projector.ProjectorConfig() # 增長一個須要可視化的embedding結果。 embedding = config.embeddings.add() # 指定這個embedding結果對應的TensorFlow變量名稱。 embedding.tensor_name = y.name # 指定embedding結果所對應的原始數據信息。好比這裏指定的就是每一張MNIST測試圖片 # 對應的真實類別。在單詞向量中能夠是單詞ID對應的單詞。這個文件是可選的,若是沒有指定 # 那麼向量就沒有標籤。 embedding.metadata_path = META_FILE # 指定sprite圖像。這個也是可選的,若是沒有提供sprite圖像,那麼可視化的結果 # 每個點就是一個小圓點,而不是具體的圖片。 embedding.sprite.image_path = SPRITE_FILE # 在提供sprite圖像時,經過single_image_dim能夠指定單張圖片的大小。 # 這將用於從sprite圖像中截取正確的原始圖片。 embedding.sprite.single_image_dim.extend([28, 28]) # 將PROJECTOR所須要的內容寫入日誌文件。 projector.visualize_embeddings(summary_writer, config) # 生成會話,初始化新聲明的變量並將須要的日誌信息寫入文件。 sess = tf.InteractiveSession() sess.run(tf.global_variables_initializer()) saver = tf.train.Saver() saver.save(sess, os.path.join(LOG_DIR, "model"), TRAINING_STEPS) summary_writer.close() # 主函數先調用模型訓練的過程,再使用訓練好的模型來處理MNIST測試數據, # 最後將獲得的輸出層矩陣輸出到PROJECTOR須要的日誌文件中。 def main(argc=None): mnist = input_data.read_data_sets('D:/Python3Space/BookStudy/book2/MNIST_data', one_hot=True) final_result = train(mnist) visualisation(final_result) if __name__ == '__main__': main() 

 

運行結果:

img

而後打開tensorboard:

img

而後就GG了,網上百度了一萬種方法。。。

參考連接:https://blog.csdn.net/weixin_42769131/article/details/84870558

tensorboard --logdir=./log3 --host=127.0.0.1

解決!然而!我能夠打開前面的log,此次模型的生成的不知道是否是須要太大的內存,界面一致卡在Computing PCA…

img

就很頭大。。。

而後我換了臺電腦(MacBook),就能直接出來。。。

img

仍是三圍旋轉的。。。旋轉~ 跳躍~

 

 

 

 

 

 

轉自:http://www.pianshen.com/article/1157412006/

相關文章
相關標籤/搜索