深度學習(一)- 全連接神經網絡


1. 神經元模型

在神經網絡中,最基本的單元為神經元。在生物的角度上來看,神經元互相連接,在神經元處於“興奮“狀態時,會向其相連的神經元傳遞化學物質。其中處於”興奮“的條件為:神經元的電位達到某個閾值。

類似的,在神經網絡模型中,一個基本的神經元模型為:

Fig. 1. 周志華. 機器學習. 2016

 

可以看到,一個神經元接受多個輸入,並產生一個輸出。其中 x 為輸入(例如一列 one-hot 編碼后的向量),w為輸入權重(即神經元的參數),y為輸出。

在其他文檔中,我們可能會看到以下神經元結構,例如:

Fig. 2. 鄭澤宇 顧思宇. TensorFlow 實戰Google深度學習框架. 2017


此處與上圖的區別在於:多了一個常量 b(偏置項),並且神經元並沒有閾值。這是由於此處將神經元的閾值固定為 -1,將 b 作為輸入考慮,以簡化問題。(上圖暫未提到激活函數,會在后續提及)在下文中提到的神經元均以 Fig. 2. 為准。

 

2. 前向傳播

 多個神經元之間相互連接,即構成了神經網絡,例如:

 

 

Fig. 3. 鄭澤宇 顧思宇. TensorFlow 實戰Google深度學習框架. 2017

 

常規神經網絡由三部分組成:輸入層,(一個或多個)隱藏層,輸出層。

前向傳播是指:由左到右,依次計算出每層每個節點的值,直至計算出y的值。

以上圖為例(此處先省略偏置項 b),設:

輸入為:X = [x1, x2]

輸入層參數為:

隱藏層參數為:

則隱藏層輸出為:

