【深度學習】Tensorboard 視覺化好幫手2
轉自https://morvanzhou.github.io/tutorials/machine-learning/tensorflow/4-2-tensorboard2/
目錄
在 layer 中為 Weights, biases 設定變化圖表
要點
注意: 本節內容會用到瀏覽器, 而且與 tensorboard 相容的瀏覽器是 “Google Chrome”. 使用其他的瀏覽器不保證所有內容都能正常顯示.
上一篇【深度學習】Tensorboard 視覺化好幫手1講到了 如何視覺化TesorBorad整個神經網路結構的過程。 其實tensorboard還可以視覺化訓練過程( biase變化過程) , 這節重點講一下視覺化訓練過程的圖示是如何做的 。請看下圖, 這是如何做到的呢?
在histograms裡面我們還可以看到更多的layers的變化:
(P.S. 灰貓使用的 tensorflow v1.1 顯示的效果可能和視訊中的不太一樣, 但是 tensorboard 的使用方法的是一樣的。)
這裡還有一個events , 在這次練習中我們會把 整個訓練過程中的誤差值(loss)在event裡面顯示出來, 甚至你可以顯示更多你想要顯示的東西.
好了, 開始練習吧, 本節內容包括:
製作輸入源
由於這節我們觀察訓練過程中神經網路的變化, 所以首先要添一些模擬資料. Python 的 numpy 工具包可以幫助我們製造一些模擬資料. 所以我們先匯入這個工具包:
import tensorflow as tf
import numpy as np
然後藉助 np 中的 np.linespace()
產生隨機的數字, 同時為了模擬更加真實我們會新增一些噪聲, 這些噪聲是通過 np.random.normal()
隨機產生的.
## make up some data x_data= np.linspace(-1, 1, 300, dtype=np.float32)[:,np.newaxis] noise= np.random.normal(0, 0.05, x_data.shape).astype(np.float32) y_data= np.square(x_data) -0.5+ noise
輸入源的問題解決之後, 我們開始製作對Weights
和biases
的變化圖表吧. 我們期望可以做到如下的效果, 那麼首先從 layer1/weight 做起吧
這個效果是如何做到的呢,請看下一個標題
在 layer 中為 Weights, biases 設定變化圖表
通過上圖的觀察我們發現每個 layer 後面有有一個數字: layer1 和layer2
於是我們在 add_layer()
方法中新增一個引數 n_layer
,用來標識層數, 並且用變數 layer_name
代表其每層的名名稱, 程式碼如下:
def add_layer(
inputs ,
in_size,
out_size,
n_layer,
activation_function=None):
## add one more layer and return the output of this layer
layer_name='layer%s'%n_layer ## define a new var
## and so on ……
接下來,我們層中的Weights
設定變化圖, tensorflow中提供了tf.histogram_summary()
方法,用來繪製圖片, 第一個引數是圖表的名稱, 第二個引數是圖表要記錄的變數
def add_layer(inputs ,
in_size,
out_size,n_layer,
activation_function=None):
## add one more layer and return the output of this layer
layer_name='layer%s'%n_layer
with tf.name_scope('layer'):
with tf.name_scope('weights'):
Weights= tf.Variable(tf.random_normal([in_size, out_size]),name='W')
# tf.histogram_summary(layer_name+'/weights',Weights) # tensorflow 0.12 以下版的
tf.summary.histogram(layer_name + '/weights', Weights) # tensorflow >= 0.12
##and so no ……
同樣的方法我們對biases
進行繪製圖標:
with tf.name_scope('biases'):
biases = tf.Variable(tf.zeros([1,out_size])+0.1, name='b')
# tf.histogram_summary(layer_name+'/biase',biases) # tensorflow 0.12 以下版的
tf.summary.histogram(layer_name + '/biases', biases) # Tensorflow >= 0.12
至於activation_function
可以不繪製. 我們對output 使用同樣的方法:
# tf.histogram_summary(layer_name+'/outputs',outputs) # tensorflow 0.12 以下版本
tf.summary.histogram(layer_name + '/outputs', outputs) # Tensorflow >= 0.12
最終經過我們的修改 , addlayer()
方法成為如下的樣子:
def add_layer(inputs ,
in_size,
out_size,n_layer,
activation_function=None):
## add one more layer and return the output of this layer
layer_name='layer%s'%n_layer
with tf.name_scope(layer_name):
with tf.name_scope('weights'):
Weights= tf.Variable(tf.random_normal([in_size, out_size]),name='W')
# tf.histogram_summary(layer_name+'/weights',Weights)
tf.summary.histogram(layer_name + '/weights', Weights) # tensorflow >= 0.12
with tf.name_scope('biases'):
biases = tf.Variable(tf.zeros([1,out_size])+0.1, name='b')
# tf.histogram_summary(layer_name+'/biase',biases)
tf.summary.histogram(layer_name + '/biases', biases) # Tensorflow >= 0.12
with tf.name_scope('Wx_plus_b'):
Wx_plus_b = tf.add(tf.matmul(inputs,Weights), biases)
if activation_function is None:
outputs=Wx_plus_b
else:
outputs= activation_function(Wx_plus_b)
# tf.histogram_summary(layer_name+'/outputs',outputs)
tf.summary.histogram(layer_name + '/outputs', outputs) # Tensorflow >= 0.12
return outputs
修改之後的名稱會顯示在每個tensorboard中每個圖表的上方顯示, 如下圖所示:
由於我們對addlayer
添加了一個引數, 所以修改之前呼叫addlayer()
函式的地方. 對此處進行修改:
# add hidden layer
l1= add_layer(xs, 1, 10 , activation_function=tf.nn.relu)
# add output layer
prediction= add_layer(l1, 10, 1, activation_function=None)
新增n_layer
引數後, 修改成為 :
# add hidden layer
l1= add_layer(xs, 1, 10, n_layer=1, activation_function=tf.nn.relu)
# add output layer
prediction= add_layer(l1, 10, 1, n_layer=2, activation_function=None)
設定loss的變化圖
Loss
的變化圖和之前設定的方法略有不同. loss是在tesnorBorad 的event下面的, 這是由於我們使用的是tf.scalar_summary()
方法.
觀看loss的變化比較重要. 當你的loss呈下降的趨勢,說明你的神經網路訓練是有效果的.
修改後的程式碼片段如下:
with tf.name_scope('loss'):
loss= tf.reduce_mean(tf.reduce_sum(
tf.square(ys- prediction), reduction_indices=[1]))
# tf.scalar_summary('loss',loss) # tensorflow < 0.12
tf.summary.scalar('loss', loss) # tensorflow >= 0.12
給所有訓練圖合併
接下來, 開始合併打包。 tf.merge_all_summaries()
方法會對我們所有的 summaries
合併到一起. 因此在原有程式碼片段中新增:
sess= tf.Session()
# merged= tf.merge_all_summaries() # tensorflow < 0.12
merged = tf.summary.merge_all() # tensorflow >= 0.12
# writer = tf.train.SummaryWriter('logs/', sess.graph) # tensorflow < 0.12
writer = tf.summary.FileWriter("logs/", sess.graph) # tensorflow >=0.12
# sess.run(tf.initialize_all_variables()) # tf.initialize_all_variables() # tf 馬上就要廢棄這種寫法
sess.run(tf.global_variables_initializer()) # 替換成這樣就好
訓練資料
假定給出了x_data,y_data
並且訓練1000次.
for i in range(1000):
sess.run(train_step, feed_dict={xs:x_data, ys:y_data})
以上這些僅僅可以記錄很繪製出訓練的圖表, 但是不會記錄訓練的資料。 為了較為直觀顯示訓練過程中每個引數的變化,我們每隔上50次就記錄一次結果 , 同時我們也應注意, merged 也是需要run 才能發揮作用的,所以在for迴圈中寫下:
if i%50 == 0:
rs = sess.run(merged,feed_dict={xs:x_data,ys:y_data})
writer.add_summary(rs, i)
最後修改後的片段如下:
for i in range(1000):
sess.run(train_step, feed_dict={xs:x_data, ys:y_data})
if i%50 == 0:
rs = sess.run(merged,feed_dict={xs:x_data,ys:y_data})
writer.add_summary(rs, i)
在 tensorboard 中檢視效果
程式執行完畢之後, 會產生logs目錄 , 使用命令 tensorboard --logdir logs
注意: 本節內容會用到瀏覽器, 而且與 tensorboard 相容的瀏覽器是 “Google Chrome”. 使用其他的瀏覽器不保證所有內容都能正常顯示.
同時注意, 如果使用 http://0.0.0.0:6006
或者 tensorboard 中顯示的網址打不開的朋友們, 請使用 http://localhost:6006
, 大多數朋友都是這個問題.
會有如下輸出:
將輸出中顯示的URL地址貼上到瀏覽器中便可以檢視. 最終的效果如下:
完整程式碼
# View more python learning tutorial on my Youtube and Youku channel!!!
# Youtube video tutorial: https://www.youtube.com/channel/UCdyjiB5H8Pu7aDTNVXTTpcg
# Youku video tutorial: http://i.youku.com/pythontutorial
"""
Please note, this code is only for python 3+. If you are using python 2+, please modify the code accordingly.
"""
from __future__ import print_function
import tensorflow as tf
import numpy as np
def add_layer(inputs, in_size, out_size, n_layer, activation_function=None):
# add one more layer and return the output of this layer
layer_name = 'layer%s' % n_layer
with tf.name_scope(layer_name):
with tf.name_scope('weights'):
Weights = tf.Variable(tf.random_normal([in_size, out_size]), name='W')
tf.summary.histogram(layer_name + '/weights', Weights)
with tf.name_scope('biases'):
biases = tf.Variable(tf.zeros([1, out_size]) + 0.1, name='b')
tf.summary.histogram(layer_name + '/biases', biases)
with tf.name_scope('Wx_plus_b'):
Wx_plus_b = tf.add(tf.matmul(inputs, Weights), biases)
if activation_function is None:
outputs = Wx_plus_b
else:
outputs = activation_function(Wx_plus_b, )
tf.summary.histogram(layer_name + '/outputs', outputs)
return outputs
# Make up some real data
x_data = np.linspace(-1, 1, 300)[:, np.newaxis]
noise = np.random.normal(0, 0.05, x_data.shape)
y_data = np.square(x_data) - 0.5 + noise
# define placeholder for inputs to network
with tf.name_scope('inputs'):
xs = tf.placeholder(tf.float32, [None, 1], name='x_input')
ys = tf.placeholder(tf.float32, [None, 1], name='y_input')
# add hidden layer
l1 = add_layer(xs, 1, 10, n_layer=1, activation_function=tf.nn.relu)
# add output layer
prediction = add_layer(l1, 10, 1, n_layer=2, activation_function=None)
# the error between prediciton and real data
with tf.name_scope('loss'):
loss = tf.reduce_mean(tf.reduce_sum(tf.square(ys - prediction),
reduction_indices=[1]))
tf.summary.scalar('loss', loss)
with tf.name_scope('train'):
train_step = tf.train.GradientDescentOptimizer(0.1).minimize(loss)
sess = tf.Session()
merged = tf.summary.merge_all()
writer = tf.summary.FileWriter("logs/", sess.graph)
init = tf.global_variables_initializer()
sess.run(init)
for i in range(1000):
sess.run(train_step, feed_dict={xs: x_data, ys: y_data})
if i % 50 == 0:
result = sess.run(merged,
feed_dict={xs: x_data, ys: y_data})
writer.add_summary(result, i)
# direct to the local dir and run this in terminal:
# $ tensorboard --logdir logs