機器學習筆記(6) - Background Propagation

機器學習筆記(6) - Background Propagation

來自專欄 數據決策

神經網路的輸出層有四個神經元 , 表示這就不是我們前面提到的二分類問題 ( 一個輸出神經元輸出 [ 0 ,1 ] )了 . 而是輸出 [0,0,0,1] 或 [0,0,1,0] 或 [0,1,0,0] 或 [1,0,0,0] 來表示預測了哪個類別 .

假設神經網路的訓練樣本有 m 個,每個包含一組輸入 x 和一組輸出信號 y ,L 表示神經網路層數, S_l 表示第 l 層的 neuron (神經元)個數 (不包括偏置單元 ) . S_L 表示輸出層的神經元個數 .

如果將神經網路分類定義為兩種情況 : 二類分類和多類分類 .

二分類 : S_L = 1 ; y = 0/1 表示類別 .

多(k)分類 , S_L = k , y_i = 1 , 表示預測的類別 , 其他 y_j = 0 .

回顧邏輯回歸問題中我們的代價函數為: J(	heta) = -frac{1}{m}ig[ sum_{j=1}^{n}{y^{(i) } logh_	heta(x^{(i)})+ (1 - y^{(i)})log(1-h_{	heta}(x^{(i)})) } ig] + frac{lambda}{2m} sum_{j=1}^{n}{	heta}_j^2 在邏輯回歸中,我們只有一個輸出變數,又稱標量(scalar),也只有一個因變數 y ,但是在神經網路中,我們可以有很多輸出變數,我們的 是一個維度為 K 的向量,並且我們訓練集中的因變數也是同樣維度的一個向量,因此我們的代價函數會比邏輯回歸更加複雜

J(Theta) = -frac{1}{m}ig[ sum_{j=1}^{n}sum_{k=1}^{k}{y_k^{(i)} logh_Theta(x^{(i)})_k+ (1 - y_k^{(i)})log(1-h_{Theta}(x^{(i)})_k) } ig] + frac{lambda}{2m} sum_{l=1}^{L-1} sum_{i=1}^{s_l} sum_{j=1}^{s_l+1} {({Theta}_{ji}^l)} ^2

我們希望通過代價函數來觀察演算法預測的結果與真實情況的誤差有多大,對於每一行特徵,我們都會給出 K 個預測,基本上我們可以利用循環,對每一行特徵都預測 K 個不同結果,然後再利用循環在 K 個預測中選擇可能性最高的一個,將其與 y 中的實際數據進行比較。

( 兩個 ∑ ( 相當於兩個 for 循環 ) :

i = 1 : k 從 1 到 k

i = 2 : k 從 1 到 k

i = 3 : k 從 1 到 k

i = 4 : k 從 1 到 k )

正則化的那一項只是排除了每一層 θ_0 後,每一層的 θ 矩陣的和。最裡層的循環 j 循環所有的行(由 S_l + 1 層的激活單元數決定),循環 i 則循環所有的列,由該層(S_l 層)的激活單元數所決定。即:h_θ(x) 與真實值之間的距離為 每個樣本 - 每個類輸出的加和 . 對參數進行 regularization 的 bias 項處理所有參數的平分和 .

直觀理解反向傳播 :

(我們沿用上一篇的一個例子 , 對反向傳播進行一個直觀的理解 )

  第一層是輸入層,包含兩個神經元 X1,X2,和偏置項(截距項) b1; 第二層是隱含層,包含兩個神經元 h1,h2 和偏置項b2, 第三層是輸出層 O1 , O2,每條線上標的 wi 是層與層之間連接的權重(參數 θ),激活函數我們默認為 sigmoid 函數。

我們對其傳入參數 (賦初值) :

輸入 X1= 0.05,X2= 0.10; 輸出數據 O1 = 0.01 , O2 = 0.99;

初始權重 w1=0.15 , w2=0.20 , w3=0.25 , w4=0.30;

  w5=0.40 , w6=0.45 , w7=0.50 , w8=0.55

我們的優化目標是 : 給出輸入數據 X1,X2 (0.05和0.10) , 使輸出盡量擬合 Target O1,O2(0.01和0.99 )

一 . 前向傳播

1.1 計算神經元 h1 的輸入加權和 :

