入門 | Tensorflow實戰講解神經網路搭建詳細過程
作者 | AI小昕
編輯 | 磐石
出品 | 磐創AI技術團隊
【磐創AI導讀】:本文詳細介紹了神經網路在實戰過程中的構建與調節方式。
之前我們講了神經網路的起源、單層神經網路、多層神經網路的搭建過程、搭建時要注意到的具體問題、以及解決這些問題的具體方法。本文將透過一個經典的案例:MNIST手寫數字識別,以程式碼的形式來為大家梳理一遍神經網路的整個過程。
一 、MNIST手寫數字資料集介紹
MNIST手寫數字資料集來源於是美國國家標準與技術研究所,是著名的公開資料集之一,通常這個資料集都會被作為深度學習的入門案例。資料集中的數字圖片是由250個不同職業的人純手寫繪製,資料集獲取的網址為:http://yann.lecun.com/exdb/mnist/。(下載後需解壓)
具體來看,MNIST手寫數字資料集包含有60000張圖片作為訓練集資料,10000張圖片作為測試集資料,且每一個訓練元素都是28*28畫素的手寫數字圖片,每一張圖片代表的是從0到9中的每個數字。該資料集樣例如下圖所示:
如果我們把每一張圖片中的畫素轉換為向量,則得到長度為28*28=784的向量。因此我們可以把MNIST資料訓練集看作是一個[60000,784]的張量,第一個維度表示圖片的索引,第二個維度表示每張圖片中的畫素點。而圖片裡的每個畫素點的值介於0-1之間。如下圖所示:
此外,MNIST資料集的類標是介於0-9的數字,共10個類別。通常我們要用獨熱編碼(One_Hot Encoding)的形式表示這些類標。所謂的獨熱編碼,直觀的講就是用N個維度來對N個類別進行編碼,並且對於每個類別,只有一個維度有效,記作數字1 ;其它維度均記作數字0。例如類標1表示為:([0,1,0,0,0,0,0,0,0,0]);同理標籤2表示為:([0,0,1,0,0,0,0,0,0,0])。最後我們透過softmax函式輸出的是每張圖片屬於10個類別的機率。
二 、網路結構的設計
接下來透過Tensorflow程式碼,實現MINIST手寫數字識別的過程。首先,如程式1所示,我們匯入程式所需要的庫函式、資料集:
程式1:
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
接下來,我們讀取MNIST資料集,並指定用one_hot的編碼方式;然後定義batch_size、batch_num兩個變數,分別代表一次性傳入神經網路進行訓練的批次大小,以及計算出訓練的次數。如程式2所示:
程式2:
mnist_data=input_data.read_data_sets("MNIST.data",one_hot=True)
batch_size=100
batch_num=mnist_data.train.num_examples//batch_size
我們需要注意的是:在執行第一句命令時,就會從預設的地方下載MNIST資料集,下載下來的資料集會以壓縮包的形式存到指定目錄,如下圖所示。這些資料分別代表了訓練集、訓練集標籤、測試集、測試集標籤。
接著我們定義兩個placeholder,程式如下所示:
程式3:
x = tf.placeholder(tf.float32,[None,784])
y = tf.placeholder(tf.float32,[None,10])
其中,x代表訓練資料,y代表標籤。具體來看,我們會把訓練集中的圖片以batch_size批次大小,分批傳入到第一個引數中(預設為None);X的第二個引數代表把圖片轉換為長度為784的向量;Y的第二個參數列示10個不同的類標。
接下來我們就可以開始構建一個簡單的神經網路了,首先定義各層的權重w和偏執b。如程式4所示:
程式4:
weights = {
'hidden_1': tf.Variable(tf.random_normal([784, 256])),
'out': tf.Variable(tf.random_normal([256, 10]))
}
biases = {
'b1': tf.Variable(tf.random_normal([256])),
'out': tf.Variable(tf.random_normal([10]))
}
因為我們準備搭建一個含有一個隱藏層結構的神經網路(當然也可以搭建兩個或是多個隱層的神經網路),所以先要設定其每層的w和b。如上程式所示,該隱藏層含有256個神經元。接著我們就可以開始搭建每一層神經網路了:
程式5:
def neural_network(x):
hidden_layer_1 = tf.add(tf.matmul(x, weights['hidden_1']), biases['b1'])
out_layer = tf.matmul(hidden_layer_1, weights['out']) + biases['out']
return out_layer
如程式5所示,我們定義了一個含有一個隱藏層神經網路的函式neural_network,函式的返回值是輸出層的輸出結果。
接下來我們定義損失函式、最佳化器以及計算準確率的方法。
程式6:
#呼叫神經網路
result = neural_network(x)
#預測類別
prediction = tf.nn.softmax(result)
#平方差損失函式
loss = tf.reduce_mean(tf.square(y-prediction))
#梯度下降法
train_step = tf.train.GradientDescentOptimizer(0.2).minimize(loss)
#預測類標
correct_pred = tf.equal(tf.argmax(y,1),tf.argmax(prediction,1))
#計算準確率
accuracy = tf.reduce_mean(tf.cast(correct_pred,tf.float32))
#初始化變數
init = tf.global_variables_initializer()
如程式6所示:首先使用softmax函式對結果進行預測,然後選擇平方差損失函式計算出loss,再使用梯度下降法的最佳化方法對loss進行最小化(梯度下降法的學習率設定為0.2)。接著使用argmax函式返回最大的值所在的位置,再使用equal函式與正確的類標進行比較,返回一個bool值,代表預測正確或錯誤的類標;最後使用cast函式把bool型別的預測結果轉換為float型別(True轉換為1,False轉換為0),並對所有預測結果統計求平均值,算出最後的準確率。要注意:最後一定不要忘了對程式中的所有變數進行初始化。
最後一步,我們啟動Tensorflow預設會話,執行上述過程。程式碼如下所示:
程式7:
step_num=400
with tf.Session() as sess:
sess.run(init)
for step in range(step_num+1):
for batch in range(batch_num):
batch_x,batch_y = mnist_data.train.next_batch(batch_size)
sess.run(train_step,feed_dict={x:batch_x,y:batch_y})
acc = sess.run(accuracy,feed_dict={x:mnist_data.test.images,y:mnist_data.test.labels})
print("Step " + str(step) + ",Training Accuracy "+ "{:.3f}" + str(acc))
print("Finished!")
上述程式定義了MNIST資料集的執行階段,首先我們定義迭代的週期數,往往開始的時候準確率會隨著迭代次數快速提高,但漸漸地隨著迭代次數的增加,準確率提升的幅度會越來越小。而對於每一輪的迭代過程,我們用不同批次的圖片進行訓練,每次訓練100張圖片,每次訓練的圖片資料和對應的標籤分別儲存在 batch_x、batch_y中,接著再用run方法執行這個迭代過程,並使用feed_dict的字典結構填充每次的訓練資料。迴圈往復上述過程,直到最後一輪的訓練結束。
最後我們利用測試集的資料檢驗訓練的準確率,feed_dict填充的資料分別是測試集的圖片資料和測試集圖片對應的標籤。輸出結果迭代次數和準確率,完成訓練過程。我們擷取400次的訓練結果,如下圖所示:
以上我們便完成了MNIST手寫數字識別模型的訓練,接下來可以從以下幾方面對模型進行改良和最佳化,以提高模型的準確率。
首先,在計算損失函式時,可以選擇交叉熵損失函式來代替平方差損失函式,通常在Tensorflow深度學習中,softmax_cross_entropy_with_logits函式會和softmax函式搭配使用,是因為交叉熵在面對多分類問題時,迭代過程中權值和偏置值的調整更加合理,模型收斂的速度更加快,訓練的的效果也更加好。程式碼如下所示:
程式8:
#預測類別
prediction = tf.nn.softmax(result)
#交叉熵損失函式
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y,logits=prediction))
#梯度下降法
train_step = tf.train.GradientDescentOptimizer(0.2).minimize(loss)
#預測類標
correct_pred = tf.equal(tf.argmax(y,1),tf.argmax(prediction,1))
#計算準確率
accuracy = tf.reduce_mean(tf.cast(correct_pred,tf.float32))
如程式8所示:我們把兩個引數:類標y以及模型的預測值prediction,傳入到交叉熵損失函式softmax_cross_entropy_with_logits中,然後對函式的輸出結果求平均值,再使用梯度下降法進行最佳化。最終的準確率如下圖所示:
我們可以明顯看到,使用交叉熵損失函式對於模型準確率的提高還是顯而易見的,訓練過程迭代200次的準確率已經超過了平方差損失函式迭代400次的準確率。
除了改變損失函式,我們還可以改變最佳化演算法。例如使用adam最佳化演算法代替隨機梯度下降法,因為它的收斂速度要比隨機梯度下降更快,這樣也能夠使準確率有所提高。如下程式所示,我們使用學習率為0.001的AdamOptimizer作為最佳化演算法(其它部分不變):
程式9:
#Adam最佳化演算法
train_step = tf.train.AdamOptimizer(1e-2).minimize(loss)
此外,如果你瞭解了過擬合的概念,那麼很容易可以聯想到測試集準確率不高的原因,可能是因為訓練過程中發生了“過擬合”的現象。所以我們可以從防止過擬合的角度出發,提高模型的準確率。我們可以採用增加資料量或是增加正則化項的方式,來緩解過擬合。這裡,我們為大家介紹dropout的方式是如何緩解過擬合的。
Dropout是在每次神經網路的訓練過程中,使得部分神經元工作而另外一部分神經元不工作。而測試的時候啟用所有神經元,用所有的神經元進行測試。這樣便可以有效的緩解過擬合,提高模型的準確率。具體程式碼如下所示:
程式10:
def neural_network(x):
hidden_layer_1 = tf.add(tf.matmul(x, weights['hidden_1']), biases['b1'])
L1 = tf.nn.tanh(hidden_layer_1)
dropout1 = tf.nn.dropout(L1,0.5)
out_layer = tf.matmul(dropout1, weights['out']) + biases['out']
return out_layer
如程式10所示,我們在隱藏層後接了dropout,隨機關掉50%的神經元,最後的測試結果如下圖所示,我們發現準確率取得了顯著的提高,在神經網路結構中沒有新增摺積層和池化層的情況下,準確率達到了92%以上。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31555081/viewspace-2648387/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- TensorFlow搭建神經網路最佳實踐樣例神經網路
- TensorFlow實戰卷積神經網路之LeNet卷積神經網路
- 超詳細講解頁面載入過程
- 通俗易懂:圖卷積神經網路入門詳解卷積神經網路
- TensorFlow筆記-04-神經網路的實現過程,前向傳播筆記神經網路
- 使用NumPy演示實現神經網路過程神經網路
- 使用PyTorch演示實現神經網路過程PyTorch神經網路
- 圖神經網路入門神經網路
- Andrew BP 神經網路詳細推導神經網路
- 如何入門Pytorch之四:搭建神經網路訓練MNISTPyTorch神經網路
- 神經網路入門篇:詳解隨機初始化(Random+Initialization)神經網路隨機random
- 深度學習筆記8:利用Tensorflow搭建神經網路深度學習筆記神經網路
- 神經網路入門篇之深層神經網路:詳解前向傳播和反向傳播(Forward and backward propagation)神經網路反向傳播Forward
- 網路安全Bypass網路卡詳細講解
- 【神經網路篇】--RNN遞迴神經網路初始與詳解神經網路RNN遞迴
- 誰可以詳細講講機器學習,深度學習,神經網路,卷積神經網路的區別以及應用場景機器學習深度學習神經網路卷積
- TensorFlow上實現卷積神經網路CNN卷積神經網路CNN
- 【深度學習】神經網路入門深度學習神經網路
- [Python人工智慧] 一.神經網路入門及theano基礎程式碼講解Python人工智慧神經網路
- TensorFlow神經網路優化策略神經網路優化
- MySQL MHA詳細搭建過程MySql
- 堆排序的Python實現(附詳細過程圖和講解)排序Python
- 神經網路入門篇:詳解多樣本向量化(Vectorizing across multiple examples)神經網路ROS
- 【Tensorflow_DL_Note6】Tensorflow實現卷積神經網路(1)卷積神經網路
- 【Tensorflow_DL_Note7】Tensorflow實現卷積神經網路(2)卷積神經網路
- 卷積神經網路(CNN)詳解卷積神經網路CNN
- Tensorflow實現神經網路的前向傳播神經網路
- webpack4.x最詳細入門講解Web
- Tensorflow-卷積神經網路CNN卷積神經網路CNN
- Tensorflow系列專題(四):神經網路篇之前饋神經網路綜述神經網路
- 用TensorFlow搭建卷積神經網路識別數字0~9卷積神經網路
- 使用全卷積神經網路FCN,進行影像語義分割詳解(附帶Tensorflow詳解程式碼實現)卷積神經網路
- 4.3CNN卷積神經網路最詳細最容易理解--tensorflow原始碼MLP對比CNN卷積神經網路原始碼
- Canal詳細入門實戰(使用總結)
- 神經網路:numpy實現神經網路框架神經網路框架
- PyTorch入門-殘差卷積神經網路PyTorch卷積神經網路
- 神經網路的菜鳥入門祕籍神經網路
- Hexo的詳細搭建過程——小白的血淚經歷QAQHexo