深度学习入门笔记(六):浅层神经网络
專欄——深度學(xué)習入門筆記
聲明
1)該文章整理自網(wǎng)上的大牛和機器學(xué)習專家無私奉獻的資料,具體引用的資料請看參考文獻。
2)本文僅供學(xué)術(shù)交流,非商用。所以每一部分具體的參考資料并沒有詳細對應(yīng)。如果某部分不小心侵犯了大家的利益,還望海涵,并聯(lián)系博主刪除。
3)博主才疏學(xué)淺,文中如有不當之處,請各位指出,共同進步,謝謝。
4)此屬于第一版本,若有錯誤,還需繼續(xù)修正與增刪。還望大家多多指點。大家都共享一點點,一起為祖國科研的推進添磚加瓦。
文章目錄
- 專欄——深度學(xué)習入門筆記
- 聲明
- 深度學(xué)習入門筆記(六):淺層神經(jīng)網(wǎng)絡(luò)
- 1 、神經(jīng)網(wǎng)絡(luò)概述
- 2、激活函數(shù)和激活函數(shù)的導(dǎo)數(shù)
- 3、為什么需要非線性激活函數(shù)?
- 4、神經(jīng)網(wǎng)絡(luò)的梯度下降
- 5、隨機初始化
- 推薦閱讀
- 參考文章
深度學(xué)習入門筆記(六):淺層神經(jīng)網(wǎng)絡(luò)
1 、神經(jīng)網(wǎng)絡(luò)概述
關(guān)于神經(jīng)網(wǎng)絡(luò)的概述,具體的可以看這個博客——大話卷積神經(jīng)網(wǎng)絡(luò)CNN(干貨滿滿),我在其中詳細的介紹了 人類視覺原理、神經(jīng)網(wǎng)絡(luò)、卷積神經(jīng)網(wǎng)絡(luò)的定義和相關(guān)網(wǎng)絡(luò)結(jié)構(gòu)基礎(chǔ),還有 應(yīng)用 和 關(guān)于深度學(xué)習的本質(zhì)的探討,如果你需要 學(xué)習資源 也可以在博客中找一下,這里就不詳細介紹了。
什么是淺層神經(jīng)網(wǎng)絡(luò)呢?
看了上面提到的博客,你應(yīng)該知道相關(guān)概念了,淺層神經(jīng)網(wǎng)絡(luò)其實就是一個單隱層神經(jīng)網(wǎng)絡(luò)!!!
2、激活函數(shù)和激活函數(shù)的導(dǎo)數(shù)
使用一個神經(jīng)網(wǎng)絡(luò)時,需要決定使用哪種激活函數(shù)用隱藏層上?哪種用在輸出節(jié)點上?不同的激活函數(shù)的效果是不一樣的。下面將介紹一下常用的激活函數(shù):
- sigmoid 函數(shù)
函數(shù)圖像和導(dǎo)數(shù)圖像如下:
公式如下:
a=σ(z)=11+e?za = \sigma(z) = \frac{1}{{1 + e}^{- z}}a=σ(z)=1+e?z1?
導(dǎo)數(shù)公式如下:
ddzg(z)=11+e?z(1?11+e?z)=g(z)(1?g(z))\fracozvdkddzhkzd{dz}g(z) = {\frac{1}{1 + e^{-z}} (1-\frac{1}{1 + e^{-z}})}=g(z)(1-g(z))dzd?g(z)=1+e?z1?(1?1+e?z1?)=g(z)(1?g(z))
如果沒有非線性的激活函數(shù),再多的神經(jīng)網(wǎng)絡(luò)只是計算線性函數(shù),或者叫恒等激勵函數(shù)。sigmoid 函數(shù)是使用比較多的一個激活函數(shù)。
- tanh 函數(shù)
函數(shù)圖像和導(dǎo)數(shù)圖像如下:
公式如下:
a=tanh(z)=ez?e?zez+e?za= tanh(z) = \frac{e^{z} - e^{- z}}{e^{z} + e^{- z}}a=tanh(z)=ez+e?zez?e?z?
導(dǎo)數(shù)公式如下:
ddzg(z)=1?(tanh(z))2\fracozvdkddzhkzd{ozvdkddzhkzdz}g(z) = 1 - (tanh(z))^{2}dzd?g(z)=1?(tanh(z))2
事實上,tanh 是 sigmoid 的向下平移和伸縮后的結(jié)果。對它進行了變形后,穿過了(0,0)(0,0)(0,0)點,并且值域介于 +1 和 -1 之間。
所以效果總是優(yōu)于 sigmoid 函數(shù)。因為函數(shù)值域在 -1 和 +1 的激活函數(shù),其均值是更接近零均值的。在訓(xùn)練一個算法模型時,如果使用 tanh 函數(shù)代替 sigmoid 函數(shù)中心化數(shù)據(jù),使得數(shù)據(jù)的平均值更接近0而不是0.5。但是也有例外的情況,有時對隱藏層使用 tanh 激活函數(shù),而輸出層使用 sigmoid 函數(shù),效果會更好。
小結(jié):
sigmoid 函數(shù)和 tanh 函數(shù)兩者共同的缺點是,在未經(jīng)過激活函數(shù)的輸出特別大或者特別小的情況下,會導(dǎo)致導(dǎo)數(shù)的梯度或者函數(shù)的斜率變得特別小,最后就會接近于0,導(dǎo)致降低梯度下降的速度。
- ReLu 函數(shù)
在機器學(xué)習另一個很流行的函數(shù)是:修正線性單元的函數(shù)(ReLu)。
函數(shù)圖像和導(dǎo)數(shù)圖像如下:
公式如下:
a=max(0,z)a =max( 0,z) a=max(0,z)
導(dǎo)數(shù)公式如下:
g(z)′={0if?z?<?01if?z?>?0undefinedif?z?=?0g(z)^{'}= \begin{cases} 0& \text{if z < 0}\\ 1& \text{if z > 0}\\ undefined& \text{if z = 0} \end{cases} g(z)′=??????01undefined?if?z?<?0if?z?>?0if?z?=?0?
當 zzz 是正值的情況下,導(dǎo)數(shù)恒等于1,當 zzz 是負值的時候,導(dǎo)數(shù)恒等于0。Relu 的一個優(yōu)點是當 zzz 是負值的時候,導(dǎo)數(shù)等于0,當 zzz 是正值的時候,導(dǎo)數(shù)等于1。這樣在梯度下降時就不會受 梯度爆炸或者梯度消失 的影響了。
詳見博客——深度學(xué)習100問之深入理解Vanishing/Exploding Gradient(梯度消失/爆炸)
一些選擇激活函數(shù)的經(jīng)驗法則:
如果輸出是0、1值(二分類問題),則輸出層選擇 sigmoid 函數(shù),然后其它的所有單元都選擇 Relu 函數(shù)。這是很多激活函數(shù)的默認選擇,如果在隱藏層上不確定使用哪個激活函數(shù),那么通常會使用 Relu 激活函數(shù)。有時,也會使用 tanh 激活函數(shù)。
- Leaky Relu 函數(shù)
這里也有另一個版本的 Relu 被稱為 Leaky Relu。
函數(shù)圖像和導(dǎo)數(shù)圖像如下:
與 ReLU 類似,公式如下:
g(z)=max?(0.01z,z)g(z)=\max(0.01z,z)g(z)=max(0.01z,z)
導(dǎo)數(shù)公式如下:
g(z)′={0.01if?z?<?01if?z?>?0undefinedif?z?=?0g(z)^{'}= \begin{cases} 0.01& \text{if z < 0}\\ 1& \text{if z > 0}\\ undefined& \text{if z = 0} \end{cases} g(z)′=??????0.011undefined?if?z?<?0if?z?>?0if?z?=?0?
當 zzz 是負值時,這個函數(shù)的值不是等于0,而是輕微的傾斜。這個函數(shù)通常比 Relu 激活函數(shù)效果要好,盡管在實際中 Leaky ReLu 使用的并不多。
RELU 系列的兩個激活函數(shù)的優(yōu)點是:
-
第一,在未經(jīng)過激活函數(shù)的輸出的區(qū)間變動很大的情況下,激活函數(shù)的導(dǎo)數(shù)或者激活函數(shù)的斜率都會遠大于0,在程序?qū)崿F(xiàn)就是一個 if-else 語句,而 sigmoid 函數(shù)需要進行浮點四則運算,在實踐中,使用 ReLu 激活函數(shù)神經(jīng)網(wǎng)絡(luò)通常會比使用 sigmoid 或者 tanh 激活函數(shù)學(xué)習的更快。
-
第二,sigmoid 和 tanh 函數(shù)的導(dǎo)數(shù)在正負飽和區(qū)的梯度都會接近于0,這會造成梯度彌散,而 Relu 和 Leaky ReLu 函數(shù)大于0部分都為常數(shù),不會產(chǎn)生梯度彌散現(xiàn)象。(同時應(yīng)該注意到的是,Relu 進入負半?yún)^(qū)的時候,梯度為0,神經(jīng)元此時不會訓(xùn)練,產(chǎn)生所謂的 稀疏性,而 Leaky ReLu 不會有這問題。但 ReLu 的梯度一半都是0,有足夠的隱藏層使得未經(jīng)過激活函數(shù)的輸出值大于0,所以對大多數(shù)的訓(xùn)練數(shù)據(jù)來說學(xué)習過程仍然可以很快。)
最后簡單介紹完了常用的激活函數(shù)之后,來快速概括一下。
-
sigmoid 激活函數(shù):除了輸出層是一個二分類問題基本上不會用 sigmoid。
-
tanh 激活函數(shù):tanh 是非常優(yōu)秀的,幾乎適合所有場合。
-
ReLu 激活函數(shù):最常用的默認激活函數(shù)。如果不確定用哪個激活函數(shù),就先使用 ReLu。
很多人在編寫神經(jīng)網(wǎng)絡(luò)的時候,經(jīng)常遇到一個問題是,有很多個選擇:隱藏層單元的個數(shù)、激活函數(shù)的種類、初始化權(quán)值的方式、等等……這些選擇想得到一個比較好的指導(dǎo)原則是挺困難的,所以其實更多的是經(jīng)驗,這也是深度學(xué)習被人稱為經(jīng)驗主義學(xué)科和被人詬病的地方,更像是一種煉丹術(shù),是不是?
你可能會看到好多博客,文章,或者哪一個工業(yè)界大佬或者學(xué)術(shù)界大佬說過,哪一種用的多,哪一種更好用。但是,你的神經(jīng)網(wǎng)絡(luò)的結(jié)構(gòu),以及需要解決問題的特殊性,是很難提前知道選擇哪些效果更好的,或者沒辦法確定別人的經(jīng)驗和結(jié)論是不是對你同樣有效。
所以通常的建議是:如果不確定哪一個激活函數(shù)效果更好,可以把它們都試試,然后在驗證集或者測試集上進行評價,這樣如果看到哪一種的表現(xiàn)明顯更好一些,就在你的網(wǎng)絡(luò)中使用它!!!
3、為什么需要非線性激活函數(shù)?
為什么神經(jīng)網(wǎng)絡(luò)需要非線性激活函數(shù)?
首先是事實證明了,要讓神經(jīng)網(wǎng)絡(luò)能夠計算出有趣的函數(shù),必須使用非線性激活函數(shù)。但是這么說太不科學(xué)了,現(xiàn)在來證明一下,證明過程如下:
a[1]=g(z[1])a^{[1]} = g(z^{[1]})a[1]=g(z[1]),這是神經(jīng)網(wǎng)絡(luò)正向傳播的方程,之前我們學(xué)過的,你還記得不?不記得去翻翻 深度學(xué)習入門筆記(二):神經(jīng)網(wǎng)絡(luò)基礎(chǔ)。
現(xiàn)在去掉函數(shù) ggg,也就是去掉激活函數(shù),然后令 a[1]=z[1]a^{[1]} = z^{[1]}a[1]=z[1],或者也可以直接令 g(z[1])=z[1]g(z^{[1]})=z^{[1]}g(z[1])=z[1],這個有時被叫做 線性激活函數(shù)(更學(xué)術(shù)點的名字是 恒等激勵函數(shù),因為它們就是把輸入值直接輸出)。
因為:
(1) a[1]=z[1]=W[1]x+b[1]a^{[1]} = z^{[1]} = W^{[1]}x + b^{[1]}a[1]=z[1]=W[1]x+b[1]
(2) a[2]=z[2]=W[2]a[1]+b[2]a^{[2]} = z^{[2]} = W^{[2]}a^{[1]}+ b^{[2]}a[2]=z[2]=W[2]a[1]+b[2]
將式子(1)代入式子(2)中,則得到:
(3) a[2]=z[2]=W[2](W[1]x+b[1])+b[2]=W[2]W[1]x+W[2]b[1]+b[2]=(W[2]W[1])x+(W[2]b[1]+b[2])a^{[2]} = z^{[2]} = W^{[2]}(W^{[1]}x + b^{[1]}) + b^{[2]} = W^{[2]}W^{[1]}x + W^{[2]}b^{[1]} + b^{[2]} = (W^{[2]}W^{[1]})x + (W^{[2]}b^{[1]} + b^{[2]})a[2]=z[2]=W[2](W[1]x+b[1])+b[2]=W[2]W[1]x+W[2]b[1]+b[2]=(W[2]W[1])x+(W[2]b[1]+b[2])
然后簡化多項式,你可以發(fā)現(xiàn)兩個括號里的式子都可以簡化,可得:
(4) a[2]=z[2]=W′x+b′a^{[2]} = z^{[2]} = W^{'}x + b^{'}a[2]=z[2]=W′x+b′
小結(jié):如果使用 線性激活函數(shù) 或者叫 恒等激勵函數(shù),那么神經(jīng)網(wǎng)絡(luò)只是把輸入線性組合再輸出。
之后我們會學(xué)到 深度網(wǎng)絡(luò),什么是 深度網(wǎng)絡(luò)?顧名思義,就是有很多層(很多隱藏層)的神經(jīng)網(wǎng)絡(luò)。然而,上面的證明告訴我們,如果使用線性激活函數(shù)或者不使用激活函數(shù),那么無論你的神經(jīng)網(wǎng)絡(luò)有多少層,一直在做的也只是計算線性函數(shù),都可以用 a[2]=z[2]=W′x+b′a^{[2]} = z^{[2]} = W^{'}x + b^{'}a[2]=z[2]=W′x+b′ 表示,還不如直接去掉全部隱藏層,反正也沒啥用。。。
總之,不能在隱藏層用線性激活函數(shù),相反你可以用 ReLU 或者 tanh 或者 leaky ReLU 或者其他的非線性激活函數(shù),唯一可以用線性激活函數(shù)的通常就是輸出層。
4、神經(jīng)網(wǎng)絡(luò)的梯度下降
我們這一次講的淺層神經(jīng)網(wǎng)絡(luò)——單隱層神經(jīng)網(wǎng)絡(luò),會有 W[1]W^{[1]}W[1],b[1]b^{[1]}b[1],W[2]W^{[2]}W[2],b[2]b^{[2]}b[2] 這些個參數(shù),還有個 nxn_xnx? 表示輸入特征的個數(shù),n[1]n^{[1]}n[1] 表示隱藏單元個數(shù),n[2]n^{[2]}n[2] 表示輸出單元個數(shù)。
好了,這就是全部的符號參數(shù)了。那么具體參數(shù)的維度如下:
-
矩陣 W[1]W^{[1]}W[1] 的維度就是(n[1],n[0]n^{[1]}, n^{[0]}n[1],n[0]),b[1]b^{[1]}b[1] 就是 n[1]n^{[1]}n[1]維向量,可以寫成 (n[1],1)(n^{[1]}, 1)(n[1],1),就是一個的列向量。
-
矩陣 W[2]W^{[2]}W[2] 的維度就是(n[2],n[1]n^{[2]}, n^{[1]}n[2],n[1]),b[2]b^{[2]}b[2] 的維度和 b[1]b^{[1]}b[1] 一樣,就是寫成 (n[2],1)(n^{[2]},1)(n[2],1)。
此外,還有一個神經(jīng)網(wǎng)絡(luò)的 代價函數(shù)(Cost function),在之前的博客——深度學(xué)習入門筆記(二):神經(jīng)網(wǎng)絡(luò)基礎(chǔ) 中講過,不過是基于邏輯回歸的。假設(shè)現(xiàn)在是在做二分類任務(wù),那么代價函數(shù)等于:
J(W[1],b[1],W[2],b[2])=1m∑i=1mL(y^,y)J(W^{[1]},b^{[1]},W^{[2]},b^{[2]}) = {\frac{1}{m}}\sum_{i=1}^mL(\hat{y}, y)J(W[1],b[1],W[2],b[2])=m1?i=1∑m?L(y^?,y)
訓(xùn)練參數(shù)之后,需要做梯度下降,然后進行參數(shù)更新,進而網(wǎng)絡(luò)優(yōu)化。所以,每次梯度下降都會循環(huán),并且計算以下的值,也就是網(wǎng)絡(luò)的輸出:
y^(i)(i=1,2,…,m)\hat{y}^{(i)} (i=1,2,…,m)y^?(i)(i=1,2,…,m)
- 前向傳播(forward propagation) 方程如下(之前講過):
(1) z[1]=W[1]x+b[1]z^{[1]} = W^{[1]}x + b^{[1]}z[1]=W[1]x+b[1]
(2) a[1]=σ(z[1])a^{[1]} = \sigma(z^{[1]})a[1]=σ(z[1])
(3) z[2]=W[2]a[1]+b[2]z^{[2]} = W^{[2]}a^{[1]} + b^{[2]}z[2]=W[2]a[1]+b[2]
(4) a[2]=g[2](z[z])=σ(z[2])a^{[2]} = g^{[2]}(z^{[z]}) = \sigma(z^{[2]})a[2]=g[2](z[z])=σ(z[2])
- 反向傳播(back propagation) 方程如下:
(1) dz[2]=A[2]?Y,Y=[y[1]y[2]?y[m]]dz^{[2]} = A^{[2]} - Y , Y = \begin{bmatrix}y^{[1]} & y^{[2]} & \cdots & y^{[m]}\\ \end{bmatrix}dz[2]=A[2]?Y,Y=[y[1]?y[2]???y[m]?]
(2) dW[2]=1mdz[2]A[1]TdW^{[2]} = {\frac{1}{m}}dz^{[2]}A^{[1]T}dW[2]=m1?dz[2]A[1]T
(3) db[2]=1mnp.sum(dz[2],axis=1,keepdims=True){\rm d}b^{[2]} = {\frac{1}{m}}np.sum(ozvdkddzhkzdz^{[2]},axis=1,keepdims=True)db[2]=m1?np.sum(dz[2],axis=1,keepdims=True)
(4) dz[1]=W[2]Tdz[2]?(n[1],m)?g[1]′?activationfunctionofhiddenlayer?(z[1])?(n[1],m)dz^{[1]} = \underbrace{W^{[2]T}{\rm d}z^{[2]}}_{(n^{[1]},m)}\quad*\underbrace{{g^{[1]}}^{'}}_{activation \; function \; of \; hidden \; layer}*\quad\underbrace{(z^{[1]})}_{(n^{[1]},m)}dz[1]=(n[1],m)W[2]Tdz[2]???activationfunctionofhiddenlayerg[1]′???(n[1],m)(z[1])??
(5) dW[1]=1mdz[1]xTdW^{[1]} = {\frac{1}{m}}dz^{[1]}x^{T}dW[1]=m1?dz[1]xT
(6) db[1]?(n[1],1)=1mnp.sum(dz[1],axis=1,keepdims=True){\underbrace{db^{[1]}}_{(n^{[1]},1)}} = {\frac{1}{m}}np.sum(dz^{[1]},axis=1,keepdims=True)(n[1],1)db[1]??=m1?np.sum(dz[1],axis=1,keepdims=True)
注:反向傳播的這些公式都是針對所有樣本,進行過向量化的(深度學(xué)習入門筆記(四):向量化)。
其中,YYY 是 1×m1×m1×m 的矩陣;這里 np.sum 是 python 的 numpy 命令,axis=1 表示水平相加求和,keepdims 是防止 python 輸出那些古怪的秩數(shù) (n,)(n,)(n,),加上這個確保陣矩陣 db[2]db^{[2]}db[2] 這個向量的輸出的維度為 (n,1)(n,1)(n,1) 這樣標準的形式。
編程操作看這個博客——深度學(xué)習入門筆記(五):神經(jīng)網(wǎng)絡(luò)的編程基礎(chǔ)。
- 參數(shù)更新 方程如下:
(1) dW[1]=dJdW[1],db[1]=dJdb[1]dW^{[1]} = \frac{dJ}{dW^{[1]}},db^{[1]} = \frac{dJ}{db^{[1]}}dW[1]=dW[1]dJ?,db[1]=db[1]dJ?
(1) dW[2]=dJdW[2],db[2]=dJdb[2]ozvdkddzhkzdW^{[2]} = \frac{{dJ}}{dW^{[2]}},ozvdkddzhkzdb^{[2]} = \frac{dJ}{db^{[2]}}dW[2]=dW[2]dJ?,db[2]=db[2]dJ?
其中 W[1]?W[1]?adW[1],b[1]?b[1]?adb[1]W^{[1]}\implies{W^{[1]} - adW^{[1]}},b^{[1]}\implies{b^{[1]} -adb^{[1]}}W[1]?W[1]?adW[1],b[1]?b[1]?adb[1],W[2]?W[2]?αdW[2],b[2]?b[2]?αdb[2]W^{[2]}\implies{W^{[2]} - \alpha{\rm d}W^{[2]}},b^{[2]}\implies{b^{[2]} - \alpha{\rm d}b^{[2]}}W[2]?W[2]?αdW[2],b[2]?b[2]?αdb[2]。
如果你跟著咱們系列下來的話(深度學(xué)習入門筆記),應(yīng)該發(fā)現(xiàn)了到目前為止,計算的都和 Logistic 回歸(深度學(xué)習入門筆記(二):神經(jīng)網(wǎng)絡(luò)基礎(chǔ))十分的相似,但當你開始 計算 反向傳播的時候,你會發(fā)現(xiàn),是需要計算隱藏層和輸出層激活函數(shù)的導(dǎo)數(shù)的,在這里(二元分類)使用的是 sigmoid 函數(shù)。
如果你想認真的推導(dǎo)一遍反向傳播,深入理解反向傳播的話,歡迎看一下這個博客——深度學(xué)習100問之深入理解Back Propagation(反向傳播),只要你跟著推導(dǎo)一遍,反向傳播基本沒什么大問題了。或者如果你覺得自己數(shù)學(xué)不太好的話,也可以和許多成功的深度學(xué)習從業(yè)者一樣直接實現(xiàn)這個算法,不去了解其中的知識,這就是深度學(xué)習相較于機器學(xué)習最大的優(yōu)勢,我猜是的。
5、隨機初始化
當訓(xùn)練神經(jīng)網(wǎng)絡(luò)時,權(quán)重隨機初始化 是很重要的,簡單來說,參數(shù)初始化 就是 決定梯度下降中的起始點。對于邏輯回歸,把權(quán)重初始化為0當然也是可以的,但是對于一個神經(jīng)網(wǎng)絡(luò),如果權(quán)重或者參數(shù)都初始化為0,那么梯度下降將不會起作用。你一定想問為什么?
慢慢來看,假設(shè)現(xiàn)在有兩個輸入特征,即 n[0]=2n^{[0]} = 2n[0]=2,2個隱藏層單元,即 n[1]n^{[1]}n[1] 等于2,因此與一個隱藏層相關(guān)的矩陣,或者說 W[1]W^{[1]}W[1] 就是一個 2*2 的矩陣。我們再假設(shè),在權(quán)重隨機初始化的時候,把它初始化為 0 的 2*2 矩陣,b[1]b^{[1]}b[1] 也等于 [00]T[0\;0]^T[00]T(把偏置項 bbb 初始化為0是合理的),但是把 www 初始化為 0 就有問題了。你會發(fā)現(xiàn),如果按照這樣進行參數(shù)初始化的話,總是發(fā)現(xiàn) a1[1]a_{1}^{[1]}a1[1]? 和 a2[1]a_{2}^{[1]}a2[1]? 相等,這兩個激活單元就會一樣了!!!為什么會這樣呢?
因為在反向傳播時,兩個隱含單元計算的是相同的函數(shù),都是來自 a1[2]a_1^{[2]}a1[2]? 的梯度變化,也就是 dz1[1]\text{dz}_{1}^{[1]}dz1[1]? 和 dz2[1]\text{dz}_{2}^{[1]}dz2[1]? 是一樣的,由 W[1]=W[1]?adWW^{[1]} = {W^{[1]}-adW}W[1]=W[1]?adW 可得 W[1]=adWW^{[1]} = ad{W}W[1]=adW,學(xué)習率 aaa 一樣,梯度變化 dWd{W}dW 一樣,這樣更新后的輸出權(quán)值也會一模一樣,由此 W[2]W^{[2]}W[2] 也等于 [00][0\;0][00]。
你可能覺得這也沒啥啊,大驚小怪的,但是如果這樣初始化這整個神經(jīng)網(wǎng)絡(luò)的話,那么這兩個隱含單元就完全一樣了,因此它們兩個完全對稱,也就意味著計算同樣的函數(shù),并且肯定的是最終經(jīng)過每次訓(xùn)練的迭代,這兩個隱含單元仍然是同一個函數(shù),令人困惑。
由此可以推導(dǎo),由于隱含單元計算的是同一個函數(shù),所有的隱含單元對輸出單元有同樣的影響。一次迭代后,同樣的表達式結(jié)果仍然是相同的,即 隱含單元仍是對稱的。那么兩次、三次、無論多少次迭代,不管網(wǎng)絡(luò)訓(xùn)練多長時間,隱含單元仍然計算的是同樣的函數(shù)。因此這種情況下超過1個隱含單元也沒什么意義,因為計算的是同樣的東西。當然無論是多大的網(wǎng)絡(luò),比如有3個特征,還是有相當多的隱含單元。
那么這個問題的解決方法是什么?其實很簡單,就是 隨機初始化參數(shù)。
你應(yīng)該這么做:把 W[1]W^{[1]}W[1] 設(shè)為 np.random.randn(2,2)(生成標準正態(tài)分布),通常再乘上一個較小的數(shù),比如 0.01,這樣就把它初始化為一個很小的隨機數(shù)。然后 bbb 本來就沒有這個對稱的問題(叫做symmetry breaking problem),所以可以把 bbb 初始化為0,因為只要隨機初始化 WWW,就有不同的隱含單元計算不同的東西,就不會有 symmetry breaking 問題了。相似地,對于 W[2]W^{[2]}W[2] 也隨機初始化,b[2]b^{[2]}b[2] 可以初始化為0。
舉一個隨機初始化的例子,比如:
W[1]=np.random.randn(2,2)?0.01,b[1]=np.zeros((2,1))W^{[1]} = np.random.randn(2,2)\;*\;0.01\;,\;b^{[1]} = np.zeros((2,1))W[1]=np.random.randn(2,2)?0.01,b[1]=np.zeros((2,1))
W[2]=np.random.randn(2,2)?0.01,b[2]=0W^{[2]} = np.random.randn(2,2)\;*\;0.01\;,\;b^{[2]} = 0W[2]=np.random.randn(2,2)?0.01,b[2]=0
你也許會疑惑,這個常數(shù)從哪里來?為什么是0.01,而不是100或者1000?
這是因為我們 通常傾向于初始化為很小的隨機數(shù)。
這么想,如果你用 tanh 或者 sigmoid 激活函數(shù),或者說只在輸出層有一個 sigmoid 激活函數(shù),這種情況下,如果(數(shù)值)波動太大,在計算激活值時 z[1]=W[1]x+b[1],a[1]=σ(z[1])=g[1](z[1])z^{[1]} = W^{[1]}x + b^{[1]}\;,\;a^{[1]} = \sigma(z^{[1]})=g^{[1]}(z^{[1]})z[1]=W[1]x+b[1],a[1]=σ(z[1])=g[1](z[1]),如果 WWW 很大,zzz 就會很大或者很小,這種情況下很可能停在 tanh / sigmoid 函數(shù)的平坦的地方(甚至在訓(xùn)練剛剛開始的時候),而這些平坦的地方對應(yīng)導(dǎo)數(shù)函數(shù)圖像中梯度很小的地方,也就意味著梯度下降會很慢(因為梯度小),因此學(xué)習也就很慢,這顯然是不好的。
sigmoid 函數(shù)圖像和導(dǎo)數(shù)函數(shù)圖像:
tanh 函數(shù)圖像和導(dǎo)數(shù)函數(shù)圖像:
如果你沒有使用 sigmoid / tanh 激活函數(shù)在整個的神經(jīng)網(wǎng)絡(luò)里,就不成問題。但如果做二分類并且輸出單元是 Sigmoid 函數(shù),那么你一定不會想讓你的初始參數(shù)太大,因此這就是為什么乘上 0.01 或者其他一些小數(shù)是合理的嘗試,對 w[2]w^{[2]}w[2] 也是一樣。
關(guān)于淺層神經(jīng)網(wǎng)絡(luò)的代碼,可以手撕一下,歡迎看一下這個博客——深度學(xué)習之手撕神經(jīng)網(wǎng)絡(luò)代碼(基于numpy)。
推薦閱讀
- 深度學(xué)習入門筆記(一):深度學(xué)習引言
- 深度學(xué)習入門筆記(二):神經(jīng)網(wǎng)絡(luò)基礎(chǔ)
- 深度學(xué)習入門筆記(三):求導(dǎo)和計算圖
- 深度學(xué)習入門筆記(四):向量化
- 深度學(xué)習入門筆記(五):神經(jīng)網(wǎng)絡(luò)的編程基礎(chǔ)
- 深度學(xué)習入門筆記(六):淺層神經(jīng)網(wǎng)絡(luò)
- 深度學(xué)習入門筆記(七):深層神經(jīng)網(wǎng)絡(luò)
- 深度學(xué)習入門筆記(八):深層網(wǎng)絡(luò)的原理
- 深度學(xué)習入門筆記(九):深度學(xué)習數(shù)據(jù)處理
- 深度學(xué)習入門筆記(十):正則化
- 深度學(xué)習入門筆記(十一):權(quán)重初始化
- 深度學(xué)習入門筆記(十二):深度學(xué)習數(shù)據(jù)讀取
- 深度學(xué)習入門筆記(十三):批歸一化(Batch Normalization)
- 深度學(xué)習入門筆記(十四):Softmax
- 深度學(xué)習入門筆記(十五):深度學(xué)習框架(TensorFlow和Pytorch之爭)
- 深度學(xué)習入門筆記(十六):計算機視覺之邊緣檢測
- 深度學(xué)習入門筆記(十七):深度學(xué)習的極限在哪?
- 深度學(xué)習入門筆記(十八):卷積神經(jīng)網(wǎng)絡(luò)(一)
- 深度學(xué)習入門筆記(十九):卷積神經(jīng)網(wǎng)絡(luò)(二)
- 深度學(xué)習入門筆記(二十):經(jīng)典神經(jīng)網(wǎng)絡(luò)(LeNet-5、AlexNet和VGGNet)
參考文章
- 吳恩達——《神經(jīng)網(wǎng)絡(luò)和深度學(xué)習》視頻課程
總結(jié)
以上是生活随笔為你收集整理的深度学习入门笔记(六):浅层神经网络的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 广告付费方式介绍
- 下一篇: 深度学习入门笔记(二):神经网络基础