1.2 神經元 h1 的輸出 out_h1 :

同理,可計算出神經元 h2 的輸出 out_h2:

2. 從 隱含層 -> 輸出層 :

2.1 計算輸出層神經元 O1 和 O2 的值:

同理,可計算出神經元 h2 的輸出 out_h2:

前向傳播的過程就結束了,我們得到輸出值為 [0.751365 , 0.772928 ],與實際值 [0.01 , 0.99] 相去甚遠 . 之後我們要對誤差進行反向傳播,更新權值,重新計算輸出。

二 . 反向傳播

1. 計算總誤差 (square error)

如果這裡使用平方誤差函數的話 : E = sum frac{1}{2}( target - output )^2 , 我們這裡有兩個輸出 . 分別計算 out1 和 out2 的誤差,總誤差為兩者之和

E_{o1} = frac{1}{2}(target_{o1} - out_{o1}) = frac{1}{2}(0.01 -0.751365 ) ^2= 0.2748

E_{o2} = frac{1}{2}(target_{o2} - out_{o2}) = frac{1}{2}(0.99 - 0.7729)^2 = 0.0235

E_{total} = E_{o1} +E_{o2} = 0.29837

2. 隱含層---->輸出層的權值更新:

以圖中的權重參數 w5 ( θ5) 為例,如果我們想知道 w5 對整體誤差產生了多少影響,可以用整體誤差( E_{total} ) 對 w5(θ5) 求偏導求出:(鏈式法則)

frac {partial E_{total}} {partial w_5} = frac {partial E_{total}} {partial out_{o1}} * frac {partial out_{o1}} {partial net_{o1}} *frac {partial net_{o1}} {partial w_5} --鏈式法則求導

( 可能你已經忘了 net_{o1}out_{o1} 是什麼了... net_{o1} 是權值之和+偏移量(偏置單元的值) , out_{o1} 是激勵函數以 net_{o1} 做自變數的函數輸出 )

3.隱含層---->隱含層的權值更新:

方法與上面的 "隱含層---->輸出層" 差不多,但是有個地方需要變一下,在上文計算總誤差對 w5 的偏導時,是從out(o1) --> net(o1) --> w5 , 但是在隱含層之間的權值更新時,是out(h1) --> net(h1) --> w1 , 這是因為 out(h1) 會接受 E(o1) 和 E(o2) 兩個地方傳來的誤差,所以這個地方兩個要加和計算。

以 w1 為例 (out(h1) 會接受 E(o1) 和 E(o2) 兩個地方傳來的誤差 , 或者說 out(h1) 會向 E(o1) 和 E(o2) 兩個方向傳遞誤差 ): frac {partial E_{total}} {partial w_1} = frac {partial E_{total}} {partial out_{o1}} * frac {partial out_{o1}} {partial net_{o1}} *frac {partial net_{o1}} {partial w_5} \ quadquadquadquadquad frac {partial E_{total}} {partial out_{o1}} = frac {partial E_{o1}} {partial out_{h1}} +frac {partial E_{o2}} {partial out_{h1}}

我們使用這種鏈式法則求導方式不斷的對參數矩陣進行更新 , 不停地迭代,在這個例子中第一次迭代之後,總誤差 E_{total} 由 0.298 下降至 0.291 。迭代10000次後,總誤差為0.000035085,輸出為 [0.015912196,0.984065734] (原為[0.01,0.99]) , 證明效果還是不錯的。

# 反向傳播演算法(Back propagation)

有了對反向傳播的直觀理解 ,我們再來看Andrew Ng 的反向傳播 , 代價函數 :

J(Theta) = -frac{1}{m}ig[ sum_{j=1}^{n}sum_{k=1}^{k}{y_k^{(i)} logh_Theta(x^{(i)})_k+ (1 - y_k^{(i)})log(1-h_{Theta}(x^{(i)})_k) } ig] + frac{lambda}{2m} sum_{l=1}^{L-1} sum_{i=1}^{s_l} sum_{j=1}^{s_l+1} {({Theta}_{ji}^l)} ^2

