參數初始化

轉自:http://blog.csdn.net/u012526120/article/details/49153683

0. 引言

主成分分析與白化一節中介紹瞭如何對輸入數據進行預處理,在這節中介紹與之類似的另一個問題,參數初始化(Weight Initialization)。

在模型訓練之初,我們不知道參數的具體分佈,然而如果數據經過了合理的歸一化(normalization)處理後,對於參數的合理猜測是其中一半是正的,另一半是負的。然後我們想是不是把參數都初始化爲0會是比較好的初始化?這樣做其實會帶來一個問題,經過正向傳播和反向傳播後,參數的不同維度之間經過相同的更新,迭代的結果是不同維度的參數是一樣的,嚴重地影響了模型的性能。

1. 小的隨機數

我們仍然想要參數接近於0,又不是絕對的0,一種可行的做法是將參數初始化爲小的隨機數,這樣做可以打破對稱性(symmetry breaking)。python代碼如下:

nn_input_dim = 2
nn_hdim = 3
W = 0.001* np.random.randn(nn_input_dim,nn_hdim)
  • 1
  • 2
  • 3

其中randn從均值爲0,標準差是1的高斯分佈中取樣,這樣,參數的每個維度來自一個多維的高斯分佈。需要注意的是參數初始值不能取得太小,因爲小的參數在反向傳播時會導致小的梯度,對於深度網絡來說,也會產生梯度彌散問題,降低參數的收斂速度。

2. 將方差乘以1/sqrt(n)

參數隨機初始化爲一個小的隨機數存在一個問題:一個神經元輸出的方差會隨着輸入神經元數量的增多而變大。對於有n個輸入單元的神經元來說,考慮χ2分佈,每個輸入的方差是1/n時,總的方差是1,因此,我們對每個輸入的標準差乘以1/sqrt(n),每個神經元的參數初始化代碼爲:

w = np.random.randn(n) / sqrt(n)
  • 1

其中n爲這個神經元輸入的個數。這樣可以確保神經元的輸出有相同的分佈,提高訓練的收斂速度。

將上面初始化方案推廣到網絡的一層,對於神經網絡的第一層可以這樣初始化:

nn_input_dim = 2
nn_hdim = 3
w = np.random.randn(nn_input_dim,nn_hdim) / sqrt(nn_input_dim)
  • 1
  • 2
  • 3

Understanding the difficulty of training deep feedforward neural networks文章中給出一個類似的初始化方案:

nn_input_dim = 2
nn_hdim = 3
w = np.random.randn(nn_input_dim,nn_hdim) / sqrt(nn_input_dim+nn_hdim)
  • 1
  • 2
  • 3

對於Relu激活神經元,Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification認爲每個神經元的方差應該爲:2/n,其初始化方案:

nn_input_dim = 2
nn_hdim = 3
w = np.random.randn(nn_input_dim,nn_hdim) / sqrt(2.0/nn_input_dim)
  • 1
  • 2
  • 3

3. 偏置項的初始化

通常偏置項(bias)初始化爲0:

nn_input_dim = 2
nn_hdim = 3
b1 = np.zeros((1, nn_hdim))
  • 1
  • 2
  • 3

對於Relu激活神經元來說,可以將偏置項初始化爲一個小的常數,比如0.01,但不確定這樣做是否提高收斂的表現,在實際應用中,也常初始化爲0。

參考內容: 
1. http://cs231n.stanford.edu/syllabus.html


發佈了48 篇原創文章 · 獲贊 43 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章