基于tensorboard的模型訓(xùn)練過(guò)程可視化

2018年9月14日筆記
閱讀本文的前提是已經(jīng)閱讀《基于tensorflow的一元二次方程回歸預(yù)測(cè)》,文章鏈接:http://www.itdecent.cn/p/b27860402fe3
本文使用tensorboard對(duì)一元二次方程回歸預(yù)測(cè)的模型訓(xùn)練過(guò)程做可視化展現(xiàn)。

0.編程環(huán)境

安裝tensorflow命令:pip install tensorflow
操作系統(tǒng):Win10
tensorflow版本:1.6
tensorboard版本:1.6
python版本:3.6

1.運(yùn)行tensorboard

本文作者花費(fèi)了4個(gè)小時(shí)才成功運(yùn)行tensorboard,失敗的主要原因是文件夾中帶有中文。
為了避免讀者踩坑,請(qǐng)跟隨本文作者做相同操作。
在桌面新建一個(gè)文件夾tensorboardTest,如下圖所示:

image.png

作者提供可以直接在tensorboard中查看的文件。
下載鏈接: https://pan.baidu.com/s/1uq7ElLd4z8AkTAs5t2gXxw 密碼: fiqs
下載文件后在放到不含有中文的文件夾中,并在此文件夾下打開(kāi)cmd,如下圖所示:
image.png

在cmd中輸入命令并運(yùn)行:tensorboard --logdir ./
成功運(yùn)行的結(jié)果如下圖所示:
image.png

開(kāi)啟tensorboard服務(wù)后,可以在瀏覽器訪問(wèn)網(wǎng)址:localhost:6006或者上圖中紅色方框內(nèi)的鏈接
下圖的4個(gè)紅色箭頭標(biāo)注表示通過(guò)代碼做出了4張圖,第1張圖是loss的變化曲線圖;
image.png

第2張圖是神經(jīng)網(wǎng)絡(luò)架構(gòu)圖;
image.png

第3張圖是權(quán)重Weights和偏置biases的變化曲線圖;
image.png

第4張圖是權(quán)重Weights和偏置biases的分布直方圖。
image.png

2.打開(kāi)jupyter

下圖中左邊紅色方框指的是要在文件夾tensorboardTest打開(kāi)PowerShell或者cmd。
在PowerShell或者cmd中輸入命令并運(yùn)行:jupyter notebook

image.png

運(yùn)行命令后會(huì)自動(dòng)打開(kāi)瀏覽器,界面如下圖所示,點(diǎn)擊下圖紅色箭頭標(biāo)注處新建代碼文件。
image.png

點(diǎn)擊下圖紅色箭頭標(biāo)注處修改代碼文件名為tensorboardTest1。
image.png

3.檢測(cè)tensorflow環(huán)境

如果下面一段代碼運(yùn)行成功,則說(shuō)明安裝tensorflow環(huán)境成功。

import tensorflow as tf
hello = tf.constant('hello world')
session = tf.Session()
session.run(hello)

上面一段代碼成功運(yùn)行的結(jié)果如下圖所示:


image.png

4.數(shù)據(jù)準(zhǔn)備

import tensorflow as tf
import numpy as np

batch_size = 100
X_data = np.linspace(-1, 1, 300).reshape(-1, 1).astype('float32')
noise = np.random.normal(0, 0.1, X_data.shape).astype('float32')
y_data = np.square(X_data) - 0.5 + noise
with tf.name_scope('inputs'):
    X_holder = tf.placeholder(tf.float32, name='input_X')
    y_holder = tf.placeholder(tf.float32, name='input_y')

第1行代碼導(dǎo)入numpy庫(kù),起別名np;
第2行代碼導(dǎo)入tensorflow庫(kù),起別名tf;
第4行代碼定義投入訓(xùn)練的樣本數(shù)量batch_size。
第5行代碼調(diào)用np.linspace方法獲得一個(gè)區(qū)間內(nèi)的等間距點(diǎn),例如np.linspace(0, 1, 11)是獲取[0, 1]區(qū)間的11個(gè)等間距點(diǎn)。如下圖所示:

image.png