(若加上偏置項,則為:

輸出層為: A x W(2) = y

(若加上偏置項,則為 A x W(2) + b(2) = y)

 

3. 激活函數

以上例子並未將激活函數考慮入內,可以明顯看出,由 x 計算出 y 的公式為一個線性模型。

若是展開 A x W2 式,則最終結果類似為:

也就是說,最終的結果仍是一個線性函數,並且添加層數並不能解決此問題。線性模型能解決的問題有限,若是一個分類問題,可以由一條線或是一個高位平面划分解決,則可以使用線性模型。而若是此問題並不是一個線性可分問題,則無法直接通過線性模型解決,例如:

 

 

此分類問題的 decision boundary(分類邊界)為一個(類)圓形方程,非線性方程,所以無法解決此類問題。

為了將神經元的輸出做去線性化,便引入了激活函數,常用激活函數有:ReLUsigmoidtanh。具體如下所示:

 

 

Fig. 4. 鄭澤宇 顧思宇. TensorFlow 實戰Google深度學習框架. 2017

 

在加入激活函數后,前向傳播的公式可寫為(f 為激活函數):

隱藏層輸出為:

輸出層為:

 

4. 損失函數

在機器學習中,損失函數用於衡量模型輸出值與目標值之間的損失(差距)。例如:在Fig.3. 的神經網絡中,對於一個訓練樣本,假設模型輸出為 y,訓練樣本的目標值為 y’,則此單個樣本的損失值為 |y’ - y|。對於多個樣本,損失值為:

為了方便求導以及計算,一般使用均方誤差,則此時損失值為:

由於 x 已知,所以其中 y’ 可以表示為自變量為 w(神經網絡參數)的輸出,所以 loss 可以表示為自變量為 w 函數。此時機器學習訓練的目標為:找出使得 loss 值最小的參數 w。此過程即為機器學習的訓練過程。

以上提到的均方誤差損失函數主要用於監督學習中的回歸問題。在機器學習中的監督學習中,主要有兩大類:分類與回歸。上面介紹了回歸問題中的經典損失函數,下面介紹分類問題中經典損失函數。

在分類問題中,以MINST 手寫識別問題為例,目標類別一共有 11 個類別,為 0 – 10。所以在神經網絡的輸出層用,一般會對應有 11個節點,這是 11 個節點組成一個 11 維向量。若是需要識別的目標值為 5,則神經網絡的輸出越接近 [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0],表示預測概率越准。其中,衡量兩個向量相似度的方法為:交叉熵(cross entropy)。

交叉熵衡量的是兩個概率分布之間的距離,作為損失函數廣泛用於多分類問題中。給定兩個概率分布 p q,通過 q 來表示 p 的交叉熵為:

上文提到,交叉熵用於衡量兩個概率分布之間的距離,但是神經網絡的輸出卻不一定是概率分布。所以我們需要將神經網絡的輸出層處理為一個概率分布,這里用到的方法是 Softmax

假設神經網絡的輸出為 y1 , y2 ,, yn,在經過 Softmax 處理后,輸出為一個概率分布:

再次回到交叉熵的公式,此公式並不是一個對稱的(也就是說 H(p,q) 並不等於 H(q,p)),它刻畫的是:用概率分布 q來表示概率分布 p 的難度。我們在計算出預測分布后,需要了解的是如何用預測分布來刻畫實際分布。所以神經網絡的輸出(經過Softmax)被用作q,實際概率分布為p

交叉熵衡量了兩個概率分布之間的距離,所以此值越小,表示預測分布與實際分布越接近。

 

5. 梯度下降

在神經網絡中,最常用的優化方法為反向傳播算法。神經網絡的訓練過程是:求解參數 w 的值,使得損失函數的損失值盡可能的小(一般很難求解最小)。所以神經網絡訓練優化的是參數 w 的值

反向傳播算法基於的是梯度下降法,梯度下降法的過程簡單的說,就是:不斷迭代更新參數,使得損失值不斷向最小值方向移動。此處的梯度表示的是函數的梯度(斜率、一階導數),給定一個參數值,使得此參數值不斷沿着梯度(斜率)的反方向移動,以使參數值不斷趨近於最小值。

 

下面以二元二次方程為例:令 y = f(x) = x2,使用梯度下降的方式求解 x,使得y不斷趨近於最小值。

1.       1. f(x) = x2 ,我們可以求得 f(x) 的一階導數為: f(x)’ = 2x

2.       2. 對 x 的初始值取隨機值(如正整數2),則在 x=2 時,它的梯度為 4,梯度的反方向為 -4

3.       3. 指定在移動的過程中步長參數為 0.1(也就是梯度下降的學習速率),則第一次移動的值為 -0.4,移動后的 x 值為 1.6y值為 2.56

4.       4. 不斷重復步驟3,直到移動到足夠小的值,或是達到指定訓練輪數

 

此過程圖示如下:

 

Fig. 5. Andrew Ng. Machine Learning (Couresra)

 

一般在機器學習的訓練中,會有多個參數值,如 w1, w2, w3 … wn。此時在使用梯度下降優化時,首先隨機為它們產生初始值,然后在一輪學習中,更新每個參數值。如更新 w1 時,先固定除它之外的所有參數,然后更新 w1。繼而在更新 w2 時,仍使用w1 更新前的值,並固定其他參數,然后更新w2 。更新完所有 w 后,為一輪學習(更新)結束,繼而進入下一輪學習(更新)。

在機器學習中,一般使用梯度下降算法對損失函數進行優化,求解損失函數的參數 w,使得損失值最小。由損失函數的公式(這里以均方誤差損失函數為例)可知,在計算時需要將訓練集中所有樣本考慮在內。這樣就會導致大量計算,每一輪迭代中都要計算整個樣本量的損失值,使得計算時間大大增加。所以之后又提出了隨機梯度下降方法。

隨機梯度下降是指:不使用全部的訓練集,而只是使用一條訓練數據,對參數進行更新。但是此方法的問題是,一條訓練數據不足以代表整個數據集。所以最終的方法使用的是:使用一個batch(如50條,100條等)的訓練數據對參數進行更新。這樣兼顧了訓練速度以及准確性。

 

6. 反向傳播

反向傳播是神經網絡中最常用的優化算法,其原理基於梯度下降,用於優化神經網絡中參數。簡單的說,就是由輸出層開始,使用梯度下降的方式,逐步向前更新每層參數。此方向與前向傳播方向相反,所以稱為反向傳播。這里我們以一個最簡單的神經網絡來說明反向傳播的過程:

 

 

 

此處 x 為單節點輸入層,a 為單節點隱藏層,y 為單節點輸出層,則:

以均方誤差為損失函數,則有:

以上函數中,給定 x,以及初始化隨機值 w、u,可求得 a 與 y,並應用梯度下降法更新參數 u 的值。將以上損失函數繼續展開得:

可以進一步得到有關自變量 w 的損失函數,然后再使用梯度下降對參數 w 進行更新。若是有多層,則逐層往以此方式更新參數。 

以上是一個簡單的反向傳播思想,在實際應用中,除了有多層,多節點外,還涉及激活函數。更詳細的反向傳播推理、求導過程(鏈式求導),請參考《機器學習》(周志華,2016)神經網絡章節。

 

7. 全連接神經網絡實現

在有了以上知識基礎后,下面我們用Keras 搭建一個神經網絡,應用於 MINST(手寫數字數據集)。Keras python 的一個庫,提供了用於搭建神經網絡模型的高層 API。在Keras 之下,用於訓練的框架可以基於 TensorFlowCNTK Theano。下面我們使用 Keras 搭建一個全連接神經網絡。

首先獲取MINST數據集:

訓練圖片集中,每一條為 28 × 28 的矩陣,取值范圍為 0-255,一共60000 條數據。這里我們需要將 28 × 28 矩陣轉換為一維向量,以輸入模型神經元:

這里除以 255 是為了將數據做歸一化,將數據范圍調整到(0, 1)范圍內,以防止數值之間差值太大,影響訓練結果。

再看一下訓練圖片集中的標注信息:

 

接下來搭建模型:

這里我們使用了全連接神經網絡(即 Dense()),其中輸入層為 28 × 28個神經元(對應訓練數據每條向量維度),隱藏層為 512 個神經元,輸出層為 10 個神經元(對應每條輸出的向量維度)。

所以輸入層與隱藏層之間的參數個數為:28×28 ×512 + 512(這里+512 表示的是偏置項)=  401920。這里隱藏層的激活函數為上文提到的 sigmoid,輸出層的激活函數為上文提到的 softmax

優化方法為 rmspropoptimizer=’rmsprop’,也是一種基於梯度的優化方法,類似隨機梯度下降),損失函數為 categorical_crossentropy(上文提到對於多分類任務使用的損失函數),metricsaccuracy(即以准確度衡量模型訓練結果)。

搭建完模型后,開始對模型進行訓練:

這里epochs 表示訓練 20 個輪次,batch_size 表示每次以 128 條為一個 batch(前文在隨機梯度下降有提到),validation_split 表示使用訓練集的多少比率數據用作驗證集。

訓練結束后,我們在測試集上進行擬合:

可以看到在測試集上的loss 0.123,准確度為 96.55%

history.history 里會記錄每輪訓練后的損失值以及正確率,使用 matplotlib 畫出訓練集與驗證集上每輪的損失值與正確率:

從上圖可以看出,訓練集在開始訓練后的很早幾輪后即開始出現了過擬合的現象,導致模型泛化性能相對不足。對此,可以嘗試增加L1L2 正則懲罰項、使用dropout、減少網絡大小(即可訓練的參數個數)、獲取更多訓練數據等,以降低過擬合(這里其實前幾輪訓練后即開始出現過擬合,所以可以在4輪左右即可停止訓練)。具體有關過擬合與欠擬合之后再詳述。

 

References

1. 鄭澤宇 顧思宇. TensorFlow 實戰Google深度學習框架. 2017

2. 周志華. 機器學習. 2016

3. Python 深度學習. 弗朗索瓦 肖萊. 張亮譯. 2018



 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM