神經網絡模型的訓練過程其實質上就是神經網絡參數的設置過程
在神經網絡優化算法中最常用的方法是反向傳播算法,下圖是反向傳播算法流程圖:
從上圖可知,反向傳播算法實現了一個迭代的過程,在每次迭代的開始,先需要選取一小部分訓練數據,這一小部分數據叫做一個batch。然后這一個batch會通過前向傳播算法得到神經網絡的預測結果。計算出當前神經網絡的預測答案與正確答案之間的差距(有監督學習,在訓練時有一個標注好的數據集),最后根據預測值和真實值之間的差距,反向傳播算法會相應的更新神經網絡參數的取值,使在這個batch上神經網絡模型的預測結果更接近真實答案。
通過TensorFlow實現反向傳播算法的第一步是使用TensorFlow表達一個batch數據,但如果每輪迭代中選取的數據都通過常量來表示,會導致TensorFlow的計算圖非常大。因為每生成一個常量,TensorFlow都會在計算圖中增加一個節點。一般來書一個神經網絡的訓練過程會經過幾百萬輪甚至上億輪的迭代,這樣就導致計算圖非常大,而且利用率低。為了避免這個問題,TensorFlow提供placeholder機制用於提供輸入數據。placeholder相當於定義了一個位置,這個位置中的數據在程序運行時再指定,這樣在程序中就不需要生成大量常量來提供輸入數據,而只需要將數據通過placeholder傳入TensorFlow計算圖。在placeholder定義時,需要指定數據類型。下面程序是通過placeholder實現前向傳播算法。
import tensorflow as tf w1 = tf.Variable(tf.random_normal([2, 3], stddev=1, seed=1)) w2 = tf.Variable(tf.random_normal([3, 1], stddev=1, seed=1)) # 定義placeholder作為存放數據的地方。這里的維度不一定要定義, # 但如果維度是確定的,給出維度會降低出錯的概率 x = tf.placeholder(tf.float32, shape=(1, 2), name="input") # 通過前項傳播算法得到神經網絡的輸出 a = tf.matmul(x, w1) y = tf.matmul(a, w2) # 定義會話 sess = tf.Session() # 定義初始化變量 init_op = tf.global_variables_initializer() sess.run(init_op) sess.run(w2.initializer) # feed_dict是一個字典,在這個字典中需要給出每個使用placeholder定義變量的取值 print(sess.run(y, feed_dict={x: [[0.7, 0.9]]})) sess.close()
在上面的程序中輸入的是1x2矩陣(shape=(1, 2)),若改為n x 2的矩陣,就可以得到n個前向傳播結果
在得到一個batch的前向傳播結果后需要定義一個損失函數來刻畫當前的預測值和真實答案之間的差距。然后通過反向傳播算法來縮小預測值和真實值之間的差距。下面代碼定義了一個損失函數,及反向傳播算法
# 使用sigmoid函數將y轉化為0-1之間的數值,轉化后y代表預測正樣本的概率, # 1-y代表預測負樣本的概率 y = tf.sigmoid(y) # 定義損失函數,刻畫預測值與真實值之間的差距 cross_entropy = -tf.reduce_mean(y_ * tf.log(tf.clip_by_value(y, le-10, 1.0)) + (1 - y_) * tf.log(tf.clip_by_value(1-y, le-10, 1.0))) # 定義學習率 LR = 0.001 # 定義反向傳播算法優化神經網絡參數 train_step = tf.train.AdamOptimizer(LR).minimize(cross_entropy)