深度神經網絡(DNN)反向傳播算法(BP)

    在深度神經網絡(DNN)模型與前向傳播算法中,咱們對DNN的模型和前向傳播算法作了總結,這裏咱們更進一步,對DNN的反向傳播算法(Back Propagation,BP)作一個總結。html

1. DNN反向傳播算法要解決的問題

    在瞭解DNN的反向傳播算法前,咱們先要知道DNN反向傳播算法要解決的問題,也就是說,何時咱們須要這個反向傳播算法? 算法

    回到咱們監督學習的通常問題,假設咱們有m個訓練樣本:$\{(x_1,y_1), (x_2,y_2), ..., (x_m,y_m)\}$,其中$x$爲輸入向量,特徵維度爲$n\_in$,而$y$爲輸出向量,特徵維度爲$n\_out$。咱們須要利用這m個樣本訓練出一個模型,當有一個新的測試樣本$(x_{test},?)$來到時, 咱們能夠預測$y_{test}$向量的輸出。 網絡

    若是咱們採用DNN的模型,即咱們使輸入層有$n\_in$個神經元,而輸出層有$n\_out$個神經元。再加上一些含有若干神經元的隱藏層。此時咱們須要找到合適的全部隱藏層和輸出層對應的線性係數矩陣$W$,偏倚向量$b$,讓全部的訓練樣本輸入計算出的輸出儘量的等於或很接近樣本輸出。怎麼找到合適的參數呢?機器學習

    若是你們對傳統的機器學習的算法優化過程熟悉的話,這裏就很容易聯想到咱們能夠用一個合適的損失函數來度量訓練樣本的輸出損失,接着對這個損失函數進行優化求最小化的極值,對應的一系列線性係數矩陣$W$,偏倚向量$b$即爲咱們的最終結果。在DNN中,損失函數優化極值求解的過程最多見的通常是經過梯度降低法來一步步迭代完成的,固然也能夠是其餘的迭代方法好比牛頓法與擬牛頓法。若是你們對梯度降低法不熟悉,建議先閱讀我以前寫的梯度降低(Gradient Descent)小結函數

    對DNN的損失函數用梯度降低法進行迭代優化求極小值的過程即爲咱們的反向傳播算法。post

    本篇使用了矩陣向量求導,若是你對這一塊不熟悉,請先閱讀下我寫的矩陣向量求導系列文章學習

