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,如下圖所示:

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

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

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

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

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

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

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

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

點(diǎn)擊下圖紅色箭頭標(biāo)注處修改代碼文件名為
tensorboardTest1。
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é)果如下圖所示:

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)。如下圖所示:

第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ì)象。

第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ì)文件夾命名,所以讀者的文件夾名與下圖不同。

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

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

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

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ù)的理解。