這篇博文詳細分析了前饋神經網絡的內容,它對應的函數,優化過程等等。
在上一篇博文中已經完整講述了 SVM 的思想和原理。講到了想用一個高度非線性的曲線作為擬合曲線。比如這個曲線可以是:
\[g(x)=w_3(f_2(w_2(f_1(w_1x_1+b_1))+b2))+b3 \]
這個函數的 \(x\), \(b\) 是向量,\(w\) 是矩陣,最后得到的結果是向量。\(f_1\) 和 \(f_2\) 是 sigmoid 函數或者階躍函數等非線性函數。這里就只復合三層,其實可以一直復合下去。它用一個圖表示就是下面的神經網絡:
神經網絡示意圖
這個圖中輸入層和輸出層的每個節點其實只是輸入向量 $x$ 和 $y(x)$ 的各個維度,而每個隱藏層中的節點就是一個 logistic 回歸,當然,這里的激活函數可以不止是 sigmod 函數。而相鄰兩層間的連接線其實就是 $w$。 也就是說,這個神經網絡其實就是一個復合而成的高度非線性的函數。所以其中的非線性函數是很重要的,不然的話嵌套多少層,最后的 $g(x)$ 其實還是線性函數。 那么如果直接對 $g(x)$ 構造損失函數(比如講的平方誤差之類的)也是可以的。但是優化參數時候很難,用梯度下降法之類的算法都需要求偏導,這個函數太復雜了,求起來會很麻煩。假如就寫成這樣一個損失函數(具體思想第一篇中講過了~): $$ L(w,b) = \frac{1}{n}\sum_{i=1}^{n}(g(x_i) - y(x_i))^2 $$ 下面的一些推導都是關於矩陣函數對矩陣或者向量的, 求導后的還是矩陣,所以鏈式法則的時候相乘的順序必須是**從右向左**。 這里面 y(x) 就表示真實的標簽,n 是訓練樣本的數量。然后就是對每個參數求偏導。因為這個是個復合函數,所以求偏導的時候需要用到鏈式法則。比如這里對 $w_3$ 的偏導就是: $$\frac{\partial L(w,b)}{\partial w_3} = \frac{2}{n}\sum_{i=1}^{n}\frac{\partial g(x_i)}{w_3}(g(x_i) - y(x_i)) = \frac{2}{n}\sum_{i=1}^{n}[f_2(w_2(f_1(w_1x_1+b_1))+b2)](g(x_i) - y(x_i))$$ 但是如果需要求更深的某一層,比如需要求對 $w_1$ 的梯度,按照上面的方法用鏈式法則一層一層求偏導,最后得到關於 $w_1$ 就非常麻煩了。這里只是三層,如果層次更深情況會更加嚴重。但是其實我們沒有必要求出關於每個參數的偏導的解析解。我們的目的是求出它們的數值。所以根據這個鏈式法則公式,比如在第 i 層,那么我們可能想求對於 $w_i$ 和 $b_i$ 的偏導,也就是: $$ \frac{\partial J(w,b)}{\partial w_i} = \frac{1}{n}\sum_{i=1}^{n}\frac{\partial (w_iF_i + b_i)}{\partial w_i} \frac{\partial J(w,b)}{\partial (w_iF_i + b_i)} = \frac{1}{n}\sum_{i=1}^{n}F_i \frac{\partial J(w,b)}{\partial (w_iF_i + b_i)} $$ 其中 $F_i$ 表示 $f_i(...)$, 其中的省略號是更深的復合函數。這個的值可以把數據 $x_i$ 帶進去得到。關鍵就是需要計算 $\frac{\partial J(w,b)}{\partial (w_iF_i + b_i)}$。但是求導是從外向里一層一層求的,也就是如果我們知道 $\frac{\partial J(w,b)}{\partial (w_{i+1}F_{i+1} + b_{i+1})}$,那么問題就解決了,因為可以: $$ \frac{\partial J(w,b)}{\partial (w_iF_i + b_i)} = \frac{\partial F_{i+1}}{\partial (w_iF_i + b_i)}\frac{\partial (w_{i+1}F_{i+1} + b_{i+1})}{\partial F_{i+1}}\frac{\partial J(w,b)}{\partial (w_{i+1}F_{i+1} + b_{i+1})} $$ 這樣就是一個遞推式了,這里的: $$ \frac{\partial (w_{i+1}F_{i+1} + b_{i+1})}{\partial F_{i+1}}=w_{i+1}\\ \frac{\partial F_{i+1}}{\partial (w_iF_i + b_i)} = diag(f^{'}_{i}(w_iF_i + b_i)) $$ 這里的第二個式子里面 diag 表示對角矩陣的意思,就是主對角線上的值就是 $f^{'}_{i}(w_iF_i + b_i)$ (i=1,...,m), (m 表示 z_i 的維度)。這是因為上面的函數得到的結果是向量,下面的 $(w_iF_i + b_i)$ 也是向量。而向量函數 $f(x)$ 對向量 $x$ 求偏導得到的是矩陣: $$ \begin{bmatrix} \frac{\partial f_1}{\partial x_1} &... &\frac{\partial f_m}{\partial x_1} \\ .&... & .\\ .&... & .\\ .&... & .\\ \frac{\partial f_1}{\partial x_1}&... &\frac{\partial f_m}{\partial x_n} \end{bmatrix} $$ 在這個問題中除了對角線上的偏導之外,其它的值都是 0。 然后用 $\delta_i$ 表示 $\frac{\partial J(w,b)}{\partial (w_iF_i + b_i)}$, 那么上面這個遞推式就是: $$ \delta_i=diag(f^{'}_{i}(w_iF_i + b_i))(w_{i+1}^T\delta_{i+1}) $$ 其實到這里問題就已經解決了,已經有了計算每一層 $w_i$ 和 $b_i$ 的式子,就是: $$ \frac{\partial J(w,b)}{\partial w_i} = \frac{1}{n}\sum_{i=1}^{n}F_i \delta_i\\ \frac{\partial J(w,b)}{\partial b_i} = \frac{1}{n}\sum_{i=1}^{n} \delta_i $$ 又有了關於 $\delta$ 的遞推式,也就是可以從 $\delta_{i+1}$ 遞推到 $\delta_i$ ,也就可以把 $w_i$ 和 $b_i$ 算出來了。但是 $\delta_{N}$ (N 為外面的一層)怎么算呢?因為 $J(w,b)$ 的形式在具體問題中是確定的,可以直接求 $\delta_{N}=\frac{\partial J(w,b)}{\partial w_NF_N + b_Ni}=\frac{\partial J(w,b)}{\partial g(x)}$ 就行了。 這個就是神經網絡中的反向傳播算法。為什么叫反向傳播呢?如果把這個復合函數 $L(w,b)$ 還原成神經網絡的圖像就比較直觀了:
這里每個節點都表示一個向量,$z$ 表示沒有經過激活函數的結果,$a$ 表示經過了激活函數的結果,這樣把同一層的節點拆成兩個過程。這里 $\frac{\partial J(w,b)}{\partial z_i}$ 就是之前推導過程中的 $\frac{\partial J(w,b)}{\partial (w_iF_i + b_i)}$。整個推導過程可以在這個圖中更清晰的表示出來。這篇博文里調參是針對它表示的函數推導的,熟悉了的話就可以直接根據網絡的圖進行推導,會比較清晰(特別是 LSTM 這些復雜的網絡)。關鍵是要找到那個遞推的式子,它其實就是相鄰兩個層的梯度之間的關系,用鏈式法則聯系起來。 整個流程就是對於某個訓練數據 $(x_i, y_i)$, 先正向(從左往右)得到一個預測值 $f(x_i)$, 帶入損失函數 $J(x, w, b)$ 中。然后用上面的遞推方法反向一層一層的計算對於各層參數的梯度以及對於下一層的梯度,最后就能夠算出來對於各個參數的梯度。然后利用梯度下降法等方法調整一次參數。這樣一次正向,一次反向就調了一次參數。 最后那個損失函數其實有很多可以選擇,交叉熵,softmax 等等。用不同的損失函數對於整個調參過程而言,就是算 $\delta_N$ 的時候不同。這個 $\delta$ 其實就是損失函數得到的誤差,對前面每一層的輸出的梯度,整個調參過程就是靠它向前傳播。這個就是神經網絡中的殘差。 這個就是神經網絡的基本流程了。但是這個算法如果是淺層的還好,一旦層數變的很多就會帶來很多問題:
- 優化的時候計算性能要求很高。所以這個算法在發明的時候並沒有特別火,現在隨着計算機性能的提高,才有了商業價值。
- 梯度消失。這個是指層數太多的時候,最后幾層的參數會調的比較好,所以在反向傳播的時候殘差會越來越小,以至於前面幾層的參數很難調好。所以結果還不如用淺層的。
- 參數過多,很容易陷入局部最優解。
針對這些問題,有很多特殊的神經網絡,這些網絡的層數可以很深,還有各種特殊的結構。這個就是深度學習。比較常見的有循環神經網絡(RNN)、卷積神經網絡(CNN)、自編碼器等。這些網絡結構各有各的優點和用處,但是基本流程和優化方法還是跟神經網絡差不多,這里就不贅述了。這個系列到這里就結束了~,自編碼器、CNN 之類的以后結合 tensorflow 再寫吧。
參考鏈接:
- 吳立德老師的視頻
如需轉載,請注明出處.
出處:http://www.cnblogs.com/xinchen1111/p/8793570.html