1. 程式人生 > >【深度學習】Tensorboard 視覺化好幫手2

【深度學習】Tensorboard 視覺化好幫手2

轉自https://morvanzhou.github.io/tutorials/machine-learning/tensorflow/4-2-tensorboard2/

目錄

要點 

製作輸入源 

在 layer 中為 Weights, biases 設定變化圖表 

設定loss的變化圖 

給所有訓練圖合併 

訓練資料 

在 tensorboard 中檢視效果 

完整程式碼


要點 

注意: 本節內容會用到瀏覽器, 而且與 tensorboard 相容的瀏覽器是 “Google Chrome”. 使用其他的瀏覽器不保證所有內容都能正常顯示.

上一篇【深度學習】Tensorboard 視覺化好幫手1講到了 如何視覺化TesorBorad整個神經網路結構的過程。 其實tensorboard還可以視覺化訓練過程( biase變化過程) , 這節重點講一下視覺化訓練過程的圖示是如何做的 。請看下圖, 這是如何做到的呢?

Tensorboard 視覺化好幫手 2

在histograms裡面我們還可以看到更多的layers的變化:

Tensorboard 視覺化好幫手 2

(P.S. 灰貓使用的 tensorflow v1.1 顯示的效果可能和視訊中的不太一樣, 但是 tensorboard 的使用方法的是一樣的。)

這裡還有一個events , 在這次練習中我們會把 整個訓練過程中的誤差值(loss)在event裡面顯示出來, 甚至你可以顯示更多你想要顯示的東西.

Tensorboard 視覺化好幫手 2

好了, 開始練習吧, 本節內容包括:

製作輸入源 

由於這節我們觀察訓練過程中神經網路的變化, 所以首先要添一些模擬資料. 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

輸入源的問題解決之後, 我們開始製作對Weightsbiases的變化圖表吧. 我們期望可以做到如下的效果, 那麼首先從 layer1/weight 做起吧

Tensorboard 視覺化好幫手 2

這個效果是如何做到的呢,請看下一個標題

在 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中每個圖表的上方顯示, 如下圖所示:

Tensorboard 視覺化好幫手 2

由於我們對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() 方法.

Tensorboard 視覺化好幫手 2

觀看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, 大多數朋友都是這個問題.

會有如下輸出:

Tensorboard 視覺化好幫手 2

將輸出中顯示的URL地址貼上到瀏覽器中便可以檢視. 最終的效果如下:

Tensorboard 視覺化好幫手 2

完整程式碼

# 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