轉自: https://www.leiphone.com/news/201703/3qMp45aQtbxTdzmK.htmlaphp
https://blog.csdn.net/shuzfan/article/details/51338178 [原理推導]html
深度學習模型訓練的過程本質是對weight(即參數 W)進行更新,這須要每一個參數有相應的初始值。有人可能會說:「參數初始化有什麼難點?直接將全部weight初始化爲0或者初始化爲隨機數!」對一些簡單的機器學習模型,或當optimization function是convex function時,這些簡單的方法確實有效。git
然而對於深度學習而言,非線性函數被瘋狂疊加,產生如本文題圖所示的non-convex function,如何選擇參數初始值便成爲一個值得探討的問題——其本質是初始參數的選擇應使得objective function便於被優化。事實上,在學術界這也是一個被actively研究的領域。github
TLDR裏已經涵蓋了本文的核心要點,下面在正文中,咱們來深刻了解一下來龍去脈。算法
答案是不可行。 這是一道送分題 哈哈!爲何將全部W初始化爲0是錯誤的呢?是由於若是全部的參數都是0,那麼全部神經元的輸出都將是相同的,那在back propagation的時候同一層內全部神經元的行爲也是相同的 --- gradient相同,weight update也相同。這顯然是一個不可接受的結果。網絡
pre-trainingdom
pre-training是早期訓練神經網絡的有效初始化方法,一個便於理解的例子是先使用greedy layerwise auto-encoder作unsupervised pre-training,而後再作fine-tuning。具體過程能夠參見UFLDL的一個tutorial,由於這不是本文重點,就在這裏簡略的說一下:iphone
pre-training階段,將神經網絡中的每一層取出,構造一個auto-encoder作訓練,使得輸入層和輸出層保持一致。在這一過程當中,參數得以更新,造成初始值機器學習
fine-tuning階段,將pre-train過的每一層放回神經網絡,利用pre-train階段獲得的參數初始值和訓練數據對模型進行總體調整。在這一過程當中,參數進一步被更新,造成最終模型。函數
隨着數據量的增長以及activation function (參見個人另外一篇文章) 的發展,pre-training的概念已經漸漸發生變化。目前,從零開始訓練神經網絡時咱們也不多采用auto-encoder進行pre-training,而是直奔主題作模型訓練。不想從零開始訓練神經網絡時,咱們每每選擇一個已經訓練好的在任務A上的模型(稱爲pre-trained model),將其放在任務B上作模型調整(稱爲fine-tuning)。
random initialization
隨機初始化是不少人目前常用的方法,然而這是有弊端的,一旦隨機分佈選擇不當,就會致使網絡優化陷入困境。下面舉幾個例子。
核心代碼見下方,完整代碼請參見個人Github。
這裏咱們建立了一個10層的神經網絡,非線性變換爲tanh,每一層的參數都是隨機正態分佈,均值爲0,標準差爲0.01。下圖給出了每一層輸出值分佈的直方圖。
隨着層數的增長,咱們看到輸出值迅速向0靠攏,在後幾層中,幾乎全部的輸出值 x 都很接近0!回憶優化神經網絡的back propagation算法,根據鏈式法則,gradient等於當前函數的gradient乘之後一層的gradient,這意味着輸出值 x 是計算gradient中的乘法因子,直接致使gradient很小,使得參數難以被更新!
讓咱們將初始值調大一些:
均值仍然爲0,標準差如今變爲1,下圖是每一層輸出值分佈的直方圖:
幾乎全部的值集中在-1或1附近,神經元saturated了!注意到tanh在-1和1附近的gradient都接近0,這一樣致使了gradient過小,參數難以被更新。
Xavier initialization
原理:https://www.jianshu.com/p/4e53d3c604f6 自編碼器參數初始化方法-Xavier initialization
Xavier initialization能夠解決上面的問題!其初始化方式也並不複雜。Xavier初始化的基本思想是保持輸入和輸出的方差一致,這樣就避免了全部輸出值都趨向於0。注意,爲了問題的簡便,Xavier初始化的推導過程是基於線性函數的,可是它在一些非線性神經元中也頗有效。讓咱們試一下:
Woohoo!輸出值在不少層以後依然保持着良好的分佈,這頗有利於咱們優化神經網絡!以前談到Xavier initialization是在線性函數上推導得出,這說明它對非線性函數並不具備普適性,因此這個例子僅僅說明它對tanh頗有效,那麼對於目前最經常使用的ReLU神經元呢(關於不一樣非線性神經元的比較請參考這裏)?繼續作一下實驗:
前面看起來還不錯,後面的趨勢倒是愈來愈接近0。幸運的是,He initialization能夠用來解決ReLU初始化的問題。
He initialization
He initialization的思想是:在ReLU網絡中,假定每一層有一半的神經元被激活,另外一半爲0,因此,要保持variance不變,只須要在Xavier的基礎上再除以2:
看起來效果很是好,推薦在ReLU網絡中使用!
Batch Normalization是一種巧妙而粗暴的方法來削弱bad initialization的影響,其基本思想是:If you want it, just make it!
咱們想要的是在非線性activation以前,輸出值應該有比較好的分佈(例如高斯分佈),以便於back propagation時計算gradient,更新weight。Batch Normalization將輸出值強行作一次Gaussian Normalization和線性變換:
Batch Normalization中全部的操做都是平滑可導,這使得back propagation能夠有效運行並學到相應的參數γ,β。須要注意的一點是Batch Normalization在training和testing時行爲有所差異。Training時μβ和σβ由當前batch計算得出;在Testing時μβ和σβ應使用Training時保存的均值或相似的通過處理的值,而不是由當前batch計算。
隨機初始化,無Batch Normalization:
隨機初始化,有Batch Normalization:
很容易看到,Batch Normalization的效果很是好,推薦使用!