1,概述
神經網絡中的權值初始化方法有很多,但是這些方法的設計也是遵循一些邏輯的,並且也有自己的適用場景。首先我們假定輸入的每個特征是服從均值為0,方差為1的分布(一般輸入到神經網絡的數據都是要做歸一化的,就是為了達到這個條件)。
為了使網絡中的信息更好的傳遞,每一層的特征的方差應該盡可能相等,如果保證這個特征的方差是相等的呢。我們可以從初始化的權重值入手。
首先來做一個公式推導:
$var(s) = var(\sum_i^n w_i x_i)$
$var(s) = \sum_i^n var(w_i x_i)$
$var(s) = \sum_i^n E(w_i^2) E(x_i^2) - (E(x_i))^2 (E(w_i))^2$
$var(s) = \sum_i^n (E(w_i))^2 var(x_i) + (E(x_i))^2 var(w_i) + var(x_i) var(w_i)$
在這里假定了x的均值為0,對於初始化的權重通常均值也是選擇0,因此上面的式子可以轉換成
$var(s) = \sum_i^n var(x_i) var(w_i)$
又因為x中每個特征我們都假定方差為1,因此上面的式子可以改寫成
$var(s) = n * var(w)$
現在要使得$var(s) = 1$,則有
$n * var(w) = 1$。
$var(w) = \frac{1}{n}$。
為了確保量綱和期望一致,我們將方差轉換成標准差,因此要確保標准差為$\frac{1}{\sqrt{n}}$
2,初始化方法
現在我們來看看每種方法初始化時我們該如何設置方差能保證輸入的分布狀態不變。
1)均勻分布
對於均勻分布$U (a, b)$,其期望和方差分別為$E(x) = \frac{(a+b)}{2}, D(x) = \frac{(b-a)^2}{12}$。
假定均勻分布為$(-\frac{1}{\sqrt{d}},\frac{1}{\sqrt{d}})$,在這里$d$為神經元的個數,則有期望和方差為:
$E(x) = 0, D(x) = \frac{1}{3d}$
代入到$var(s) = n * var(w)$中,可以得到:
$var(s) = \frac{1}{3}$,因此為了保證最終的方差為1,因此方差需要乘以3,標准差則需要乘以$\sqrt{3}$。因此一般均勻分布的初始化值可以選擇$(-\sqrt{\frac{3}{d}},\sqrt{\frac{3}{d}})$。
在xavier uniform init(glorot uniform),也就是 tf.glorot_uniform_initializer()方法中初始化值為$(-\sqrt{\frac{6}{(d_{in}+d_{out})}},\sqrt{\frac{6}{d_{in}+d_{out}}})$。在一個二維矩陣中$d_{in}, d_{out}$分別表示矩陣的第一個維度和第二個維度。
見下面一個例子,對於tf.glorot_uniform_initializer()方法:
可以看到經過一層神經網絡之后,x的期望和方差基本不變。對於均勻分布tf.random_uniform_initializer(),當我們將參數初始化為$(-\sqrt{\frac{3}{d}},\sqrt{\frac{3}{d}})$。其結果如下:
2)正態分布
正態分布會直接給出期望和標准差,所以這個不用多說。為了保證$var(s) = 1$,我們需要讓$var(w) = \frac{1}{d}$,則標准差為$\sqrt{\frac{1}{d}}$。
tf.random_normal_initializer(),我們將其標准差設置為$\sqrt{\frac{1}{d}}$。結果如下:
xavier normal init(glorot normal),也就是tf.glorot_normal_initializer(),其標准差為$\sqrt{\frac{2}{(d_{in} + d_{out})}}$,其結果如下:
3)常數初始化
常數初始化時期望為常數值n,方差為0。
tf.zeros_initializer(),以0初始化會導致輸出x為0。
tf.ones_initializer(),以1初始化方差會很大
tf.constant_initializer(),同上
3,引入激活函數
上面都是在線性運算的情況下的結果,但實際應用中都是要引入激活函數的,這樣神經網絡才具有更強的表達能力。如果引入激活函數會怎么樣?
為了觀看效果,我們將網絡層數設置為100層,權重初始化采用tf.glorot_normal_initializer()。
不加激活函數時:
可以看到不加激活函數,方差即使在100層時也基本保持不變。
引入tanh函數,
結果如上,方差會減小到0.005,因此在深層網絡中引入歸一化層確實是很重要的。
引入relu函數:
上面的結果很顯然relu函數並不適用tf.glorot_normal_initializer()。對於relu激活函數時,正態分布的標准差通常為$\sqrt{\frac{2}{d}}$,均勻分布通常為$(-\sqrt{\frac{6}{d}},\sqrt{\frac{6}{d}})$。因此更換下初始化參數,結果如下
上面看結果就好很多了,方差在100層的輸出為0.1,結果是比tanh要好的,此外這里的期望不再接近0,因為relu函數就是不像tanh那樣關於0對稱的。
另外我還發現一個奇怪的事情,暫時無法解釋,可以給大家看下結果:
當我們直接用tf.random_normal_initializer()初始化時,此時方差為1。
不引入激活函數。
100層后得到的期望和方差都為nan,應該是發生爆炸了。
引入tanh函數:
100層后竟然能保持方差為1。
relu激活函數:
期望和方差均為0。
從上面的結果看好像在用tanh做激活函數時,可以直接將參數用0,1的正態分布初始化。
4,初始化的隨機性
在實踐中還發現一個問題,就是參數的大小也會影響最終的結果,以relu激活函數為例。為了方便計算,x和w的維度一致
所有維度為512,兩次得到的結果差異比較大:
其實這個也好理解,本身x和w都是隨機初始化的,雖然分布是一樣的,但是具體的值並不一樣,最終的結果也不一樣,所以說即使同樣的分布初始化,有時候得到的結果也會有所差異,這個差異可能是收斂的速度,也可能是最終的結果等等。
參考文獻: