【深度學習】Tensorboard 視覺化好幫手1
轉自https://morvanzhou.github.io/tutorials/machine-learning/tensorflow/4-1-tensorboard1/
注意: 本節內容會用到瀏覽器, 而且與 tensorboard 相容的瀏覽器是 “Google Chrome”. 使用其他的瀏覽器不保證所有內容都能正常顯示.
學會用 Tensorflow 自帶的 tensorboard 去視覺化我們所建造出來的神經網路是一個很好的學習理解方式. 用最直觀的流程圖告訴你你的神經網路是長怎樣,有助於你發現程式設計中間的問題和疑問.
目錄
效果
好,我們開始吧。
這次我們會介紹如何視覺化神經網路。因為很多時候我們都是做好了一個神經網路,但是沒有一個影象可以展示給大家看。這一節會介紹一個TensorFlow的視覺化工具 — tensorboard :) 通過使用這個工具我們可以很直觀的看到整個神經網路的結構、框架。 以前幾節的程式碼為例:相關程式碼 通過tensorflow的工具大致可以看到,今天要顯示的神經網路差不多是這樣子的
同時我們也可以展開看每個layer中的一些具體的結構:
好,通過閱讀程式碼和之前的圖片我們大概知道了此處是有一個輸入層(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')
可以將xs
和ys
包含進來,形成一個大的圖層,圖層的名字就是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裡面的“內部構件”呢?)
最後編輯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了, 如下:
使用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 指令.
完整程式碼
# 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