機(jī)器學(xué)習(xí) Week3 —— 神經(jīng)網(wǎng)絡(luò),反向傳播算法

之前介紹了用于回歸問題的模型:線性回歸模型,和用于分類問題的算法:Logistic 回歸,使用這兩種算法,我們可以很好地匹配線性的特征,而如果想要得到非線性的模型,我們就需要手動(dòng)加入非線性的特征。比如在 Logistic 回歸中,我們可以加入非線性特征 x_1^2,x_1^2x_2,x_2^2等等,但是這樣大多數(shù)情況下是不實(shí)用的,因?yàn)榧词箤?duì)于只有x_1,x_2的情況,想要加入非線性特征的話就可以加x_1^2,x_2^2,x_1x_2,x_1^3...等等非常多的特征,這樣會(huì)導(dǎo)致計(jì)算量急劇增大,難以實(shí)現(xiàn)。而如果是處理圖像的話,一張圖片的每個(gè)像素都是一個(gè)特征,在這么多的特征的基礎(chǔ)上再加入非線性特征,計(jì)算量是無法想象的。因此我們需要引入新的機(jī)器學(xué)習(xí)模型——神經(jīng)網(wǎng)絡(luò)模型(Neural Networks)
先簡單介紹一下神經(jīng)網(wǎng)絡(luò)模型的背景:它最初是用來模擬大腦的,在上世紀(jì)80年代很流行,后來衰退了,但是最近又風(fēng)靡起來,成為很受歡迎的模型,有很多應(yīng)用,主要的原因是算力起來了,能夠支持神經(jīng)網(wǎng)絡(luò)模型了。

神經(jīng)網(wǎng)絡(luò)模型

一個(gè)簡單的神經(jīng)網(wǎng)絡(luò)模型包括輸入層、隱藏層、輸出層:
\begin{bmatrix}x_0 \newline x_1 \newline x_2 \newline x_3\end{bmatrix}\rightarrow\begin{bmatrix}a_1^{(2)} \newline a_2^{(2)} \newline a_3^{(2)} \newline \end{bmatrix}\rightarrow h_\theta(x)
最后輸出層的h_{\theta}(x)就是之前所說的假設(shè)函數(shù)
每層的運(yùn)算過程使用的是前向傳播(Forward Propagation),由輸入層到隱藏層的計(jì)算過程如下:
\begin{align*} a_1^{(2)} = g(\Theta_{10}^{(1)}x_0 + \Theta_{11}^{(1)}x_1 + \Theta_{12}^{(1)}x_2 + \Theta_{13}^{(1)}x_3) \newline a_2^{(2)} = g(\Theta_{20}^{(1)}x_0 + \Theta_{21}^{(1)}x_1 + \Theta_{22}^{(1)}x_2 + \Theta_{23}^{(1)}x_3) \newline a_3^{(2)} = g(\Theta_{30}^{(1)}x_0 + \Theta_{31}^{(1)}x_1 + \Theta_{32}^{(1)}x_2 + \Theta_{33}^{(1)}x_3) \newline \end{align*}
其中上標(biāo)(2)代表是第二層,g(x)代表Logistic函數(shù),\theta叫做權(quán)重(Weights)或者參數(shù),可以看到隱藏層中結(jié)點(diǎn)a_1^{(2)},a_2^{(2)},a_3^{(2)}的值都是用輸入層中的結(jié)點(diǎn)x_0,x_1...乘以一個(gè)\Theta^{(1)}的矩陣,再使用一個(gè)Logistic函數(shù)得到的。
而最后的輸出層也是類似地通過將隱藏層中的結(jié)點(diǎn)分別乘以參數(shù)求和,然后使用Logistic函數(shù)得到的:
h_\Theta(x) = a_1^{(3)} = g(\Theta_{10}^{(2)}a_0^{(2)} + \Theta_{11}^{(2)}a_1^{(2)} + \Theta_{12}^{(2)}a_2^{(2)} + \Theta_{13}^{(2)}a_3^{(2)})
可以看到如果某一層有s_j個(gè)神經(jīng)元而下一層有s_{j+1}個(gè)神經(jīng)元,那么此時(shí)\theta就是一個(gè)s_{j+1}*(s_j+1)的矩陣,之所以后面要加一是因?yàn)槲覀兠恳粚佣家~外加一個(gè)偏置(Bias)結(jié)點(diǎn)a_0^{(i)}進(jìn)去
下圖就是剛剛構(gòu)建的一個(gè)最簡單的神經(jīng)網(wǎng)絡(luò)的結(jié)構(gòu),輸入層有三個(gè)結(jié)點(diǎn),隱藏層有三個(gè)結(jié)點(diǎn),輸出層有一個(gè)結(jié)點(diǎn),隱藏層的每個(gè)結(jié)點(diǎn)都是由輸入層的每個(gè)結(jié)點(diǎn)共同運(yùn)算得到的,輸出層的結(jié)點(diǎn)也是由隱藏層的每個(gè)結(jié)點(diǎn)共同運(yùn)算得到的:

