什麼是TensorBoard?

Java3y發表於2019-04-20

前言

只有光頭才能變強。

文字已收錄至我的GitHub倉庫,歡迎Star:github.com/ZhongFuChen…

回顧前面:

這篇文章主要講講TensorBoard的基本使用以及name_scope和variable_scope的區別

一、入門TensorBoard

首先來講講TensorBoard是什麼吧,我當時是在官方文件裡學習的,官網也放出了介紹TensorBoard的視訊。我在b站搜了一把,發現也有,大家可以先去看看視訊瞭解一下(其實已經說得很好了):

為了更方便 TensorFlow 程式的理解、除錯與優化,於是就有了TensorBoard 這樣的的視覺化工具

因為我們編寫出來的TensorFlow程式,建好一個神經網路,其實我們也不知道神經網路裡頭具體細節到底做了什麼,要人工除錯十分困難(就好比你無法想象出遞迴的所有步驟一樣)。有了TensorBoard,可以將TensorFlow程式的執行步驟都顯示出來,非常直觀。並且,我們可以對訓練的引數(比如loss值)進行統計,用的方式來檢視變化的趨勢。

1.1 name_scope和variable_scope

在視訊中其實也有提到,我們想要TensorBoard的圖能夠更好地展示(更加有條理),那一般我們需要對其用name_scope取名。

那除了name_scope,還有一個叫做variable_scope。那他們有什麼區別呢?顧名思義,name_scope是一個名稱作用域,variable_scope是變數作用域。

在前面文章中,建立變數有兩種方式,一種是用tf.get_variable()來建立,一種是用tf.Variable()來建立。這兩種建立方式也是有區別的。

  • tf.name_scope下時,tf.get_variable()建立的變數名不受name_scope 的影響,而且在未指定共享變數時,如果重名就會報錯。tf.Variable()會自動檢測有沒有變數重名,如果有則會自行處理(自動建立一個)

比如下面的程式碼:

with tf.name_scope('name_sp1') as scp1:
    with tf.variable_scope('var_scp2') as scp2:
        with tf.name_scope('name_scp3') as scp3:
            a = tf.Variable('a')
            b = tf.get_variable('b')
複製程式碼

等同於:

with tf.name_scope('name_sp1') as scp1:
    with tf.name_scope('name_sp2') as scp2:
        with tf.name_scope('name_scp3') as scp3:
            a = tf.Variable('a')

with tf.variable_scope('var_scp2') as scp2:
        b = tf.get_variable('b')
複製程式碼

這裡體現的是如果用get_variable的方式來建立物件,是不受name_scope所影響的。


要注意的是,下面的程式碼會報錯。因為在scp作用域下壓根就沒有a這個變數,同時又設定成reuse=True。這裡因為的是找不到共享變數而出錯

with tf.variable_scope('scp', reuse=True) as scp:
    a = tf.get_varialbe('a') #報錯
複製程式碼

同樣地,下面的程式碼也會報錯,因為明明已經有共享變數了,但設定成reuse=false。所以就會報錯。

with tf.variable_scope('scp', reuse=False) as scp:    
     a = tf.get_varialbe('a')
    a = tf.get_varialbe('a') #報錯
複製程式碼

最後,我們再來看這個例子,應該就可以看懂了。

with tf.variable_scope('variable_scope_y') as scope:
    var1 = tf.get_variable(name='var1', shape=[1], dtype=tf.float32)
    scope.reuse_variables()  # 設定共享變數
    var1_reuse = tf.get_variable(name='var1')
    var2 = tf.Variable(initial_value=[2.], name='var2', dtype=tf.float32)
    var2_reuse = tf.Variable(initial_value=[2.], name='var2', dtype=tf.float32)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(var1.name, sess.run(var1))
    print(var1_reuse.name, sess.run(var1_reuse))
    print(var2.name, sess.run(var2))
    print(var2_reuse.name, sess.run(var2_reuse))
# 輸出結果:
# variable_scope_y/var1:0 [-1.59682846]
# variable_scope_y/var1:0 [-1.59682846]   可以看到變數var1_reuse重複使用了var1
# variable_scope_y/var2:0 [ 2.]
# variable_scope_y/var2_1:0 [ 2.]
複製程式碼

參考資料:

1.2 TensorBoard例子

下面我們來看一個TensorBoard簡單的入門例子,感受一下:

def learn_tensor_board_2():
    # prepare the original data
    with tf.name_scope('data'):
        x_data = np.random.rand(100).astype(np.float32)
        y_data = 0.3 * x_data + 0.1
    ##creat parameters
    with tf.name_scope('parameters'):
        with tf.name_scope('weights'):
            weight = tf.Variable(tf.random_uniform([1], -1.0, 1.0))
            tf.summary.histogram('weight', weight)
        with tf.name_scope('biases'):
            bias = tf.Variable(tf.zeros([1]))
            tf.summary.histogram('bias', bias)
    ##get y_prediction
    with tf.name_scope('y_prediction'):
        y_prediction = weight * x_data + bias
    ##compute the loss
    with tf.name_scope('loss'):
        loss = tf.reduce_mean(tf.square(y_data - y_prediction))
        tf.summary.scalar('loss', loss)
    ##creat optimizer
    optimizer = tf.train.GradientDescentOptimizer(0.5)
    # creat train ,minimize the loss
    with tf.name_scope('train'):
        train = optimizer.minimize(loss)
    # creat init
    with tf.name_scope('init'):
        init = tf.global_variables_initializer()
    ##creat a Session
    sess = tf.Session()
    # merged
    merged = tf.summary.merge_all()
    ##initialize
    writer = tf.summary.FileWriter("/Users/zhongfucheng/tensorboard/loss-2", sess.graph)
    sess.run(init)
    ## Loop
    for step in range(201):
        sess.run(train)
        rs = sess.run(merged)
        writer.add_summary(rs, step)


if __name__ == '__main__':
    learn_tensor_board_2()
    # 啟動完了之後,要在命令列上執行tensor_board的命令,指定其目錄,最後我們就可以通過6006的預設埠訪問我們的圖。

複製程式碼

(例子來源網路,我改動了一下,出處我忘了,侵刪~)

接下來,我們啟動一下TensorBoard,看看圖是怎麼樣的,啟動命令如下:

tensorboard --logdir=/Users/zhongfucheng/tensorboard/loss-2
複製程式碼

啟動成功的圖:

啟動成功的圖

通過6006埠我們去訪問一下,首先我們可以檢測到loss值的變更:

loss值的變更

我們也可以檢視TensorFlow程式大概的執行步驟:

Tensorflow大概的執行步驟

引數w和b的直方圖:

引數w和b的直方圖

總之,TensorBoard可以方便地檢視我們引數的變化,以便更好理解我們寫的程式碼。

參考資料:

最後

樂於輸出乾貨的Java技術公眾號:Java3y。公眾號內有200多篇原創技術文章、海量視訊資源、精美腦圖,不妨來關注一下!

帥的人都關注了

覺得我的文章寫得不錯,不妨點一下

相關文章