1. 程式人生 > 其它 >深度學習--結合程式碼講解如何簡單訓練一個神經網路

深度學習--結合程式碼講解如何簡單訓練一個神經網路

文章目錄

 

前言

或許你差不多理解神經網路,知道神經網路可以理解為一個網,每個網是由多個層堆疊連線起來的。但卻沒有實操訓練過一個自己的網路,下面將結合程式碼講解如何訓練一個簡單的神經網路。

一、神經網路的構造與訓練

神經網路的核心元件是層(layer),它是一種資料處理模組,你可以將它看成資料過濾器。 進去一些資料,出來的資料變得更加有用。具體來說,層從輸入資料中提取表示——我們期望這種表示有助於解決手頭的問題。大多數深度學習都是將簡單的層連結起來,從而實現漸進式的資料蒸餾。深度學習模型就像是資料處理的篩子,包含一系列越來越精細的資料過濾器。

訓練一個神經網路的步驟一般為:構建網路 -> 編譯網路 -> 訓練網路。下面來詳細講解流程,使用python的Keras庫來學習:

1.構建網路

網路的構建就是layers的堆疊,一般呼叫 models.Sequential()函式來建立一個網路,使用add來新增網路層。
如以下例子是個簡單的兩層神經網路,包括2個Dense層,叫做密集連線層或全連線層,是神經網路作為分類器很常用的層。

from keras import models
from keras import layers
network = models.Sequential()
network.add(layers.Dense(512, activation='relu', input_shape=(28 * 28,)))
network.add(layers.Dense(10, activation='softmax'))

可以看到與第一個層即輸入層帶有三個引數,第一個引數就是該層網路的輸出特徵,512表示輸出特徵有512個通道;第二個引數是該層使用的啟用函式,可以理解為輸入經過啟用函式計算後得到輸出特徵;第三個引數是輸入資料的形狀,需要根據你的輸入資料調整。啟用函式的選擇要根據資料的預測型別進行選擇。
第二層是一個 10 通道的輸出層,使用的啟用函式是 ‘softmax’ 它將返回一個由 10 個概率值(總和為 1)組成的陣列。每個概率值表示當前數字影象屬於 10 個數字類別中某一個的概率。

2.編譯網路

構建好網路後就要對網路進行編譯,呼叫compile()函式進行編譯

network.compile(optimizer='rmsprop',
                loss='categorical_crossentropy',
                metrics=['accuracy'])

編譯時需要我們對三個引數進行選擇:
損失函式(loss):網路如何衡量在訓練資料上的效能,即網路如何朝著正確的方向前進。
優化器(optimizer):基於訓練資料和損失函式來更新網路的機制。
在訓練和測試過程中需要監控的指標(metrics):精度或者損失,即正確分類的影象所佔的比例。
模型要解決的問題(分類/迴歸等)不同,損失函式等引數的選擇也不同。

3.訓練網路

網路對輸入資料的形狀一般都會有要求,所以開始訓練網路前需要對輸入資料進行預處理,對標籤也需要進行編碼。做好這些操作就可以把訓練集(特徵+標籤)放入編譯好的網路中進行訓練,一般是呼叫網路的fit方法來進行訓練:

network.fit(train_images, train_labels, epochs=5, batch_size=128)

在fiit函式中放入訓練集特徵與標籤,然後需要設定迭代次數epochs,表示網路迴圈訓練的次數,每訓練一輪網路會根據編譯時設定的損失函式計算網路的損失值(即預測值與真實值之間的距離),損失越小越好;接著網路的優化器會根據上一輪訓練得到的損失值來調整網路,然後接著進行下一輪訓練,直到迭代結束。如上例子該次網路訓練進行了5次迭代,得到的最終結果精度就是本次網路訓練得到的精確度。

二、舉個栗子:

接下來使用 “MNIST” 資料集作為例子來進行研究,該資料集是機器學習領域的一個經典資料集,解決”MNIST ”問題可以看作深度學習的“Hello World”。
要解決的問題是,將手寫數字的灰度影象(28 ×28 )劃分到 10 個類別(0~9)。這個資料集包含 60000 張訓練影象和 10000 張測試影象。
keras庫中有這個資料集,可以直接從庫下載匯入。

#匯入資料集
from keras.datasets import mnist
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
train_images.shape#看下資料的維度
#構建網路
from keras import models
from keras import layers
network = models.Sequential()
network.add(layers.Dense(512, activation='relu', input_shape=(28 * 28,)))
network.add(layers.Dense(10, activation='softmax'))
#編譯網路
network.compile(optimizer='rmsprop',
                loss='categorical_crossentropy',
                metrics=['accuracy'])
#資料放入模型訓練前要對資料進行預處理
train_images = train_images.reshape((60000, 28 * 28))
train_images = train_images.astype('float32') / 255
test_images = test_images.reshape((10000, 28 * 28))
test_images = test_images.astype('float32') / 255 
#對標籤進行編碼
from keras.utils import to_categorical
train_labels = to_categorical(train_labels)
test_labels = to_categorical(test_labels)
#模型訓練
network.fit(train_images, train_labels, epochs=5, batch_size=128)


訓練過程中顯示了兩個數字:一個是網路在訓練資料上的損失(loss),另一個是網路在 訓練資料上的精度(acc)。
可以看出在訓練集上的最終精度為(98.9%),接著將模型用到測試集上看效能

test_loss, test_acc = network.evaluate(test_images, test_labels)
print('test_acc:', test_acc)
test_acc: 0.9785

可以看到測試集精度為 97.8%,比訓練集精度低不少。訓練精度和測試精度之間的這種差距是過擬合造成的。過擬合是神經網路模型普遍存在的顯現,偶爾還會存在欠擬合,神經網路的訓練很重要的就是要解決欠擬合的問題來提高模型範化能力。
一個簡單的模型訓練就完成了,根據啟用函式,損失函式的不同選擇可以解決不同的預測問題,如二分類,多分類,迴歸等。