深度学习入门笔记(七):深层神经网络
歡迎關注WX公眾號:【程序員管小亮】
專欄——深度學習入門筆記
聲明
1)該文章整理自網上的大牛和機器學習專家無私奉獻的資料,具體引用的資料請看參考文獻。
2)本文僅供學術交流,非商用。所以每一部分具體的參考資料并沒有詳細對應。如果某部分不小心侵犯了大家的利益,還望海涵,并聯系博主刪除。
3)博主才疏學淺,文中如有不當之處,請各位指出,共同進步,謝謝。
4)此屬于第一版本,若有錯誤,還需繼續修正與增刪。還望大家多多指點。大家都共享一點點,一起為祖國科研的推進添磚加瓦。
文章目錄
- 歡迎關注WX公眾號:【程序員管小亮】
- 專欄——深度學習入門筆記
- 聲明
- 深度學習入門筆記(七):深層神經網絡
- 1、深層神經網絡
- 2、前向傳播和反向傳播
- 3、核對矩陣的維數
- 4、參數VS超參數
- 5、調參
- 推薦閱讀
- 參考文章
深度學習入門筆記(七):深層神經網絡
1、深層神經網絡
目前為止,學習了只有一個單獨隱藏層的神經網絡(深度學習入門筆記(六):淺層神經網絡)的正向傳播和反向傳播,還有邏輯回歸(深度學習入門筆記(二):神經網絡基礎),并且還學到了向量化(深度學習入門筆記(四):向量化),這在隨機初始化權重(深度學習入門筆記(六):淺層神經網絡)時是很重要。
這一次所要做的是把這些理念集合起來,就可以組建并執行一個術語你自己的 深度神經網絡,有沒有一種樂高積木的感覺呢?
簡單復習下前面的內容:
邏輯回歸,下圖左邊。一個隱藏層的神經網絡,下圖右邊。
神經網絡層數的定義方式:從左到右,由隱藏層開始,定義為第一層,比如上邊右圖,x1{x}_{1}x1?、x2{x}_{2}x2?、x3{x}_{3}x3?這一層右邊的隱藏層是第一層,所以淺層神經網絡是兩層網絡。
由此類推,下圖左邊是兩個隱藏層的三層神經網絡,右邊是五個隱藏層的六層神經網絡。(這個層數叫法是存在不同的結論的,最簡單且不出錯的方法是說隱藏層的層數,比如左邊的是兩個隱藏層,右邊的是五個隱藏層)
所以,嚴格意義上來說,邏輯回歸也是一個一層的神經網絡,而上邊右圖一個深得多的模型,是一個六層的神經網絡。我們所說的淺層神經網絡和深層神經網絡中的淺與深,僅僅是指一種程度,也就是相對而言的。
小結一下: 嚴格的說,有一個隱藏層的神經網絡,就是一個兩層神經網絡。記住算神經網絡的層數時,不算輸入層,只算隱藏層和輸出層。
2、前向傳播和反向傳播
深度神經網絡的每一層都有 前向傳播 步驟以及一個相反的 反向傳播 步驟,那么這兩個步驟是如何實現的呢?
先說前向傳播,lll 表示層數,網絡的輸入 a[l?1]{a}^{[l-1]}a[l?1],網絡的輸出是 a[l]{a}^{[l]}a[l],網絡的緩存為 z[l]{z}^{[l]}z[l];從實現的角度來說可以緩存下 w[l]{w}^{[l]}w[l] 和 b[l]{b}^{[l]}b[l],這樣更容易在不同的環節中調用函數。
所以前向傳播的步驟可以寫成:
(1)z[l]=W[l]?a[l?1]+b[l]{z}^{[l]}={W}^{[l]}\cdot{a}^{[l-1]}+{b}^{[l]}z[l]=W[l]?a[l?1]+b[l]
(2)a[l]=g[l](z[l]){{a}^{[l]}}={{g}^{[l]}}\left( {{z}^{[l]}}\right)a[l]=g[l](z[l])
向量化(深度學習入門筆記(四):向量化)整個過程之后,可以寫成:
(1)z[l]=W[l]?A[l?1]+b[l]{z}^{[l]}={W}^{[l]}\cdot {A}^{[l-1]}+{b}^{[l]}z[l]=W[l]?A[l?1]+b[l]
(2)A[l]=g[l](Z[l]){A}^{[l]}={g}^{[l]}({Z}^{[l]})A[l]=g[l](Z[l])
前向傳播需要喂入 A[0]{A}^{[0]}A[0] 也就是 XXX,即輸入特征,來進行初始化,初始化的是第一層的輸入值。a[0]{a}^{[0]}a[0] 對應于一個訓練樣本中的輸入特征,而 A[0]{{A}^{[0]}}A[0] 對應于一整個訓練樣本中的輸入特征,所以這就是這條鏈的第一個前向函數的輸入,重復這個步驟就可以從左到右計算前向傳播。
再講反向傳播,具體的原理和推導可以看這個博客——深度學習100問之深入理解Back Propagation(反向傳播),輸入為 da[l]{{da}^{[l]}}da[l],輸出為 da[l?1]{{da}^{[l-1]}}da[l?1],dw[l]{{dw}^{[l]}}dw[l], db[l]{{db}^{[l]}}db[l]。
所以反向傳播的步驟可以寫成:
(1)dz[l]=da[l]?g[l]′(z[l])d{{z}^{[l]}}=d{{a}^{[l]}}*{{g}^{[l]}}'( {{z}^{[l]}})dz[l]=da[l]?g[l]′(z[l])
(2)dw[l]=dz[l]?a[l?1]d{{w}^{[l]}}=d{{z}^{[l]}}\cdot{{a}^{[l-1]}}~dw[l]=dz[l]?a[l?1]?
(3)db[l]=dz[l]d{{b}^{[l]}}=d{{z}^{[l]}}~~db[l]=dz[l]??
(4)da[l?1]=w[l]T?dz[l]d{{a}^{[l-1]}}={{w}^{\left[ l \right]T}}\cdot {{dz}^{[l]}}da[l?1]=w[l]T?dz[l]
(5)dz[l]=w[l+1]Tdz[l+1]?g[l]′(z[l])d{{z}^{[l]}}={{w}^{[l+1]T}}d{{z}^{[l+1]}}\cdot \text{ }{{g}^{[l]}}'( {{z}^{[l]}})~dz[l]=w[l+1]Tdz[l+1]??g[l]′(z[l])?
式子(5)由式子(4)帶入式子(1)得到,前四個式子就可實現反向傳播。
向量化實現過程可以寫成:
(6)dZ[l]=dA[l]?g[l]′(Z[l])d{{Z}^{[l]}}=d{{A}^{[l]}}*{{g}^{\left[ l \right]}}'\left({{Z}^{[l]}} \right)~~dZ[l]=dA[l]?g[l]′(Z[l])??
(7)dW[l]=1mdZ[l]?A[l?1]Td{{W}^{[l]}}=\frac{1}{m}\text{}d{{Z}^{[l]}}\cdot {{A}^{\left[ l-1 \right]T}}dW[l]=m1?dZ[l]?A[l?1]T
(8)db[l]=1mnp.sum(dz[l],axis=1,keepdims=True)d{{b}^{[l]}}=\frac{1}{m}\text{ }np.sum(d{{z}^{[l]}},axis=1,keepdims=True)db[l]=m1??np.sum(dz[l],axis=1,keepdims=True)
(9)dA[l?1]=W[l]T?dZ[l]d{{A}^{[l-1]}}={{W}^{\left[ l \right]T}}\cdot d{{Z}^{[l]}}dA[l?1]=W[l]T?dZ[l]
小結一下:
吳恩達老師手稿如下,舉一個簡單的三層(兩層隱藏層)神經網絡。
- 前向傳播:第一層可能有一個 ReLU 激活函數,第二層為另一個 ReLU 激活函數,第三層(輸出層)可能是 sigmoid 函數(如果做二分類的話),輸出值為 y^\hat yy^?,用來和 yyy 計算損失 LLL;
- 反向傳播:向后迭代,進行反向傳播求導來求 dw[3]{{dw}^{[3]}}dw[3],db[3]{{db}^{[3]}}db[3] ,dw[2]{{dw}^{[2]}}dw[2] ,db[2]{{db}^{[2]}}db[2] ,dw[1]{{dw}^{[1]}}dw[1] ,db[1]{{db}^{[1]}}db[1]。在計算的時候,緩存會把 z[1]{{z}^{[1]}}z[1] z[2]{{z}^{[2]}}z[2]z[3]{{z}^{[3]}}z[3] 傳遞過來,然后回傳 da[2]{{da}^{[2]}}da[2],da[1]{{da}^{[1]}}da[1] ,da[0]{{da}^{[0]}}da[0];
- 前向遞歸:用輸入數據 xxx 來初始化,那么反向遞歸(使用 Logistic 回歸做二分類),對 A[l]{{A}^{[l]}}A[l] 求導。
3、核對矩陣的維數
當實現深度神經網絡的時候,其中一個最常用的也是最好用的檢查代碼是否有錯的方法,就是拿出一張紙過一遍算法中矩陣的維數。或者有一個笨方法就是,一直運行,一直 debugdebugdebug,不過這樣太低效了。
向量化前,變量的維度如下:
-
www 的維度是(下一層的維數,前一層的維數),即 w[l]{{w}^{[l]}}w[l]:(n[l]{{n}^{[l]}}n[l],n[l?1]{{n}^{[l-1]}}n[l?1]);
-
bbb 的維度是(下一層的維數,1),即 b[l]{{b}^{[l]}}b[l]:(n[l],1){{n}^{[l]}},1)n[l],1);
-
zzz 和 aaa 的維度是(下一層的維數,1),即 z[l]{{z}^{[l]}}z[l],a[l]{{a}^{[l]}}a[l]: (n[l],1)({{n}^{[l]}},1)(n[l],1);
-
dw[l]{{dw}^{[l]}}dw[l] 和 w[l]{{w}^{[l]}}w[l] 維度相同;
-
db[l]{{db}^{[l]}}db[l] 和 b[l]{{b}^{[l]}}b[l] 維度相同;
www 和 bbb 向量化維度不變,但 zzz,aaa 以及 xxx 的維度會向量化后發生變化。
向量化后:
-
Z[l]{Z}^{[l]}Z[l] 可以看成由每一個單獨的 z[l]{z}^{[l]}z[l] 疊加而得到,Z[l]=(z[l][1],z[l][2],z[l][3],…,z[l][m]){Z}^{[l]}=({{z}^{[l][1]}},{{z}^{[l][2]}},{{z}^{[l][3]}},…,{{z}^{[l][m]}})Z[l]=(z[l][1],z[l][2],z[l][3],…,z[l][m]),mmm 為訓練集大小,所以 Z[l]{Z}^{[l]}Z[l] 的維度不再是 (n[l],1)({{n}^{[l]}},1)(n[l],1),而是 (n[l],m)({{n}^{[l]}},m)(n[l],m)。
-
A[l]{A}^{[l]}A[l] 和 Z[l]{Z}^{[l]}Z[l] 一樣,維度變成 (n[l],m)({n}^{[l]},m)(n[l],m),其中 A[0]=X=(n[l],m){A}^{[0]} = X =({n}^{[l]},m)A[0]=X=(n[l],m)
到這里,一個深層神經網絡就設計完成了,理論知識也大概講述完畢了。
4、參數VS超參數
想要你的深度神經網絡起很好的效果,維度的準確性是最基本的東西,代碼不出錯也是必須的一步,除了這些以外,還需要規劃好參數以及超參數。
- 什么是超參數?
定義:在機器學習的上下文中,超參數是在開始學習過程之前設置值的參數,而不是通過訓練得到的參數數據。通常情況下,需要對超參數進行優化,給學習機選擇一組最優超參數,以提高學習的性能和效果。
- 超參數和參數的區別是什么?
參數是從數據中自動估計的,而超參數是手動設置的。
- 超參數是如何影響神經網絡的?
超參數,實際上控制了最后的參數 WWW 和 bbb 的值,影響了模型。
- 超參數有哪些呢?
比如算法中的 learning rate(學習率)、iterations(梯度下降法循環的數量)、LLL(隱藏層數目)、n[l]{{n}^{[l]}}n[l](隱藏層單元數目)、choice of activation function(激活函數的選擇)等等,這些都需要你來設置。
輸了一些比較熟悉的超參數,你可能有點感覺了,但是實際上深度學習有很多不同的超參數,之后也會介紹一些其他的超參數,如 momentum(動量)、mini batch size(批大小)、regularization parameters(正則化參數)等等。
- 如何尋找超參數的最優值?
其實這個過程和人類的思維過程類似,為什么這么說呢?人類在大腦風暴的過程中,是先有 Idea,然后 Realize,最后 Experiment。不過深度學習中,是 Idea—Code—Experiment—Idea 這個大循環,Realize 是用 Code 替換的,再嘗試各種不同的參數,實現模型并觀察是否成功,然后再迭代。
深度學習的應用領域,是個很經驗性的過程:通常有個想法(Idea),比如你可能大致知道一個別人用的最好的學習率值,可能說 a=0.0001(10?4)a=0.0001(10^{-4})a=0.0001(10?4) 效果最好,我在做圖像處理實驗的時候,真的發現這個學習率很不錯,建議你也可以嘗試一下。
那么我會想說,先試試看,然后可以實際更改一下,再訓練一下,最后看看效果如何。
基于這個嘗試的結果,你會發現,學習率設定再提高到 0.0005(5?10?4)0.0005(5*10^{-4})0.0005(5?10?4) 可能會比較好。
但是你又不確定什么值是最好的,這個時候大可以先試試你猜想的新學習率 aaa 到底怎么樣,更改參數重新實驗,再看看損失函數 JJJ 的值有沒有下降?
如果沒有的話,你可以試一試再大一些的值,如果這個時候,你發現損失函數的值不但沒減少,反而增加并且發散了。恭喜你,你失敗了2333。
然后可能需要試試其他的一些數,再改再看實驗結果,看損失函數是否下降的很快或者收斂到在更高的位置?
你可能嘗試不同的 aaa 并觀察損失函數 JJJ 這么變了,試試一組值,然后可能損失函數變成這樣,這個 aaa 值會加快學習過程,并且收斂在更低的損失函數值上,然后敲定,我就用這個 aaa 值了。
再或者還可能你發現,固定學習率并不能滿足你的要求,這個時候你需要學習率是變化的,比如學習率衰減——深度學習100問之學習率衰減。
可能有的小伙伴就會說了,這也太麻煩了吧,這不是一直試試試的???這也是工作量的一部分,所以深度學習也被人吐槽說是一個經驗主義學科。。。應用深度學習領域,一個很大程度基于經驗的過程,憑經驗的過程通俗來說,就是試直到你找到合適的數值。
只能說調參是門玄學,好與壞不是你我說了算的。
之前在知乎上看到過一個文章說可以使用算法調參,但是我還沒接觸過。。。論文:Hyperparameter Optimization: A Spectral Approach,有興趣的小伙伴可以看一看,這可是頂端科學技術了。
5、調參
一個近來深度學習的影響是,它可以用于解決很多問題,從 計算機視覺 到 語音識別,到 自然語言處理,到很多 結構化的數據應用,比如 網絡廣告 或是 網頁搜索 或 產品推薦 等等。
很多領域的研究人員,對這些領域中的一個問題進行研究,嘗試了不同的參數設置,有時候這種設置超參數的直覺是可以推廣的,但有時又不會。所以剛開始應用新問題的人們,去試一定范圍的值看看結果如何(比如我們實驗室的方向,就是近兩年才開始結合深度學習作為方法論,進行問題的研究與解決)。
然后是其他情況,比如你已經用了很久的模型進行問題的解決,可能你在做網絡廣告應用,也可能是其他的,在開發的過程中,很有可能學習率的最優數值或是其他超參數的最優值是會變的!!!所以即使每天都在用當前最優的參數調試系統,你還是會發現,最優值過一年就會變化,這可能是很多原因導致的,其中一種可能就是因為電腦的基礎設施,CPU 或是 GPU 可能會變化很大,比如你是一個 GPU,那么 GPU 的型號?(以N卡的天梯為例)
(圖源:http://www.mydrivers.com/zhuanti/tianti/gpu/)
所以之前的經驗規律可能每幾個月就會變,如果你的工作臺一直不變,那么數據也可能會有變化,再或者你的網絡結構也會有微調,等等。所以要經常試試不同的超參數,勤于檢驗結果,看看有沒有更好的超參數數值,相信慢慢的,你會得到設定超參數的直覺,知道你的問題最好用什么數值。😃
這可能的確是深度學習比較讓人不滿的一部分,也就是你必須嘗試很多次不同可能性。但參數設定這個領域,深度學習研究還在進步中,所以可能過段時間就會有更好的方法決定超參數的值,也很有可能由于 CPU、GPU、網絡和數據都在變化,這樣的指南可能只會在一段時間內起作用,只有不斷嘗試,并且嘗試保留交叉檢驗或類似的檢驗方法,然后挑一個對你的問題效果比較好的數值,這種方法才是現在最好的解決辦法。
近年來,受深度學習影響或者可以稱之為 沖擊,很多領域發生了變化,從計算機視覺到語音識別到自然語言處理到很多結構化的數據應用,比如網絡廣告、網頁搜索、產品推薦等等;有些同一領域設置超參數的直覺可以推廣,但有時又不可以,特別是那些剛開始研究新問題的人們應該去嘗試一定范圍內的結果如何,甚至那些用了很久的模型得學習率或是其他超參數的最優值也有可能會改變。我們能做的只有以不變應萬變!!!這也是這個領域的項目經驗或者經歷更為重要的原因之一。
最后,記住一條經驗規律:經常試試不同的超參數,勤于檢查結果,看看有沒有更好的超參數取值,你將會得到設定超參數的直覺。
推薦閱讀
- 深度學習入門筆記(一):深度學習引言
- 深度學習入門筆記(二):神經網絡基礎
- 深度學習入門筆記(三):求導和計算圖
- 深度學習入門筆記(四):向量化
- 深度學習入門筆記(五):神經網絡的編程基礎
- 深度學習入門筆記(六):淺層神經網絡
- 深度學習入門筆記(七):深層神經網絡
- 深度學習入門筆記(八):深層網絡的原理
- 深度學習入門筆記(九):深度學習實踐
- 深度學習入門筆記(十):正則化
- 深度學習入門筆記(十一):權重初始化
- 深度學習入門筆記(十二):深度學習數據讀取
- 深度學習入門筆記(十三):批歸一化(Batch Normalization)
- 深度學習入門筆記(十四):Softmax
- 深度學習入門筆記(十五):深度學習框架(TensorFlow和Pytorch之爭)
- 深度學習入門筆記(十六):計算機視覺之邊緣檢測
- 深度學習入門筆記(十七):深度學習的極限在哪?
- 深度學習入門筆記(十八):卷積神經網絡(一)
- 深度學習入門筆記(十九):卷積神經網絡(二)
- 深度學習入門筆記(二十):經典神經網絡(LeNet-5、AlexNet和VGGNet)
參考文章
- 吳恩達——《神經網絡和深度學習》視頻課程
總結
以上是生活随笔為你收集整理的深度学习入门笔记(七):深层神经网络的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 标签体系应用及设计思路
- 下一篇: 金博科技果园分销商城系统APP定制开发