Neural network with one hidden layer

當(dāng)然,除了這種結(jié)構(gòu),你也可以設(shè)計(jì)其他的神經(jīng)網(wǎng)絡(luò)模型的結(jié)構(gòu),比如多個(gè)隱藏層,在隱藏層中設(shè)置更多結(jié)點(diǎn),等等,更復(fù)雜的結(jié)構(gòu)可以得到更復(fù)雜的非線性的特征。不管是什么結(jié)構(gòu),你只需要記住如何使用前向傳播算法計(jì)算得到每一層的值,那么這些不同的結(jié)構(gòu)都是萬變不離其宗
剛剛所介紹的模型中輸出層都只有一個(gè)結(jié)點(diǎn),如果我們要在多分類(One-vs-All)問題中應(yīng)用神經(jīng)網(wǎng)絡(luò)模型,可以在輸出層設(shè)置n個(gè)結(jié)點(diǎn):
Multiple output units

最終輸出層的結(jié)果中,對(duì)于某一類,對(duì)應(yīng)的單元為1,其余單元為0,比如四分類:
四分類

神經(jīng)網(wǎng)絡(luò)模型的損失函數(shù)

神經(jīng)網(wǎng)絡(luò)模型的損失函數(shù)和 Logistic 回歸的損失函數(shù)基本上是一樣的,只是求和多了一些,因?yàn)檩敵鰧涌赡苡胁恢挂粋€(gè)輸出h_{\theta}(x),并且在正則化的時(shí)候考慮了所有層中的參數(shù)\Theta,損失函數(shù)為:
J(\Theta) = - \frac{1}{m} \sum_{i=1}^m \sum_{k=1}^K \left[y^{(i)}_k \log ((h_\Theta (x^{(i)}))_k) + (1 - y^{(i)}_k)\log (1 - (h_\Theta(x^{(i)}))_k)\right] + \frac{\lambda}{2m}\sum_{l=1}^{L-1} \sum_{i=1}^{s_l} \sum_{j=1}^{s_{l+1}} ( \Theta_{j,i}^{(l)})^2
其中,l是指神經(jīng)網(wǎng)絡(luò)模型中的第幾層,L是指總的層數(shù),s_l指第l層中的單元總數(shù)(不包含偏置單元),k指輸出層的結(jié)點(diǎn)
其實(shí)這個(gè)損失函數(shù)的公式就是將輸出層中的所有h_{\theta}(x)的損失求和,正則化的部分就是將所有的參數(shù)\Theta平方求和

反向傳播算法(Back Propagation,BP)

有了損失函數(shù)之后,下一步就是使用算法最小化損失函數(shù)J(\Theta),以得到最優(yōu)的參數(shù)\Theta,比如在線性回歸和 Logistic 回歸中,我們使用的是梯度下降法。但是梯度下降法涉及到計(jì)算損失函數(shù)的偏導(dǎo)數(shù),線性回歸和 Logistic 回歸中的損失函數(shù)的偏導(dǎo)數(shù)可以直接計(jì)算,但是要計(jì)算神經(jīng)網(wǎng)絡(luò)模型的偏導(dǎo)數(shù)\dfrac{\partial}{\partial \Theta_{i,j}^{(l)}}J(\Theta),我們就需要使用一種算法:反向傳播算法。下面介紹一下使用反向傳播算法計(jì)算偏導(dǎo)數(shù)的流程。
首先,給定訓(xùn)練集\lbrace (x^{(1)}, y^{(1)}) \cdots (x^{(m)}, y^{(m)})\rbrace之后,對(duì)于每組數(shù)據(jù)(x^{(t)},y^{(t)}),利用前向傳播算法得到每一層的結(jié)果a^{(l)},之后,對(duì)于輸出層a^{(L)},計(jì)算:
\delta^{(L)}=a^{(L)}-y^{(t)}
L指輸出層的層數(shù),可以看出這個(gè)式子計(jì)算的就是神經(jīng)網(wǎng)絡(luò)最后的輸出結(jié)果和給定的訓(xùn)練集的y^{(t)}的差值。接下來,要得到上一層的\delta^{(l)},我們就需要用到下面的方程,可以讓我們從右到左反向計(jì)算\delta^{(L-1)},\delta^{(L-2)}一直到\delta^{(2)}
\delta^{(l)} = ((\Theta^{(l)})^T \delta^{(l+1)})\ .*\ g'(z^{(l)})
其中g'(z^{(l)})=a^{(l)}\ .*\ (1 - a^{(l)})
接下來,將\Delta_{i,j}^{(l)}初始化為一個(gè)全0的矩陣,然后使用:
\Delta_{i,j}^{(l)}=\Delta_{i,j}^{(l)}+a_j^{(l)}\delta_i^{(l+1)}
或者使用矩陣化的形式:
\Delta^{(l)}=\Delta^{(l)}+\delta^{(l+1)}(a^{(l)})^T
來更新\Delta矩陣。最后,使用方程:
D^{(l)}_{i,j} := \dfrac{1}{m}\left(\Delta^{(l)}_{i,j} + \lambda\Theta^{(l)}_{i,j}\right)\;\;\;if \;j\ne0
D^{(l)}_{i,j} := \dfrac{1}{m}\Delta^{(l)}_{i,j}\;\;\;if \;j=0
最終,我們就可以得到:
\frac \partial {\partial \Theta_{ij}^{(l)}} J(\Theta)=D_{i,j}^{(l)}

梯度檢驗(yàn)(Gradient Checking)

使用反向傳播算法我們可以計(jì)算出損失函數(shù)的偏導(dǎo)數(shù),而梯度檢驗(yàn)則是用來檢測(cè)反向傳播算法是否算出了正確的偏導(dǎo)數(shù)。
為什么要使用梯度檢驗(yàn)?zāi)??兩者都可以算出偏?dǎo)數(shù),而梯度檢驗(yàn)使用的是計(jì)算導(dǎo)數(shù)的原始方法,那么如果兩者的結(jié)果相近,說明你在模型種使用的反向傳播算法是正確的,如果結(jié)果相差很大,則說明你需要更正你的算法。注意由于這種原始的方法運(yùn)算量很大,因此訓(xùn)練模型的時(shí)候不要使用,而是只使用反向傳播算法,檢測(cè)的時(shí)候再用。
這種原始的算導(dǎo)數(shù)的方法是:
\dfrac{\partial}{\partial\Theta}J(\Theta) \approx \dfrac{J(\Theta + \epsilon) - J(\Theta - \epsilon)}{2\epsilon}
也就是使用兩個(gè)相距很近的點(diǎn)的斜率來近似導(dǎo)數(shù)
那么在神經(jīng)網(wǎng)絡(luò)模型中,對(duì)于每個(gè)\Theta_j,J(\Theta)的偏導(dǎo)數(shù)就是:
\dfrac{\partial}{\partial\Theta_j}J(\Theta) \approx \dfrac{J(\Theta_1, \dots, \Theta_j + \epsilon, \dots, \Theta_n) - J(\Theta_1, \dots, \Theta_j - \epsilon, \dots, \Theta_n)}{2\epsilon}

權(quán)重(Weights)的初始化

接下來只剩下初始化權(quán)重(參數(shù))的問題了,如果我們將所有參數(shù)\Theta初始化成一樣的,那么結(jié)果就是我們每次反向傳播的時(shí)候都不會(huì)對(duì)參數(shù)進(jìn)行優(yōu)化,因此我們需要進(jìn)行隨機(jī)初始化(Random Initialization)來破除這種對(duì)稱性,如果想在[-\epsilon,\epsilon]之間隨機(jī)初始化一個(gè)值,算法是:
\Theta=rand(10,11)*2*\epsilon-\epsilon
rand(10,11)意思是初始化一個(gè)10x11的矩陣,里面的元素都是0-1的隨機(jī)數(shù)

構(gòu)建神經(jīng)網(wǎng)絡(luò)——總結(jié)

總結(jié)一下構(gòu)建神經(jīng)網(wǎng)絡(luò)模型的步驟:
首先選擇一種架構(gòu):確定輸入、輸出的維度,有幾層隱藏層,每層有幾個(gè)單元。默認(rèn)的結(jié)構(gòu)是含一個(gè)隱藏層;隱藏層越多,模型越準(zhǔn)確,但是帶來的問題是計(jì)算量增加;如果不止一層隱藏層,推薦每層隱藏層的單元數(shù)目相同;
接下來就是神經(jīng)網(wǎng)絡(luò)模型的訓(xùn)練了,訓(xùn)練過程大致分為以下的步驟:

  • 隨機(jī)初始化權(quán)重
  • 使用前向傳播算法計(jì)算出每一層的每個(gè)結(jié)點(diǎn)的值,以及輸出層的值
  • 計(jì)算出損失函數(shù)
  • 使用反向傳播算法計(jì)算出損失函數(shù)的導(dǎo)數(shù)
  • 使用梯度檢驗(yàn)確保反向傳播算法是正確的,然后就棄用梯度檢驗(yàn)
  • 最后,使用梯度下降法或者一些編程語言的內(nèi)置優(yōu)化函數(shù)來最小化損失函數(shù),得到最優(yōu)的參數(shù)。梯度下降不一定能讓你達(dá)到全局最優(yōu),有可能只是達(dá)到了局部最優(yōu),但在實(shí)際情況中,并不怎么影響
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容