第6行代碼調(diào)用np.random.normal方法初始化符合正態(tài)分布的點(diǎn),第1個(gè)參數(shù)是正態(tài)分布的均值,第2個(gè)參數(shù)是正態(tài)分布的方差,第3個(gè)參數(shù)是返回值的shape,返回值的數(shù)據(jù)類型為ndarray對(duì)象。
第7行代碼調(diào)用np.square方法對(duì)X中的每一個(gè)值求平方,- 0.5使用了ndarray對(duì)象的廣播特性,最后加上噪聲noise,將計(jì)算結(jié)果賦值給變量y。
第8行代碼中scope中文叫做適用范圍,每定義一個(gè)tf.name_scope,在tensorboard界面的graph中會(huì)有一個(gè)節(jié)點(diǎn)。
第9、10行代碼中placeholder中文叫做占位符,tf.placeholder方法的第1個(gè)參數(shù)是tensorflow中的數(shù)據(jù)類型;第2個(gè)關(guān)鍵字參數(shù)name的數(shù)據(jù)類型是字符串,是在tensorboard界面中的顯示名。

5.搭建神經(jīng)網(wǎng)絡(luò)

定義addConnect函數(shù),作用是添加1層連接。
因?yàn)樵撋窠?jīng)網(wǎng)絡(luò)總共有3層:輸入層、隱層、輸出層,所以需要調(diào)用2次addConnect函數(shù)添加2層連接。
addConnect函數(shù)第1個(gè)參數(shù)是輸入矩陣,第2個(gè)參數(shù)是輸入矩陣的列數(shù),第3個(gè)參數(shù)是輸出矩陣的列數(shù),第4個(gè)參數(shù)用來(lái)定義是第幾層連接,第5個(gè)參數(shù)是激活函數(shù)。
最后6行代碼定義損失函數(shù)、優(yōu)化器、訓(xùn)練過(guò)程。

