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

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

轉自https://morvanzhou.github.io/tutorials/machine-learning/tensorflow/4-1-tensorboard1/

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

學會用 Tensorflow 自帶的 tensorboard 去視覺化我們所建造出來的神經網路是一個很好的學習理解方式. 用最直觀的流程圖告訴你你的神經網路是長怎樣,有助於你發現程式設計中間的問題和疑問.

目錄

效果 

搭建圖紙 

可能會遇到的問題 

完整程式碼


效果 

好,我們開始吧。

這次我們會介紹如何視覺化神經網路。因為很多時候我們都是做好了一個神經網路,但是沒有一個影象可以展示給大家看。這一節會介紹一個TensorFlow的視覺化工具 — tensorboard :) 通過使用這個工具我們可以很直觀的看到整個神經網路的結構、框架。 以前幾節的程式碼為例:相關程式碼 通過tensorflow的工具大致可以看到,今天要顯示的神經網路差不多是這樣子的

Tensorboard 視覺化好幫手 1

同時我們也可以展開看每個layer中的一些具體的結構:

Tensorboard 視覺化好幫手 1

好,通過閱讀程式碼和之前的圖片我們大概知道了此處是有一個輸入層(inputs),一個隱含層(layer),還有一個輸出層(output) 現在可以看看如何進行視覺化.

搭建圖紙 

首先從 Input 開始:

# define placeholder for inputs to network
xs = tf.placeholder(tf.float32, [None, 1])
ys = tf.placeholder(tf.float32, [None, 1])

對於input我們進行如下修改: 首先,可以為xs指定名稱為x_in:

xs= tf.placeholder(tf.float32, [None, 1],name='x_in')

然後再次對ys指定名稱y_in:

ys= tf.placeholder(tf.loat32, [None, 1],name='y_in')

這裡指定的名稱將來會在視覺化的圖層inputs中顯示出來

使用with tf.name_scope('inputs')可以將xsys包含進來,形成一個大的圖層,圖層的名字就是with tf.name_scope()方法裡的引數。

with tf.name_scope('inputs'):
    # define placeholder for inputs to network
    xs = tf.placeholder(tf.float32, [None, 1])
    ys = tf.placeholder(tf.float32, [None, 1])

接下來開始編輯layer , 請看編輯前的程式片段 :

def add_layer(inputs, in_size, out_size, activation_function=None):
    # add one more layer and return the output of this layer
    Weights = tf.Variable(tf.random_normal([in_size, out_size]))
    biases = tf.Variable(tf.zeros([1, out_size]) + 0.1)
    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, )
    return outputs

這裡的名字應該叫layer, 下面是編輯後的:

def add_layer(inputs, in_size, out_size, activation_function=None):
    # add one more layer and return the output of this layer
    with tf.name_scope('layer'):
        Weights= tf.Variable(tf.random_normal([in_size, out_size]))
        # and so on...

在定義完大的框架layer之後,同時也需要定義每一個’框架‘裡面的小部件:(Weights biases 和 activation function): 現在現對 Weights 定義: 定義的方法同上,可以使用tf.name.scope()方法,同時也可以在Weights中指定名稱W。 即為:

    def add_layer(inputs, in_size, out_size, activation_function=None):
	#define layer name
    with tf.name_scope('layer'):
        #define weights name 
        with tf.name_scope('weights'):
            Weights= tf.Variable(tf.random_normal([in_size, out_size]),name='W')
        #and so on......

接著繼續定義biases , 定義方式同上。

def add_layer(inputs, in_size, out_size, activation_function=None):
    #define layer name
    with tf.name_scope('layer'):
        #define weights name 
        with tf.name_scope('weights')
            Weights= tf.Variable(tf.random_normal([in_size, out_size]),name='W')
        # define biase
        with tf.name_scope('Wx_plus_b'):
            Wx_plus_b = tf.add(tf.matmul(inputs, Weights), biases)
        # and so on....

activation_function 的話,可以暫時忽略。因為當你自己選擇用 tensorflow 中的激勵函式(activation function)的時候,tensorflow會預設新增名稱。 最終,layer形式如下:

def add_layer(inputs, in_size, out_size, activation_function=None):
    # add one more layer and return the output of this layer
    with tf.name_scope('layer'):
        with tf.name_scope('weights'):
            Weights = tf.Variable(
            tf.random_normal([in_size, out_size]), 
            name='W')
        with tf.name_scope('biases'):
            biases = tf.Variable(
            tf.zeros([1, out_size]) + 0.1, 
            name='b')
        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, )
        return outputs

