8.3 TensorFlow BP神经网络构建与超参数的选取
前言
之前的8.1 構建回歸模型的重點在于計算圖概念,8.2則介紹一些在整個流程中更靠后的部分:損失函數,優化函數,以及一些其他常用的函數.而本片中的重點在于構建計算圖,與模型的訓練與測試BP
代碼與講解
設置數據
之所以對第一次生成的隨機數據進行存儲主要是為了能夠進行后面的超參數的選取
# 生成與加載數據 # 構造滿足一元二次方程的函數 def Build_Data():Path_x_data = '/home/fonttian/Data/tf_basis/8_2_df_x_data.npy'Path_y_data = '/home/fonttian/Data/tf_basis/8_2_df_y_data.npy'if os.path.exists(Path_x_data) and os.path.exists(Path_y_data):x_data = np.load(Path_x_data)y_data = np.load(Path_y_data)else:x_data = np.linspace(-1, 1, 300)[:, np.newaxis]# 為了使點更密一些,我們構建了300個點,分布在-1到1 的區間,直接曹永np生成等差數列的方式,并將結果為300個點的一維函數,轉換為300 * 1 的二維函數noise = np.random.normal(0, 0.05, x_data.shape)# 加入一些噪聲點,使它與x_data的維度一致,并且擬合為均值為0,方差為0.05的正態分布y_data = np.square(x_data) - 0.5 + noise# y = x^2 - 0.5 + 噪聲if not os.path.exists("/home/fonttian/Data/tf_basis"):os.mkdir("/home/fonttian/Data/tf_basis")# 創建文件夾np.save(Path_x_data,x_data)np.save(Path_y_data,y_data)# 讀取數據return (x_data,y_data)添加神經元
本處添加的神經元隱藏層數為二,隱藏神經元為二十,由我們之前的神經網絡知識所知道,輸入層到隱藏層與隱藏層到輸入層有相當多的代碼一致,所以我們將相同代碼提取出來,設計一個add_layer()函數,根據該代碼,同樣的,當你需要設置隱藏層到隱藏層時
def add_layer(inputs, in_size, out_size, activation_function=None):# 構建權重 : in_size * out)_sieze 大小的矩陣weights = tf.Variable(tf.zeros([in_size, out_size]))# 構建偏置 : 1 * out_size 的矩陣biases = tf.Variable(tf.zeros([1, out_size]) + 0.1)# 矩陣相乘Wx_plus_b = tf.matmul(inputs, weights) + biasesif activation_function is None:outputs = Wx_plus_belse:outputs = activation_function(Wx_plus_b)return outputs # 得到輸出數據hidden_layers = 50 # 構建輸入層到隱藏層,假設隱藏層有 hidden_layers 個神經元 h1 = add_layer(xs, 1, hidden_layers, activation_function=tf.nn.sigmoid) # 構建隱藏層到隱藏層 # h2 = add_layer(h1, hidden_layers, hidden_layers, activation_function=tf.nn.sigmoid) # 構建隱藏層到隱藏層 # h3 = add_layer(h2, hidden_layers, hidden_layers, activation_function=tf.nn.sigmoid) # 構建隱藏層到輸出層 prediction = add_layer(h1, hidden_layers, 1, activation_function=None)然后是構建損失函數與優化函數,并存儲計算圖
# 接下來構建損失函數: 計算輸出層的預測值和真是值間的誤差,對于兩者差的平方求和,再取平均,得到損失函數.運用梯度下降法,以0.1的效率最小化損失 loss = tf.reduce_mean(tf.reduce_sum(tf.square(ys - prediction), reduction_indices=[1])) train_step = tf.train.GradientDescentOptimizer(0.1).minimize(loss) # 優化算法選取SGD,隨機梯度下降print('將計算圖寫入事件文件,在TensorBoard里查看') writer = tf.summary.FileWriter(logdir='logs/8_2_BP', graph=tf.get_default_graph()) writer.close()訓練模型并測試
# 訓練模型 (x_data,y_data) = Build_Data() # 我們讓TensorFlow訓練1000次,每50次輸出訓練的損失值: with tf.Session() as sess:tf.global_variables_initializer().run() # 初始化所有變量for i in range(100000):sess.run(train_step, feed_dict={xs: x_data, ys: y_data})if i % 50 == 0:print('第%d次的損失值為'%i,sess.run(loss, feed_dict={xs: x_data, ys: y_data}))選取超參數
可以參考的文章
關于隨機初始化,建議閱讀這篇文章:http://blog.csdn.net/fontthrone/article/details/77970533
關于激活函數的一些介紹以及TensorFlow中的局部響應歸一化(之前(谷歌的論文)?中提到:一般提升1~2%):http://blog.csdn.net/fontthrone/article/details/77970486,僅以參考這一篇文章.
該例子我做了什么
選擇激活函數與隱藏層數
本例子中我只對隱藏層數與隱藏節點數與激活函數種類進行少量測試,
首先一般而言,BP神經網絡的隱藏層數不能太多,不然一般梯度會消失,而三層的隱藏層理論上足以擬合任何結構,那么首先我們選取最常用的激活函數sigmid函數進行測試.但是結果似乎并沒有說明什么,然后我繼續使用relu函數與tanh函數進行測試,測試次數為10000次,隱藏節點數為20
此時僅僅從最后的結果中我們就可以看出,在本例子(一元二次方程)中,一個隱藏層的BP神經網絡為最佳
而且,通過變化率我們還知道了另外一個極其重要的信息,那就是tanh函數與sigmoid函數其最后都沒用長時間停滯在某個值,無法再繼續優化loss函數.此時待定兩個激活函數:tanh函數與sigmoid函數
但是因為測試次數較少,我們還不能確定其是否真的陷入了局部最優解,所以我又進行了100000(十萬)次的測試,結果顯示,雖然部分超參數時還會有微小的變化,但是loss已經幾乎不變了,這個時候我們可以繼續進行更長時間的測試,但是因為時間關系我直接進行了超參數的下一步的調參優化,選擇合適的隱藏節點數
最終選擇激活函數與隱藏節點數
一般而言隱藏節點數應當在測試樣本的2~10倍,之前我們選取的20似乎有點不合適?那么現在我們還是選取合適的隱藏節點數進行測試吧.
但是因為時間與篇幅關系,我并沒有進行過于詳細的測試,如果在比賽或者工程中還是進行比較詳細的測試比較好
測試結果如下:
而此時,我們可以選取 50 sigmoid為最后的超參數,也可以選擇進行更多次數的測試,然后再選擇最后的超參數,本例子不再做更多演示,請自行測試.
超參數測試總結
code_all
# -*- coding: UTF-8 -*- # 作者:田豐(FontTian) # 創建時間:'2017/8/7' # 郵箱:fonttian@Gmaill.com # CSDN:http://blog.csdn.net/fontthrone # import tensorflow as tf import os import numpy as np import pandas as pd import sysos.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'# 生成與加載數據 # 構造滿足一元二次方程的函數 def Build_Data():Path_x_data = '/home/fonttian/Data/tf_basis/8_2_df_x_data.npy'Path_y_data = '/home/fonttian/Data/tf_basis/8_2_df_y_data.npy'if os.path.exists(Path_x_data) and os.path.exists(Path_y_data):x_data = np.load(Path_x_data)y_data = np.load(Path_y_data)else:x_data = np.linspace(-1, 1, 300)[:, np.newaxis]# 為了使點更密一些,我們構建了300個點,分布在-1到1 的區間,直接曹永np生成等差數列的方式,并將結果為300個點的一維函數,轉換為300 * 1 的二維函數noise = np.random.normal(0, 0.05, x_data.shape)# 加入一些噪聲點,使它與x_data的維度一致,并且擬合為均值為0,方差為0.05的正態分布y_data = np.square(x_data) - 0.5 + noise# y = x^2 - 0.5 + 噪聲if not os.path.exists("/home/fonttian/Data/tf_basis"):os.mkdir("/home/fonttian/Data/tf_basis")# 創建文件夾np.save(Path_x_data,x_data)np.save(Path_y_data,y_data)# 讀取數據return (x_data,y_data)xs = tf.placeholder(tf.float32, [None, 1]) ys = tf.placeholder(tf.float32, [None, 1])# 構建網絡模型def add_layer(inputs, in_size, out_size, activation_function=None):# 構建權重 : in_size * out)_sieze 大小的矩陣weights = tf.Variable(tf.zeros([in_size, out_size]))# 構建偏置 : 1 * out_size 的矩陣biases = tf.Variable(tf.zeros([1, out_size]) + 0.1)# 矩陣相乘Wx_plus_b = tf.matmul(inputs, weights) + biasesif activation_function is None:outputs = Wx_plus_belse:outputs = activation_function(Wx_plus_b)return outputs # 得到輸出數據hidden_layers = 20 # 構建輸入層到隱藏層,假設隱藏層有 hidden_layers 個神經元 h1 = add_layer(xs, 1, hidden_layers, activation_function=tf.nn.sigmoid) # 構建隱藏層到隱藏層 h2 = add_layer(h1, hidden_layers, hidden_layers, activation_function=tf.nn.sigmoid) # 構建隱藏層到隱藏層 h3 = add_layer(h2, hidden_layers, hidden_layers, activation_function=tf.nn.sigmoid) # 構建隱藏層到輸出層 prediction = add_layer(h3, hidden_layers, 1, activation_function=None)# 接下來構建損失函數: 計算輸出層的預測值和真是值間的誤差,對于兩者差的平方求和,再取平均,得到損失函數.運用梯度下降法,以0.1的效率最小化損失 loss = tf.reduce_mean(tf.reduce_sum(tf.square(ys - prediction), reduction_indices=[1])) train_step = tf.train.GradientDescentOptimizer(0.1).minimize(loss) # 優化算法選取SGD,隨機梯度下降print('將計算圖寫入事件文件,在TensorBoard里查看') writer = tf.summary.FileWriter(logdir='logs/8_2_BP', graph=tf.get_default_graph()) writer.close()# 訓練模型 (x_data,y_data) = Build_Data() # 我們讓TensorFlow訓練1000次,每50次輸出訓練的損失值: with tf.Session() as sess:tf.global_variables_initializer().run() # 初始化所有變量for i in range(10000):sess.run(train_step, feed_dict={xs: x_data, ys: y_data})if i % 50 == 0:print('第%d次的損失值為'%i,sess.run(loss, feed_dict={xs: x_data, ys: y_data}))總結
以上是生活随笔為你收集整理的8.3 TensorFlow BP神经网络构建与超参数的选取的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 聊一聊深度学习的weight initi
- 下一篇: 8.2 TensorFlow实现KNN与