計算代價函數的偏導數 : frac {partial }{partial	heta_{ij}^{(l)}} J(	heta) , 這裡的 frac {partial }{partial	heta_{ij}^{(l)}} 其實就等價於上面我們提到的 w_k ( 在例子中曾有 k = 1,還曾 =5) 參數 .就是首先計算最後一層的誤差,然後再一層一層反向求出各層的誤差 。由於吳恩達教授視頻上的證明嚴謹而稍顯複雜, 這裡暫且按下不表 .

梯度檢驗 :

當我們對一個較為複雜的模型(例如神經網路)使用梯度下降演算法時,可能會存在一些不容易察覺的錯誤,意味著,雖然代價看上去在不斷減小,但最終的結果可能並不是最優解。為了避免這樣的問題,我們採取一種叫做梯度的數值檢驗(Numerical Gradient Checking)方法。這種方法的思想是通過估計梯度值來檢驗我們計算的導數值是否真的是我們要求的。

對梯度的估計採用的方法是在代價函數上沿著切線的方向選擇離兩個非常近的點 , 然後計算兩個點的 frac {Delta y} {Delta x} , 用以估計梯度。即對於某個特定的 	heta ,我們計算出在 	heta - varepsilon 處和 	heta + varepsilon 的代價值( varepsilon 是一個非常小的值,通常選取 0.0001),然後求兩個代價的平均,用以估計在 	heta 處的代價值。

當 θ 是一個向量時,我們則需要對偏導數進行檢驗。因為代價函數的偏導數檢驗只針對一個參數的改變進行檢驗,下面是一個只針對 θ1 進行檢驗的示例:

frac {partial}{partial 	heta_1} = frac{J(	heta_1+varepsilon_1 ,	heta_2,	heta_3...	heta_n) -J(	heta_1-varepsilon_1 ,	heta_2,	heta_3...	heta_n) }{2varepsilon}

最後我們還需要對通過反向傳播方法計算出的偏導數進行檢驗。根據上面的演算法,計算出的偏導數存儲在矩陣 D_{ij}^{(l)} 中 , 檢驗時 ,我們要將該矩陣展開成為向量,同時我們也將 θ 矩陣展開為向量,我們針對每一個 θ 都計算一個近似的梯度值,將這些值存儲於一個近似梯度矩陣中,最終將得出的這個矩陣同 D_{ij}^{(l)} 進行比較。

隨機初始化 :

任何優化演算法都需要一些初始的參數。到目前為止我們都是初始所有參數為 0,這樣的初始方法對於邏輯回歸來說是可行的,但是對於神經網路來說是不可行的。如果我們令所有的初始參數都為 0,這將意味著我們第二層的所有激活單元都會有相同的值。同理,如果我們初始所有的參數都為一個非 0 的數,結果也是一樣的。

我們通常初始參數為正負 varepsilon 之間的隨機值,假設我們要隨機初始一個尺寸為 10×11 的參數矩陣,代碼如下:

Theta1 = rand(10, 11) * (2*eps) – eps

綜合步驟 ( Putting It Together)

小結一下使用神經網路時的步驟:

網路結構:第一件要做的事是選擇網路結構,即決定選擇多少層以及決定每層分別有多少個單元。如果隱藏層數大於 1,確保每個隱藏層的單元個數相同,通常情況下隱藏層單元的個數越多越好。

我們真正要決定的是隱藏層的層數和每個中間層的單元數。

訓練神經網路:

1. 參數的隨機初始化

2. 利用正向傳播方法計算所有的? ?? (??)

3. 編寫計算代價函數 ?? 的代碼

4. 利用反向傳播方法計算所有偏導數

5. 利用數值檢驗方法檢驗這些偏導數

6. 使用優化演算法來最小化代價函數


聲明

本文章是筆記形式 . 不做任何商業用途 , 主要內容大量取材於

吳恩達機器學習 - 網易雲課堂

fengdu78/Coursera-ML-AndrewNg-Notes

fengdu78 筆記忠於視頻 , 鄙人又進行了證明方面的加工和自己的理解 .

本著分享知識 , 自作筆記的初衷 , 發布到知乎 .

推薦閱讀:

知識布局-tensorflow-梯度下降
一樣的打遊戲,不一樣的酷
Building Deep Neural Network from scratch-吳恩達深度學習第一課第四周習題答案(1)
強化學習(五):Model Free Example
機器學習Kaggle入門學習筆記以及問題匯總

TAG:機器學習 | 神經網路 |