1. 程式人生 > >TensorFlow學習筆記(二)之視覺化(Tensorboard)

TensorFlow學習筆記(二)之視覺化(Tensorboard)

一、Tensorboard簡介

Tensorboard是TensorFlow自帶的一個強大的視覺化工具,也是一個web應用程式套件。通過將tensorflow程式輸出的日誌檔案的資訊視覺化使得tensorflow程式的理解、除錯和優化更加簡單高效。支援其七種視覺化:

  • SCALARS:展示訓練過程中的準確率、損失值、權重/偏置的變化情況
  • IMAGES:展示訓練過程中及記錄的影象
  • AUDIO:展示訓練過程中記錄的音訊
  • GRAPHS:展示模型的資料流圖,以及各個裝置上消耗的記憶體和時間
  • DISTRIBUTIONS:展示訓練過程中記錄的資料的分佈圖
  • HISTOGRAMS:展示訓練過程中記錄的資料的柱狀圖
  • EMBEDDINGS:展示詞向量後的投影分佈

介面展示:
這裡寫圖片描述

那如何啟動tensorboard呢?使用是手寫體識別的例子,原始碼如下:

import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
import os

os.environ["CUDA_VISIBLE_DEVICES"] = "0"
config = tf.ConfigProto(allow_soft_placement=True)
gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=0.33
) config.gpu_options.allow_growth = True max_steps = 1000 # 最大迭代次數 learning_rate = 0.001 # 學習率 dropout = 0.9 # dropout時隨機保留神經元的比例 data_dir = './MNIST_DATA' # 樣本資料儲存的路徑 log_dir = './MNIST_LOG' # 輸出日誌儲存的路徑 # 獲取資料集,並採用採用one_hot熱編碼 mnist = input_data.read_data_sets(data_dir, one_hot=True) sess = tf.InteractiveSession(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_reshape'): image_shaped_input = tf.reshape(x, [-1, 28, 28, 1]) tf.summary.image('input', image_shaped_input, 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'): # 計算引數的均值,並使用tf.summary.scaler記錄 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.scaler記錄記錄下標準差,最大值,最小值 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): # 呼叫之前的方法初始化權重w,並且呼叫引數資訊的記錄方法,記錄w的資訊 with tf.name_scope('weights'): weights = weight_variable([input_dim, output_dim]) variable_summaries(weights) # 呼叫之前的方法初始化權重b,並且呼叫引數資訊的記錄方法,記錄b的資訊 with tf.name_scope('biases'): biases = bias_variable([output_dim]) variable_summaries(biases) # 執行wx+b的線性計算,並且用直方圖記錄下來 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, 'layer1') # 建立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('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) # 使用AdamOptimizer優化器訓練模型,最小化交叉熵損失 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'): # 分別將預測和真實的標籤中取出最大值的索引,弱相同則返回1(true),不同則返回0(false) 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) # summaries合併 merged = tf.summary.merge_all() # 寫到指定的磁碟路徑中 train_writer = tf.summary.FileWriter(log_dir + '/train', sess.graph) test_writer = tf.summary.FileWriter(log_dir + '/test') # 執行初始化所有變數 tf.global_variables_initializer().run() def feed_dict(train): """Make a TensorFlow feed_dict: maps data onto Tensor placeholders.""" if train: xs, ys = mnist.train.next_batch(100) 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_steps): if i % 10 == 0: # 記錄測試集的summary與accuracy 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: # 記錄訓練集的summary summary, _ = sess.run([merged, train_step], feed_dict=feed_dict(True)) train_writer.add_summary(summary, i) train_writer.close() test_writer.close()

在pycharm中執行這段程式碼,效果如下:
這裡寫圖片描述
同時,在訓練的時候開啟命令列,輸入下面命令,啟動TesnorBoard:

tensorboard --logdir=./MNIST_LOG/

這裡寫圖片描述
這裡生成一個連結地址,複製到遊覽器中檢視各個模組的內容。

總的來說步驟如下:

  1. 建立writer,寫日誌檔案:tf.summary.FileWriter(log_dir + ‘/train’, sess.graph)
  2. 儲存日誌檔案:writer.close()
  3. 執行視覺化命令,啟動服務:tensorboard –logdir /path/

二、SCALARS面板

SCALARS 面板,統計tensorflow中的標量(如:學習率、模型的總損失)隨著迭代輪數的變化情況。SCALARS 面板的左邊是一些選項,包括Split on undercores(用下劃線分開顯示)、Data downloadlinks(資料下載連結)、Smoothing(影象的曲線平滑程度)以及Horizontal Axis(水平軸)的表示,其中水平軸的表示分3 種(STEP 代表迭代次數,RELATIVE 代表按照訓練集和測試集的相對值,WALL 代表按照時間)。圖中右邊給出了準確率變化曲線。
如下圖二所示,SCALARS欄目顯示通過函式tf.summary.scalar()記錄的資料的變化趨勢。如下所示程式碼可新增到程式中,用於記錄學習率的變化情況。

