來記錄一下建立第一個基于 TensorFlow 框架的神經(jīng)網(wǎng)絡(luò)的過程,由于是第一次練習(xí),建立的神經(jīng)網(wǎng)絡(luò)比較簡單,輸入層有兩個節(jié)點(diǎn) x1 x2,隱藏層三個節(jié)點(diǎn) a1 a2 a3,輸出層一個節(jié)點(diǎn) y。
建立過程可以分為三個步驟:
- 定義神經(jīng)網(wǎng)絡(luò)的結(jié)構(gòu)和前向傳播的輸出結(jié)果
- 定義損失函數(shù)以及選擇反向傳播優(yōu)化的算法
- 生成會話,并且在訓(xùn)練數(shù)據(jù)上反復(fù)運(yùn)行反向傳播優(yōu)化算法
以下就分這三部分記錄
1. 定義神經(jīng)網(wǎng)絡(luò)的結(jié)構(gòu)和前向傳播算法的輸出結(jié)果
import tensorflow as tf
from numpy.random import RandomState
# 定義訓(xùn)練數(shù)據(jù) batch 的大小
batch_size = 8
# 定義神經(jīng)網(wǎng)絡(luò)的參數(shù)
# random_naomal 為正態(tài)分布,stddev 為標(biāo)準(zhǔn)差,seed 為隨機(jī)種子
w1 = tf.Variable(tf.random_normal([2,3], stddev=1, seed=1))
w2 = tf.Variable(tf.random_normal([3,1], stddev=1, seed=1))
# 定義神經(jīng)網(wǎng)絡(luò)的輸入層的輸出的和輸出層的輸出
x = tf.placeholder(tf.float32, shape=(None, 2), name='x-input')
y_ = tf.placeholder(tf.float32, shape=(None, 1), name='y-input')
# 定義神經(jīng)網(wǎng)絡(luò)前向傳播的過程
# matmul 為矩陣相乘
a = tf.matmul(x, w1)
y = tf.matmul(a, w2)
2. 定義損失函數(shù)以及選擇反向傳播優(yōu)化的算法
# 定義損失函數(shù)和反向傳播的算法
cross_entropy = -tf.reduce_mean(y_ * tf.log(tf.clip_by_value(y, 1e-10, 1.0)))
train_step = tf.train.AdamOptimizer(0.001).minimize(cross_entropy)
# 通過隨機(jī)數(shù)生成一個模擬數(shù)據(jù)集
rdm = RandomState(1) # 小于 1
dataset_size = 128
# 從 128 個隨機(jī)數(shù)抽 2 個
X = rdm.rand(dataset_size, 2)
# 從 X 中 x1+x2 < 1 的隨機(jī)數(shù)中 抽 2 個
Y = [[int(x1+x2 < 1)] for (x1, x2) in X]
3. 生成會話,并且在訓(xùn)練數(shù)據(jù)上反復(fù)運(yùn)行反向傳播優(yōu)化算法
# 創(chuàng)建一個會話來運(yùn)行 TensorFlow 程序
with tf.Session() as sess:
init_op = tf.initialize_all_variables()
# 初始化變量
sess.run(init_op)
# 打印在訓(xùn)練之前神經(jīng)網(wǎng)絡(luò)參數(shù)的值
print sess.run(w1)
print sess.run(w2)
# 設(shè)定訓(xùn)練的輪數(shù)
STEPS = 5000
for i in range(STEPS):
# 每次選取 batch_size 個樣本進(jìn)行訓(xùn)練
start = (i * batch_size) % dataset_size
end = min(start+batch_size, dataset_size)
# 通過選取的樣本訓(xùn)練神經(jīng)網(wǎng)絡(luò)并更新參數(shù)
sess.run(train_step, feed_dict={x: X[start:end], y_ : Y[start:end]})
if i % 1000 == 0:
# 每隔一段時(shí)間計(jì)算在所有數(shù)據(jù)上的交叉熵并輸出
total_cross_entropy = sess.run(cross_entropy, feed_dict={x: X, y_: Y})
# 打印交叉熵
print ("經(jīng)過 %d 次訓(xùn)練后,總交叉熵為 %g" % (i, total_cross_entropy))
# 打印訓(xùn)練結(jié)束后神經(jīng)網(wǎng)絡(luò)參數(shù)的值
print sess.run(w1)
print sess.run(w2)
打印結(jié)果截圖如下:
-
訓(xùn)練之前神經(jīng)網(wǎng)絡(luò)參數(shù)的值
訓(xùn)練之前神經(jīng)網(wǎng)絡(luò)參數(shù)的值 -
交叉熵的變化
交叉熵的變化
可以發(fā)現(xiàn),隨著訓(xùn)練的進(jìn)行,交叉熵在逐漸變小,說明預(yù)測的結(jié)果和真實(shí)的結(jié)果差距越來越小
-
訓(xùn)練之后神經(jīng)網(wǎng)絡(luò)參數(shù)的值
訓(xùn)練之后神經(jīng)網(wǎng)絡(luò)參數(shù)的值
訓(xùn)練后參數(shù)的值可以使神經(jīng)網(wǎng)絡(luò)能更好的擬合提供的訓(xùn)練數(shù)據(jù)
--
第一次寫深度學(xué)習(xí)的代碼,還有很多地方有疑問,以后會把學(xué)習(xí)過程中產(chǎn)生的疑問總結(jié)記錄下來。