機器學習之神經網絡算法
在機器學習和認知科學領域,人工神經網絡(英文:artificial neural network,縮寫ANN),簡稱神經網絡(英文:neural network,縮寫NN)或類神經網絡,是一種模仿生物神經網絡(動物的中樞神經系統,特別是大腦)的結構和功能的數學模型或計算模型,用於對函數進行估計或近似。神經網絡由大量的人工神經元聯結進行計算。大多數情況下人工神經網絡能在外界信息的基礎上改變內部結構,是一種自適應系統。[來源請求]現代神經網絡是一種非線性統計性數據建模工具。
神經網絡(Neural Network)概述
神經網絡算法能夠提供一種複雜且非線性的假設模型
hW,b(x)
,它具有參數
W,b
,可以以此參數來擬合我們的數據。
爲了描述神經網絡,我們先從最簡單的神經網絡講起,這個神經網絡僅由一個「神經元」構成,以下即是這個「神經元」的圖示:
![singleneuron](http://static.javashuo.com/static/loading.gif)
這個「神經元」是一個以
x1,x2,x3
及截距
+1
爲輸入值的運算單元,其輸出爲
hW,b(x)=f(WTx)=f(∑3i=1Wixi+b)
,其中函數
f:R↦R
被稱爲「激活函數」。在本教程中,我們選用sigmoid函數作爲激活函數
f(⋅)
f(z)=11+exp(−z)
可以看出,這個單一「神經元」的輸入-輸出映射關係其實就是一個邏輯迴歸(logistic regression)。
雖然本系列教程採用sigmoid函數,但你也可以選擇雙曲正切函數(tanh):
f(z)=tanh(z)=ez−e−zez+e−z
以下分別是sigmoid及tanh的函數圖像
![tanh](http://static.javashuo.com/static/loading.gif)
tanh(z)
函數是sigmoid函數的一種變體,它的取值範圍爲
[−1,1]
,而不是sigmoid函數的
[0,1]
。
注意,與其它地方不同的是,這裏我們不再令
x0=1
。取而代之,我們用單獨的參數
b
來表示截距。
最後要說明的是,有一個等式我們以後會經常用到:如果選擇
f(z)=1/(1+exp(−z))
,也就是sigmoid函數,那麼它的導數就是
f′(z)=f(z)(1−f(z))
(如果選擇tanh函數,那它的導數就是
f′(z)=1−(f(z))2
,你可以根據sigmoid(或tanh)函數的定義自行推導這個等式。
神經網絡模型
所謂神經網絡就是將許多個單一「神經元」聯結在一起,這樣,一個「神經元」的輸出就可以是另一個「神經元」的輸入。例如,下圖就是一個簡單的神經網絡:
![network331](http://static.javashuo.com/static/loading.gif)
我們使用圓圈來表示神經網絡的輸入,標上「
+1
」的圓圈被稱爲偏置節點,也就是截距項。神經網絡最左邊的一層叫做輸入層,最右的一層叫做輸出層(本例中,輸出層只有一個節點)。中間所有節點組成的一層叫做隱藏層,因爲我們不能在訓練樣本集中觀測到它們的值。同時可以看到,以上神經網絡的例子中有3個輸入單元(偏置單元不計在內),3個隱藏單元及一個輸出單元。
我們用
nl
來表示網絡的層數,本例中
nl=3
,我們將第
l
層記爲
Ll
,於是
L1
是輸入層,輸出層是
Lnl
。本例神經網絡有參數
(W,b)=(W(1),b(1),W(2),b(2))
,其中
W(l)ij
(下面的式子中用到)是第
l
層第
j
單元與第
l+1
層第
i
單元之間的聯接參數(其實就是連接線上的權重,注意標號順序),
b(l)i
是第
l+1
層第
i
單元的偏置項。因此在本例中,
W(1)∈R3×3
,
W(2)∈R1×3
。注意,沒有其他單元連向偏置單元(即偏置單元沒有輸入),因爲它們總是輸出
+1
。同時,我們用
sl
表示第
l
層的節點數(偏置單元不計在內)。
我們用
a(l)i
表示第
l
層第
i
單元的激活值(輸出值)。當
l=1
時,
a(1)i=xi
,也就是第
i
個輸入值(輸入值的第
i
個特徵)。對於給定參數集合
W,b
,我們的神經網絡就可以按照函數
hW,b(x)
來計算輸出結果。本例神經網絡的計算步驟如下:
a(2)1a(2)2a(2)3hW,b(x)=f(W(1)11x1+W(1)12x2+W(1)13x3+b(1)1)=f(W(1)21x1+W(1)22x2+W(1)23x3+b(1)2)=f(W(1)31x1+W(1)32x2+W(1)33x3+b(1)3)=a(3)1=f(W(2)11a(2)1+W(2)12a(2)2+W(2)13a(2)3+b(2)1)(1)(2)(3)(4)
我們用
z(l)i
表示第
l
層第
i
單元輸入加權和(包括偏置單元),比如,
z(2)i=∑nj=1W(1)ijxj+b(1)i
,則
a(l)i=f(z(l)i)
。
這樣我們就可以得到一種更簡潔的表示法。這裏我們將激活函數
f(⋅)
擴展爲用向量(分量的形式)來表示,即
f([z1,z2,z3])=[f(z1),f(z2),f(z3)]
,那麼,上面的等式可以更簡潔地表示爲:
z(2)a(2)z(3)hW,b(x)=W(1)x+b(1)=f(z(2))=W(2)a(2)+b(2)=a(3)=f(z(3))(5)(6)(7)(8)
我們將上面的計算步驟叫作前向傳播。回想一下,之前我們用
a(1)=x
表示輸入層的激活值,那麼給定第
l
層的激活值
a(l)
後,第
l+1
層的激活值
a(l+1)
就可以按照下面步驟計算得到:
z(l+1)a(l+1)=W(l)a(l)+b(l)=f(z(l+1))(9)(10)
將參數矩陣化,使用矩陣-向量運算方式,我們就可以利用線性代數的優勢對神經網絡進行快速求解。
目前爲止,我們討論了一種神經網絡,我們也可以構建另一種結構的神經網絡(這裏結構指的是神經元之間的聯接模式),也就是包含多個隱藏層的神經網絡。最常見的一個例子是
nl
層的神經網絡,第
1
層是輸入層,第
nl
層是輸出層,中間的每個層
l
與層
l+1
緊密相聯。這種模式下,要計算神經網絡的輸出結果,我們可以按照之前描述的等式,按部就班,進行前向傳播,逐一計算第
L2
層的所有激活值,然後是第
L3
層的激活值,以此類推,直到第
Lnl
層。這是一個前饋神經網絡的例子,因爲這種聯接圖沒有閉環或迴路。
神經網絡也可以有多個輸出單元。比如,下面的神經網絡有兩層隱藏層:
L2
及
L3
,輸出層
L4
有兩個輸出單元。
![network3322](http://static.javashuo.com/static/loading.gif)
要求解這樣的神經網絡,需要樣本集
(x(i),y(i))
,其中
y(i)∈R2
。如果你想預測的輸出是多個的,那這種神經網絡很適用。(比如,在醫療診斷應用中,患者的體徵指標就可以作爲向量的輸入值,而不同的輸出值
yi
可以表示不同的疾病存在與否。)
Backpropagation算法
假設我們有一個固定樣本集
(x(1),y(1)),⋯,(x(m),y(m))
,它包含
m
個樣例。我們可以用批量梯度下降法來求解神經網絡。具體來講,對於單個樣例
(x,y)
,其代價函數爲:
J(W,b;x,y)=12∥hW,b(x)−y∥2
這是一個(二分之一的)方差代價函數。給定一個包含
m
個樣例的數據集,我們可以定義整體代價函數爲:
J(W,b)=[1m∑i=1mJ(W,b;x(i),y(i))]+λ2∑l=1nl−1∑i=1sl∑j=1sl+1(W(l)ji)2=[1m∑i=1m(12∥∥hW,b(x(i))−y(i)∥∥2)]+λ2∑l=1nl−1∑i=1sl∑j=1sl+1(W(l)ji)2(11)(12)
以上關於
J(W,b)
定義是一個均方差項。以上的代價函數經常被用於分類和迴歸問題。在分類問題中,我們用
y=0
或
1
,來代表兩種類型的標籤(回想一下,這是因爲 sigmoid激活函數的值域爲
[0,1]
;如果我們使用雙曲正切型激活函數,那麼應該選用
−1
和
+1
作爲標籤)。對於迴歸問題,我們首先要變換輸出值域(推導過程:也就是
y
,以保證其範圍爲
[0,1]
(同樣地,如果我們使用雙曲正切型激活函數,要使輸出值域爲
[−1,1]
。
我們的目標是針對參數
W
和
b
來求其函數
J(W,b)
的最小值。爲了求解神經網絡,我們需要將每一個參數
W(l)ij
和
b(l)i
初始化爲一個很小的、接近零的隨機值(比如說,使用正態分佈
Normal(0,ϵ2)
生成的隨機值,其中
ϵ
設置爲
0.01)
,之後對目標函數使用諸如批量梯度下降法的最優化算法。因爲
J(W,b)
是一個非凸函數,梯度下降法很可能會收斂到局部最優解;但是在實際應用中,梯度下降法通常能得到令人滿意的結果。最後,需要再次強調的是,要將參數進行隨機初始化,而不是全部置爲
0
。如果所有參數都用相同的值作爲初始值,那麼所有隱藏層單元最終會得到與輸入值有關的、相同的函數(也就是說,對於所有
i
,
W(1)ij
都會取相同的值,那麼對於任何輸入
x
都會有:
a(2)1=a(2)2=a(2)3=…)
。隨機初始化的目的是使對稱失效。
梯度下降法中每一次迭代都按照如下公式對參數
W和
b 進行更新:
W(l)ijb(l)i=W(l)ij−α∂∂W(l)ijJ(W,b)=b(l)i−α∂∂b(l)iJ(W,b)(13)(14)
其中
α
是學習速率。其中關鍵步驟是計算偏導數。我們現在來講一下反向傳播算法,它是計算偏導數的一種有效方法。
我們首先來講一下如何使用反向傳播算法來計算
∂∂W(l)ijJ(W,b;x,y)
和
∂∂b(l)iJ(W,b;x,y)
,這兩項是單個樣例
(x,y)
的代價函數
J(W,b;x,y)
的偏導數。一旦我們求出該偏導數,就可以推導出整體代價函數
J(W,b)
的偏導數:
∂∂W(l)ijJ(W,b)∂∂b(l)iJ(W,b)=⎡⎣1m∑i=1m∂∂W(l)ijJ(W,b;x(i),y(i))⎤⎦=1m∑i=1m∂∂b(l)iJ(W,b;x(i),y(i))(15)(16)
反向傳播算法的思路如下:給定一個樣例
(x,y)
,我們首先進行「前向傳導」運算,計算出網絡中所有的激活值,包括
hW,b(x)
的輸出值。之後,針對第
l
層的每一個節點
i
,我們計算出其「殘差」
δ(l)i
,該殘差表明了該節點對最終輸出值的殘差產生了多少影響。對於最終的輸出節點,我們可以直接算出網絡產生的激活值與實際值之間的差距,我們將這個差距定義爲
δ(nl)i
(第
nl
層表示輸出層)。對於隱藏單元我們如何處理呢?我們將基於節點(推導過程:第
l+1
層節點)殘差的加權平均值計算
δ(l)i
,這些節點以
a(l)i
作爲輸入。下面將給出反向傳導算法的細節:
進行前饋傳導計算,利用前向傳導公式,得到
L2,L3,…
直到輸出層
Lnl
的激活值。
對於第
nl
層(輸出層)的每個輸出單元
i
,我們根據以下公式計算殘差:
δ(nl)i=∂∂z(nl)i12∥y−hW,b(x)∥2=−(yi−a(nl)i)⋅f′(z(nl)i)
[推導過程:
δ(nl)i=∂∂znliJ(W,b;x,y)=∂∂znli12∥y−hW,b(x)∥2=∂∂znli12∑j=1Snl(yj−a(nl)j)2=∂∂znli12∑j=1Snl(yj−f(z(nl)j))2=−(yi−f(z(nl)i))⋅f′(z(nl)i)=−(yi−a(nl)i)⋅f′(z(nl)i)(17)(18)(19)]
對
l=nl−1,nl−2,nl−3,…,2
的各個層,第
l
層的第
i
個節點的殘差計算方法如下:
δ(l)i=(∑j=1Sl+1W(l)jiδ(l+1)j)f′(z(l)i)
{推導過程:
δ(nl−1)i=∂∂znl−1iJ(W,b;x,y)=∂∂znl−1i12∥y−hW,b(x)∥2=∂∂znl−1i12∑j=1Snl(yj−a(nl)j)2=12∑j=1Snl∂∂znl−1i(yj−a(nl)j)2=12∑j=1Snl∂∂znl−1i(yj−f(z(nl)j))2=∑j=1Snl−(yj−f(z(nl)j))⋅∂∂z(nl−1)if(z(nl)j)=∑j=1Snl−(yj−f(z(nl)j))⋅f′(z(nl)j)⋅∂z(nl)j∂z(nl−1)i=∑j=1Snlδ(nl)j⋅∂z(nl)j∂znl−1i=∑j=1Snl⎛⎝δ(nl)j⋅∂∂znl−1i∑k=1Snl−1f(znl−1k)⋅Wnl−1jk⎞⎠=∑j=1Snlδ(nl)j⋅Wnl−1ji⋅f′(znl−1i)=⎛⎝∑j=1SnlWnl−1jiδ(nl)j⎞⎠f′(znl−1i)(20)(21)(22)(23)(24)
將上式中的
nl−1
與
nl
的關係替換爲
l
與
l+1
的關係,就可以得到:
δ(l)i=(∑sl+1j=1W(l)jiδ(l+1)j)f′(z(l)i)
以上逐次從後向前求導的過程即爲「反向傳導」的本意所在。
計算我們需要的偏導數,計算方法如下:
∂∂W(l)ijJ(W,b;x,y)∂∂b(l)iJ(W,b;x,y)=a(l)jδ(l+1)i=δ(l+1)i.(25)(26)
最後,我們用矩陣-向量表示法重寫以上算法。我們使用「
∙
」 表示向量乘積運算符,也稱作阿達馬乘積。若
a=b∙c
,則
ai=bici
。在上一個教程中我們擴展了
f(⋅)
的定義,使其包含向量運算,這裏我們也對偏導數
f′(⋅)
也做了同樣的處理(於是又有
f′([z1,z2,z3])=[f′(z1),f′(z2),f′(z3)])
。
那麼,反向傳播算法可表示爲以下幾個步驟:
進行前饋傳導計算,利用前向傳導公式,得到
L2,L3,…
直到輸出層
Lnl
的激活值。
對輸出層(第
nl
層),計算:
δ(nl)=−(y−a(nl))∙f′(z(nl))(27)
對於
l=nl−1,nl−2,nl−3,…,2
的各層,計算:
δ(l)=((W(l))Tδ(l+1))∙f′(z(l))(28)
計算最終需要的偏導數值:
∇W(l)J(W,b;x,y)∇b(l)J(W,b;x,y)=δ(l+1)(a(l))T,=δ(l+1).(29)(30)
實現中應注意:在以上的第2步和第3步中,我們需要爲每一個
i
值計算其
f′(z(l)i)
。假設
f(z)
是sigmoid函數,並且我們已經在前向傳導運算中得到了
a(l)i
。那麼,使用我們早先推導出的
f′(z)
表達式,就可以計算得到
f′(z(l)i)=a(l)i(1−a(l)i)
。
最後,我們將對梯度下降算法做個全面總結。在下面的僞代碼中,
ΔW(l)
是一個與矩陣
W(l)
維度相同的矩陣,
Δb(l)
是一個與
b(l)
維度相同的向量。注意這裏「
ΔW(l)
」是一個矩陣,而不是「
Δ
與
W(l)
相乘」。下面,我們實現批量梯度下降法中的一次迭代:
對於所有
l
,令
ΔW(l):=0,Δb(l):=0
(設置爲全零矩陣或全零向量)
對於
i=1
到
m
,
a. 使用反向傳播算法計算
∇W(l)J(W,b;x,y)
和
∇b(l)J(W,b;x,y)
。
b. 計算
ΔW(l):=ΔW(l)+∇W(l)J(W,b;x,y)
。
c. 計算
Δb(l):=Δb(l)+∇b(l)J(W,b;x,y)
。
更新權重參數:
W(l)b(l)=W(l)−α[(1mΔW(l))]=b(l)−α[1mΔb(l)](31)(32)
現在,我們可以重複梯度下降法的迭代步驟來減小代價函數
J(W,b)
的值,進而求解我們的神經網絡。
神經網絡優化
柔性最大值(softmax)
另外一種解決學習緩慢問題的方法。
柔性最大值的想法其實就是爲神經網絡定義一種新式的輸出層。
基本原理
(1). 首先計算帶權輸入
ZLj=∑kwLjkaL−1k+bLj
(2). 不在帶權輸入z上使用S型函數來獲得輸出,而是使用softmax函數來獲得輸出。
aLj=ezLj∑kezLk⋯⋯(1)
其中,分母中的求和是在所有的輸出神經元上進行的。另外一個特性:根據定義,輸出的激活值加起來正好爲1。
∑jaLj=∑jezLj∑kezLk⋯⋯(2)
由公式(1)(2),我們看到柔性最大值層的輸出是一些相加爲1正數的集合。換言之,柔性最大值層的輸出可以被看做是一個概率分佈。在很多問題中,使用softmax是很方便的。比如在MNIST分類問題中,我們可以將輸出層第j個神經元的激活值解釋成網絡估計正確數字分類爲j的概率。
softmax如何解決學習緩慢的問題?
先定義一個對數似然(log-likelihood)代價函數。對數似然函數滿足我們期待的代價函數的條件。對數似然代價函數關於權重和偏置的偏導數分別是:這些方程其實和之前的交叉熵得到的類似。只是之前的是平均值。正如前面的分析,這些表達式確保我們不會遇到學習緩慢的問題。事實上,把一個具有對數似然代價的柔性最大值輸出層,看作與一個具有交叉熵代價的S型輸出層非常相似,這是很有用的。
應該使用一個具有交叉熵代價的S 型輸出層,還是一個具有對數似然代價的柔性最大值輸出層呢?
實際上,在很多應用場景中,這兩種方式的效果都不錯。
柔性最大值加上對數似然的組合更加適用於那些需要將輸出激活值解釋爲概率的場景。
交叉熵代價函數(The cross-entropy cost function
在採用softmax爲神經網絡定義了輸出層後,其對應的代價函數爲交叉熵代價函數也稱爲對數似然代價函數(The log-likelihood cost function)。令
a=σ(z),z=∑jwjxj+b
,對於單個樣例
(x,y)
,其代價函數爲:
J(W,b;x,y)=−(ylna−(1−y)ln(1−a))
對於一個包含
m
個樣例的數據集,我們可以定義整體交叉熵代價函數爲:
J(W,b)=−1m∑i=1my(i)lna−(1−y(i))ln(1−a)
將交叉熵看作代價函數,是基於它的以下兩個特性:
(1). 它是非負的。
(2). 如果對於所有的訓練輸入
x
,神經元實際的輸出接近目標值,那麼交叉熵將接近0。
相比於二次代價函數,交叉熵還有一個特性可以避免學習速度下降的問題。
爲什麼交叉熵代價函數代價函數可以解決學習慢的問題?
因爲交叉熵函數關於權重和偏置的偏導數的表達式中不存在
σ'(z)
這樣的項,從而避免了學習緩慢。具體分析如下:
二次函數關於權重和偏置的偏導數分別是:
∂J(W,b)∂w∂J(W,b)∂b=(a−y)σ′(z)x=(a−y)σ′(z)(41)