tf.summary.scalar('accuracy', accuracy)

這裡寫圖片描述

SCALARS 面板中還繪製了每一層的偏置(biases)和權重(weights)的變化曲線,包括每
次迭代中的最大值、最小值、平均值和標準差,如下圖,layer1層:
這裡寫圖片描述
layer2層:
這裡寫圖片描述

構建損失曲線:

tf.summary.scalar('loss', cross_entropy)

這裡寫圖片描述

三、IMAGES面板

影象儀表盤,可以顯示通過tf.summary.image()函式來儲存的png圖片檔案。

1. # 指定圖片的資料來源為輸入資料x,展示的相對位置為[-1,28,28,1] 
2. image_shaped_input = tf.reshape(x, [-1, 28, 28, 1])
3. # 將input名稱空間下的圖片放到summary中,一次展示10張 
4. tf.summary.image('input', image_shaped_input , 10) 

如上面程式碼,將輸入資料中的png圖片放到summary中,準備後面寫入日誌檔案。執行程式,生成日誌檔案,然後在tensorboard的IMAGES欄目下就會出現如下圖一所示的內容(實驗用的是mnist資料集)。儀表盤設定為每行對應不同的標籤,每列對應一個執行。影象儀表盤僅支援png圖片格式,可以使用它將自定義生成的視覺化影象(例如matplotlib散點圖)嵌入到tensorboard中。該儀表盤始終顯示每個標籤的最新影象。
IMAGES面板展示訓練過程中及記錄的影象,下圖展示了資料集合測試資料經過處理後圖片的樣子:
這裡寫圖片描述

四、AUDIO

AUDIO 面板是展示訓練過程中處理的音訊資料。可嵌入音訊的小部件,用於播放通過tf.summary.audio()函式儲存的音訊。一個音訊summary要存成 的二維字元張量。其中,k為summary中記錄的音訊被剪輯的次數,每排張量是一對[encoded_audio, label],其中,encoded_audio 是在summary中指定其編碼的二進位制字串,label是一個描述音訊片段的UTF-8編碼的字串。
儀表盤設定為每行對應不同的標籤,每列對應一個執行。該儀表盤始終嵌入每個標籤的最新音訊。

五、GRAPHS

GRAPHS 面板是對理解神經網路結構最有幫助的一個面板,它直觀地展示了資料流圖。下圖所示介面中節點之間的連線即為資料流,連線越粗,說明在兩個節點之間流動的張量(tensor)越多。
這裡寫圖片描述

在GRAPHS 面板的左側,可以選擇迭代步驟。可以用不同Color(顏色)來表示不同的Structure(整個資料流圖的結構),或者用不同Color 來表示不同Device(裝置)。例如,當使用多個GPU 時,各個節點分別使用的GPU 不同。當我們選擇特定的某次迭代時,可以顯示出各個節點的Compute time(計算時間)以及Memory(記憶體消耗)。
這裡寫圖片描述

六、DISTRIBUTIONS

DISTRIBUTIONS 面板和接下來要講的HISTOGRAMS 面板類似,只不過是用平面來表示來自特定層的啟用前後、權重和偏置的分佈,它顯示了一些分發的高階統計資訊。
這裡寫圖片描述

七、HISTOGRAMS

HISTOGRAMS面板,統計tensorflow中的張量隨著迭代輪數的變化情況。它用於展示通過tf.summary.histogram記錄的資料的變化趨勢。如下程式碼所示:

# 用直方圖記錄引數的分佈
tf.summary.histogram('histogram', var)

# 執行wx+b的線性計算,並且用直方圖記錄下來
tf.summary.histogram('linear', preactivate)

# 將線性輸出經過激勵函式,並將輸出也用直方圖記錄下來
tf.summary.histogram('activations', activations)

上述程式碼將神經網路中某一層的引數分佈、線性計算結果、經過激勵函式的計算結果資訊加入到日誌檔案中,執行程式生成日誌後,啟動tensorboard就可以在HISTOGRAMS欄目下看到對應的展開影象。
HISTOGRAMS 主要是立體地展現來自特定層的啟用前後、權重和偏置的分佈。
這裡寫圖片描述

八、EMBEDDINGS

EMBEDDINGS 面板展示的是詞嵌入投影儀。(後續做詞嵌入的時候更新上…….)