2. DNN反向傳播算法的基本思路

    在進行DNN反向傳播算法前,咱們須要選擇一個損失函數,來度量訓練樣本計算出的輸出和真實的訓練樣本輸出之間的損失。你也許會問:訓練樣本計算出的輸出是怎麼得來的?這 個輸出是隨機選擇一系列$W,b$,用咱們上一節的前向傳播算法計算出來的。即經過一系列的計算:$a^l = \sigma(z^l) = \sigma(W^la^{l-1} + b^l)$。計算到輸出層第$L$層對應的$a^L$即爲前向傳播算法計算出來的輸出。測試

    回到損失函數,DNN可選擇的損失函數有很多,爲了專一算法,這裏咱們使用最多見的均方差來度量損失。即對於每一個樣本,咱們指望最小化下式:$$J(W,b,x,y) = \frac{1}{2}||a^L-y||_2^2$$優化

    其中,$a^L$和$y$爲特徵維度爲$n\_out$的向量,而$||S||_2$爲S的L2範數。htm

    損失函數有了,如今咱們開始用梯度降低法迭代求解每一層的$W,b$。

    首先是輸出層第$L$層。注意到輸出層的$W,b$知足下式:$$a^L = \sigma(z^L) = \sigma(W^La^{L-1} + b^L)$$

    這樣對於輸出層的參數,咱們的損失函數變爲:$$J(W,b,x,y) = \frac{1}{2}||a^L-y||_2^2 =  \frac{1}{2}|| \sigma(W^La^{L-1} + b^L)-y||_2^2$$

    這樣求解$W,b$的梯度就簡單了:$$\frac{\partial J(W,b,x,y)}{\partial W^L} = [(a^L-y) \odot \sigma^{'}(z^L)](a^{L-1})^T$$$$\frac{\partial J(W,b,x,y)}{\partial b^L} =(a^L-y)\odot \sigma^{'}(z^L)$$

    注意上式中有一個符號$\odot$,它表明Hadamard積,對於兩個維度相同的向量$A(a_1,a_2,...a_n)^T$和$B(b_1,b_2,...b_n)^T$,則$A \odot B = (a_1b_1, a_2b_2,...a_nb_n)^T$。

    咱們注意到在求解輸出層的$W,b$的時候,有中間依賴部分$\frac{\partial J(W,b,x,y)}{\partial z^L}$,所以咱們能夠把公共的部分即對$z^L$先算出來,記爲:$$\delta^L = \frac{\partial J(W,b,x,y)}{\partial z^L} = (a^L-y)\odot \sigma^{'}(z^L)$$

    如今咱們終於把輸出層的梯度算出來了,那麼如何計算上一層$L-1$層的梯度,上上層$L-2$層的梯度呢?這裏咱們須要一步步的遞推,注意到對於第$l$層的未激活輸出$z^l$,它的梯度能夠表示爲:$$\delta^l =\frac{\partial J(W,b,x,y)}{\partial z^l} = (\frac{\partial z^L}{\partial z^{L-1}}\frac{\partial z^{L-1}}{\partial z^{L-2}}...\frac{\partial z^{l+1}}{\partial z^{l}})^T\frac{\partial J(W,b,x,y)}{\partial z^L}$$

    若是咱們能夠依次計算出第$l$層的$\delta^l$,則該層的$W^l,b^l$很容易計算?爲何呢?注意到根據前向傳播算法,咱們有:$$z^l= W^la^{l-1} + b^l$$

    因此根據上式咱們能夠很方便的計算出第l層的$W^l,b^l$的梯度以下:$$\frac{\partial J(W,b,x,y)}{\partial W^l} = \delta^{l}(a^{l-1})^T$$$$\frac{\partial J(W,b,x,y)}{\partial b^l} = \delta^{l}$$

    其中,第一個式子的推導能夠參考機器學習中的矩陣向量求導(四) 矩陣向量求導鏈式法則中第三節的最後一個公式。

    那麼如今問題的關鍵就是要求出$ \delta^{l}$了。這裏咱們用數學概括法,第$L$層的$\delta^{L}$上面咱們已經求出, 假設第$l+1$層的$\delta^{l+1}$已經求出來了,那麼咱們如何求出第$l$層的$\delta^{l}$呢?咱們注意到:$$\delta^{l} = \frac{\partial J(W,b,x,y)}{\partial z^l} = (\frac{\partial z^{l+1}}{\partial z^{l}})^T\frac{\partial J(W,b,x,y)}{\partial z^{l+1}} =(\frac{\partial z^{l+1}}{\partial z^{l}})^T \delta^{l+1}$$

    可見,用概括法遞推$\delta^{l+1}$和$\delta^{l}$的關鍵在於求解$\frac{\partial z^{l+1}}{\partial z^{l}}$。

    而$z^{l+1}$和$z^{l}$的關係其實很容易找出:$$z^{l+1}= W^{l+1}a^{l} + b^{l+1} = W^{l+1}\sigma(z^l) + b^{l+1} $$

    這樣很容易求出:$$\frac{\partial z^{l+1}}{\partial z^{l}} = W^{l+1}diag(\sigma^{'}(z^l))$$

    將上式帶入上面$\delta^{l+1}$和$\delta^{l}$關係式咱們獲得:$$\delta^{l} = (\frac{\partial z^{l+1}}{\partial z^{l}})^T\frac{\partial J(W,b,x,y)}{\partial z^{l+1}} = diag(\sigma^{'}(z^l))(W^{l+1})^T\delta^{l+1} =(W^{l+1})^T\delta^{l+1}\odot \sigma^{'}(z^l)$$

    如今咱們獲得了$\delta^{l}$的遞推關係式,只要求出了某一層的$\delta^{l}$,求解$W^l,b^l$的對應梯度就很簡單的。

3. DNN反向傳播算法過程

    如今咱們總結下DNN反向傳播算法的過程。因爲梯度降低法有批量(Batch),小批量(mini-Batch),隨機三個變種,爲了簡化描述,這裏咱們以最基本的批量梯度降低法爲例來描述反向傳播算法。實際上在業界使用最多的是mini-Batch的梯度降低法。不過區別僅僅在於迭代時訓練樣本的選擇而已。

    輸入: 總層數L,以及各隱藏層與輸出層的神經元個數,激活函數,損失函數,迭代步長$\alpha$,最大迭代次數MAX與中止迭代閾值$\epsilon$,輸入的m個訓練樣本$\{(x_1,y_1), (x_2,y_2), ..., (x_m,y_m)\}$

    輸出:各隱藏層與輸出層的線性關係係數矩陣$W$和偏倚向量$b$

    1) 初始化各隱藏層與輸出層的線性關係係數矩陣$W$和偏倚向量$b$的值爲一個隨機值。

      2)for iter to 1 to MAX:

    2-1) for i =1 to m:

      a) 將DNN輸入$a^1$設置爲$x_i$

      b) for $l$=2 to L,進行前向傳播算法計算$a^{i,l} = \sigma(z^{i,l}) = \sigma(W^la^{i,l-1} + b^l)$

      c) 經過損失函數計算輸出層的$\delta^{i,L}$

      d) for $l$= L-1 to 2, 進行反向傳播算法計算$\delta^{i,l} =  (W^{l+1})^T\delta^{i,l+1}\odot \sigma^{'}(z^{i,l})$

    2-2) for $l$ = 2 to L,更新第$l$層的$W^l,b^l$:$$W^l = W^l -\alpha \sum\limits_{i=1}^m \delta^{i,l}(a^{i, l-1})^T $$$$b^l = b^l -\alpha \sum\limits_{i=1}^m \delta^{i,l}$$

    2-3) 若是全部$W,b$的變化值都小於中止迭代閾值$\epsilon$,則跳出迭代循環到步驟3。

    3) 輸出各隱藏層與輸出層的線性關係係數矩陣$W$和偏倚向量$b$。

4. DNN反向傳播算法小結

    有了DNN反向傳播算法,咱們就能夠很方便的用DNN的模型去解決第一節裏面提到了各類監督學習的分類迴歸問題。固然DNN的參數衆多,矩陣運算量也很大,直接使用會有各類各樣的問題。有哪些問題以及如未嘗試解決這些問題並優化DNN模型與算法,咱們在下一篇講。

 

(歡迎轉載,轉載請註明出處。歡迎溝通交流: liujianping-ok@163.com) 

參考資料:

1) Neural Networks and Deep Learning by By Michael Nielsen

2) Deep Learning, book by Ian Goodfellow, Yoshua Bengio, and Aaron Courville

3) UFLDL Tutorial

相關文章
相關標籤/搜索