效果如下:(有沒有看見剛才定義layer裡面的“內部構件”呢?)

Tensorboard 視覺化好幫手 1

最後編輯loss部分:將with tf.name_scope()新增在loss上方,併為它起名為loss

# the error between prediciton and real data
with tf.name_scope('loss'):
    loss = tf.reduce_mean(
    tf.reduce_sum(
    tf.square(ys - prediction),
    eduction_indices=[1]
    ))

這句話就是“繪製” loss了, 如下:

Tensorboard 視覺化好幫手 1

使用with tf.name_scope()再次對train_step部分進行編輯,如下:

with tf.name_scope('train'):
    train_step = tf.train.GradientDescentOptimizer(0.1).minimize(loss)

我們需要使用 tf.summary.FileWriter() (tf.train.SummaryWriter() 這種方式已經在 tf >= 0.12 版本中摒棄) 將上面‘繪畫’出的圖儲存到一個目錄中,以方便後期在瀏覽器中可以瀏覽。 這個方法中的第二個引數需要使用sess.graph , 因此我們需要把這句話放在獲取session的後面。 這裡的graph是將前面定義的框架資訊收集起來,然後放在logs/目錄下面。

sess = tf.Session() # get session
# tf.train.SummaryWriter soon be deprecated, use following
writer = tf.summary.FileWriter("logs/", sess.graph)

最後在你的terminal(終端)中 ,使用以下命令

tensorboard --logdir logs

同時將終端中輸出的網址複製到瀏覽器中,便可以看到之前定義的檢視框架了。

tensorboard 還有很多其他的引數,希望大家可以多多瞭解, 可以使用 tensorboard --help 檢視tensorboard的詳細引數 最終的全部程式碼在這裡

可能會遇到的問題 

(1) 而且與 tensorboard 相容的瀏覽器是 “Google Chrome”. 使用其他的瀏覽器不保證所有內容都能正常顯示.

(2) 同時注意, 如果使用 http://0.0.0.0:6006 網址打不開的朋友們, 請使用 http://localhost:6006, 大多數朋友都是這個問題.

(3) 請確保你的 tensorboard 指令是在你的 logs 檔案根目錄執行的. 如果在其他目錄下, 比如 Desktop 等, 可能不會成功看到圖. 比如在下面這個目錄, 你要 cd 到 project 這個地方執行 /project > tensorboard --logdir logs

- project
   - logs
   model.py
   env.py

(4) 討論區的朋友使用 anaconda 下的 python3.5 的虛擬環境, 如果你輸入 tensorboard 的指令, 出現報錯: "tensorboard" is not recognized as an internal or external command...

解決方法的關鍵就是需要啟用TensorFlow. 管理員模式開啟 Anaconda Prompt, 輸入 activate tensorflow, 接著按照上面的流程執行 tensorboard 指令.

下一篇【深度學習】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


def add_layer(inputs, in_size, out_size, activation_function=None):
    # add one more layer and return the output of this layer
    with tf.name_scope('layer'):
        with tf.name_scope('weights'):
            Weights = tf.Variable(tf.random_normal([in_size, out_size]), name='W')
        with tf.name_scope('biases'):
            biases = tf.Variable(tf.zeros([1, out_size]) + 0.1, name='b')
        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, )
        return outputs


# 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, activation_function=tf.nn.relu)
# add output layer
prediction = add_layer(l1, 10, 1, 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]))

with tf.name_scope('train'):
    train_step = tf.train.GradientDescentOptimizer(0.1).minimize(loss)

sess = tf.Session()

# tf.train.SummaryWriter soon be deprecated, use following
if int((tf.__version__).split('.')[1]) < 12 and int((tf.__version__).split('.')[0]) < 1:  # tensorflow version < 0.12
    writer = tf.train.SummaryWriter('logs/', sess.graph)
else: # tensorflow version >= 0.12
    writer = tf.summary.FileWriter("logs/", sess.graph)

# tf.initialize_all_variables() no long valid from
# 2017-03-02 if using tensorflow >= 0.12
if int((tf.__version__).split('.')[1]) < 12 and int((tf.__version__).split('.')[0]) < 1:
    init = tf.initialize_all_variables()
else:
    init = tf.global_variables_initializer()
sess.run(init)

# direct to the local dir and run this in terminal:
# $ tensorboard --logdir=logs