def addConnect(inputs, in_size, out_size, n_connect, activation_function=None):
    connect_name = 'connect%s' %n_connect
    with tf.name_scope(connect_name):
        with tf.name_scope('Weights'):
            Weights = tf.Variable(tf.random_normal([in_size, out_size]) ,name='W')
            tf.summary.histogram(connect_name + '/Weights', Weights)
        with tf.name_scope('biases'):
            biases = tf.Variable(tf.zeros([1, out_size]) + 0.1, name='b')
            tf.summary.histogram(connect_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:
            return Wx_plus_b
        else:
            return activation_function(Wx_plus_b)
        
connect_1 = addConnect(X_holder, 1, 10, 1, tf.nn.relu)
predict_y = addConnect(connect_1, 10, 1, 2)
with tf.name_scope('loss'):
    loss = tf.reduce_mean(tf.square(y_holder - predict_y))
    tf.summary.scalar('loss', loss)
with tf.name_scope('train'):
    optimizer = tf.train.AdamOptimizer(0.1)
    train = optimizer.minimize(loss)

6.變量初始化

init = tf.global_variables_initializer()
session = tf.Session()
session.run(init)

對(duì)于神經(jīng)網(wǎng)絡(luò)模型,重要是其中的W、b這兩個(gè)參數(shù)。
開(kāi)始神經(jīng)網(wǎng)絡(luò)模型訓(xùn)練之前,這兩個(gè)變量需要初始化。
第1行代碼調(diào)用tf.global_variables_initializer實(shí)例化tensorflow中的Operation對(duì)象。


image.png

第2行代碼調(diào)用tf.Session方法實(shí)例化會(huì)話對(duì)象;
第3行代碼調(diào)用tf.Session對(duì)象的run方法做變量初始化。

7.模型訓(xùn)練

import datetime
import random

nowTime = datetime.datetime.now()
timestamp = nowTime.strftime('%m%d%H%M%S')
write = tf.summary.FileWriter('logs'+timestamp, session.graph)
merge_all = tf.summary.merge_all()

for i in range(201):
    select_index = random.sample(range(len(X_data)), k=batch_size)
    select_X = X_data[select_index]
    select_y = y_data[select_index]
    session.run(train, feed_dict={X_holder:select_X, y_holder:select_y})
    merged = session.run(merge_all, feed_dict={X_holder:select_X, y_holder:select_y})
    write.add_summary(merged, i)

第1行代碼導(dǎo)入datetime庫(kù)獲取當(dāng)前時(shí)間,從而給文件夾命名;
第2行代碼導(dǎo)入random庫(kù),第10行代碼使用random.sample方法選取數(shù)量為batch_size的樣本來(lái)訓(xùn)練;
第4、 5、 6行代碼給新建的日志文件夾命名;
第7行代碼將繪制標(biāo)量曲線圖SCALARS、變量曲線圖DISTRIBUTIONS、變量分布直方圖HISTOGRAMS的任務(wù)合并交給變量merge_all;
在200次訓(xùn)練迭代中,第10、11、12行代碼選取數(shù)量為batch_size的樣本來(lái)訓(xùn)練;
第13行代碼每運(yùn)行1次,即神經(jīng)網(wǎng)絡(luò)訓(xùn)練1次;
第14行代碼獲得每次訓(xùn)練后loss、Weights、biases值;
第15行代碼把loss、Weights、biases值寫入日志文件中。

8.完整代碼和查看結(jié)果

import tensorflow as tf
import numpy as np
import datetime
import random

batch_size = 100
X_data = np.linspace(-1, 1, 300).reshape(-1, 1).astype('float32')
noise = np.random.normal(0, 0.1, X_data.shape).astype('float32')
y_data = np.square(X_data) - 0.5 + noise
with tf.name_scope('inputs'):
    X_holder = tf.placeholder(tf.float32, name='input_X')
    y_holder = tf.placeholder(tf.float32, name='input_y')

def addConnect(inputs, in_size, out_size, n_connect, activation_function=None):
    connect_name = 'connect%s' %n_connect
    with tf.name_scope(connect_name):
        with tf.name_scope('Weights'):
            Weights = tf.Variable(tf.random_normal([in_size, out_size]) ,name='W')
            tf.summary.histogram(connect_name + '/Weights', Weights)
        with tf.name_scope('biases'):
            biases = tf.Variable(tf.zeros([1, out_size]) + 0.1, name='b')
            tf.summary.histogram(connect_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:
            return Wx_plus_b
        else:
            return activation_function(Wx_plus_b)
        
connect_1 = addConnect(X_holder, 1, 10, 1, tf.nn.relu)
predict_y = addConnect(connect_1, 10, 1, 2)
with tf.name_scope('loss'):
    loss = tf.reduce_mean(tf.square(y_holder - predict_y))
    tf.summary.scalar('loss', loss)
with tf.name_scope('train'):
    optimizer = tf.train.AdamOptimizer(0.1)
    train = optimizer.minimize(loss)

init = tf.global_variables_initializer()
session = tf.Session()
session.run(init)

nowTime = datetime.datetime.now()
timestamp = nowTime.strftime('%m%d%H%M%S')
write = tf.summary.FileWriter('logs'+timestamp, session.graph)
merge_all = tf.summary.merge_all()

for i in range(201):
    select_index = random.sample(range(len(X_data)), k=batch_size)
    select_X = X_data[select_index]
    select_y = y_data[select_index]
    session.run(train, feed_dict={X_holder:select_X, y_holder:select_y})
    merged = session.run(merge_all, feed_dict={X_holder:select_X, y_holder:select_y})
    write.add_summary(merged, i)

代碼成功運(yùn)行會(huì)在同級(jí)文件夾中產(chǎn)生日志文件夾,如下圖所示。
根據(jù)代碼運(yùn)行時(shí)間對(duì)文件夾命名,所以讀者的文件夾名與下圖不同。

image.png

點(diǎn)擊進(jìn)入此文件夾,在此文件夾在打開(kāi)cmd,如下圖所示:
image.png

在cmd中輸入命令并運(yùn)行:tensorboard --logdir ./
image.png

開(kāi)啟tensorboard服務(wù)后,可以在瀏覽器訪問(wèn)網(wǎng)址:localhost:6006
瀏覽器中的界面如下圖所示,則說(shuō)明操作都是成功的。

image.png

9.結(jié)合matplotlib可視化、tensorboard日志

visualization2代碼文件下載鏈接: https://pan.baidu.com/s/1KkCMOAVrWOkg1SfDaySFoA 密碼: ud3z
在代碼文件同級(jí)目錄下打開(kāi)cmd,輸入命令并運(yùn)行:python visualization2.py
運(yùn)行結(jié)果部分截圖如下:

image.png

10.結(jié)論

1.這是本文作者寫的第3篇關(guān)于tensorflow的文章,加深了對(duì)tensorflow框架的理解;
2.本文是作者學(xué)習(xí)《周莫煩tensorflow視頻教程》的成果,感激前輩;
3.因?yàn)閠ensorboard版本原因,原視頻的代碼需要修改,自己復(fù)現(xiàn)代碼花費(fèi)了10多個(gè)小時(shí);
4.通過(guò)指定batch_size,加深了對(duì)tf.Session對(duì)象的run方法中的feed_dict參數(shù)的理解。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容