深度学习入门笔记(十一):权重初始化
歡迎關注WX公眾號:【程序員管小亮】
專欄——深度學習入門筆記
聲明
1)該文章整理自網上的大牛和機器學習專家無私奉獻的資料,具體引用的資料請看參考文獻。
2)本文僅供學術交流,非商用。所以每一部分具體的參考資料并沒有詳細對應。如果某部分不小心侵犯了大家的利益,還望海涵,并聯系博主刪除。
3)博主才疏學淺,文中如有不當之處,請各位指出,共同進步,謝謝。
4)此屬于第一版本,若有錯誤,還需繼續修正與增刪。還望大家多多指點。大家都共享一點點,一起為祖國科研的推進添磚加瓦。
文章目錄
- 歡迎關注WX公眾號:【程序員管小亮】
- 專欄——深度學習入門筆記
- 聲明
- 深度學習入門筆記(十一):深入理解梯度
- 1、梯度消失/梯度爆炸
- 2、神經網絡的權重初始化
- 1_對w隨機初始化
- 2_Xavier初始化
- 3_He初始化
- 3、TensorFlow實現權重初始化
- 1_常量初始化
- 2_正態分布初始化
- 3_均勻分布初始化
- 4_截斷正態分布初始化
- 5_正交矩陣初始化
- 6_Xavier初始化、He_初始化
- 4、總結
- 推薦閱讀
- 參考文章
深度學習入門筆記(十一):深入理解梯度
1、梯度消失/梯度爆炸
早些時間寫過一個博客——深度學習100問之深入理解Vanishing/Exploding Gradient(梯度消失/爆炸),感興趣的小伙伴可以看一下。
訓練神經網絡,尤其是深度神經網絡所面臨的一個問題就是 梯度消失或梯度爆炸,那么什么是 梯度消失或梯度爆炸?
其實就是訓練神經網絡時,導數或坡度 有時會變得非常大,或者非常小,甚至于以指數方式變小,這加大了訓練的難度。下面通過一個例子來詳細的講解:
假設正在訓練這樣一個 極深 的神經網絡,為了簡化問題,假設神經網絡每層只有兩個隱藏單元,但是因為 極深,所以還有很多參數,如 W[1]W^{[1]}W[1],W[2]W^{[2]}W[2],W[3]W^{[3]}W[3] 等等,直到 W[l]W^{[l]}W[l]。為了簡單起見,假設使用線性激活函數 g(z)=zg(z)=zg(z)=z,同時忽略偏置 bbb,即假設 b[l]b^{[l]}b[l]=0,這樣的話,輸出:
y=W[l]W[L?1]W[L?2]…W[3]W[2]W[1]xy=W^{[l]}W^{[L -1]}W^{[L - 2]}\ldots W^{[3]}W^{[2]}W^{[1]}xy=W[l]W[L?1]W[L?2]…W[3]W[2]W[1]x
如果你是數學帕金森患者或者想考驗我的數學水平,那么就簡單說一下推導過程:
根據前向傳播中的公式 W[1]x=z[1]W^{[1]} x = z^{[1]}W[1]x=z[1],又因為 b=0b=0b=0,所以 z[1]=W[1]xz^{[1]} =W^{[1]} xz[1]=W[1]x,a[1]=g(z[1])a^{[1]} = g(z^{[1]})a[1]=g(z[1]),而由于使用的事線性激活函數 g(z)=zg(z)=zg(z)=z,所以第一項 W[1]x=a[1]W^{[1]} x = a^{[1]}W[1]x=a[1],通過推理。。。得出 W[2]W[1]x=a[2]W^{[2]}W^{[1]}x =a^{[2]}W[2]W[1]x=a[2],因為 a[2]=g(z[2])=g(W[2]a[1])a^{[2]} = g(z^{[2]})=g(W^{[2]}a^{[1]})a[2]=g(z[2])=g(W[2]a[1]),第一項 W[1]x=a[1]W^{[1]} x = a^{[1]}W[1]x=a[1],故可以用 W[1]xW^{[1]}xW[1]x 替換 a[1]a^{[1]}a[1],所以 a[2]=g(W[2]W[1]x)=W[2]W[1]xa^{[2]}=g(W^{[2]}W^{[1]}x)=W^{[2]}W^{[1]}xa[2]=g(W[2]W[1]x)=W[2]W[1]x。依次類推,可得 a[l]=W[l]W[L?1]W[L?2]…W[3]W[2]W[1]xa^{[l]}=W^{[l]}W^{[L -1]}W^{[L - 2]}\ldots W^{[3]}W^{[2]}W^{[1]}xa[l]=W[l]W[L?1]W[L?2]…W[3]W[2]W[1]x。
吳恩達老師手稿如下:
假設每個權重矩陣 W[l]=[1.5001.5]W^{[l]} = \begin{bmatrix} 1.5 & 0 \\0 & 1.5 \\\end{bmatrix}W[l]=[1.50?01.5?],從技術上來講,最后一項有不同維度,可能它就是余下的權重矩陣,比如這里就是(None,1),所以根據上面推導的公式,可以得到 y=W[L][1.5001.5](L?1)xy= W^{[L]}\begin{bmatrix} 1.5 & 0 \\ 0 & 1.5 \\\end{bmatrix}^{(L -1)}xy=W[L][1.50?01.5?](L?1)x。又因為 [1.5001.5]=1.5?[1001]\begin{bmatrix} 1.5 & 0 \\ 0 & 1.5 \\\end{bmatrix} = 1.5 * \begin{bmatrix} 1 & 0 \\ 0 & 1 \\\end{bmatrix}[1.50?01.5?]=1.5?[10?01?],是1.5倍的單位矩陣(注意:網絡的輸出是 y^\hat yy^? 而不是 yyy),所以計算結果是 y^=1.5(L?1)x\hat{y}={1.5}^{(L-1)}xy^?=1.5(L?1)x。
?
如果對于一個深度神經網絡來說,它的 LLL 值明顯較大,那么 y^\hat{y}y^? 的值也會非常大。在數學上分析的話,實際上它就是一個指數函數,因此是呈指數級增長的。該函數的增長比率是 1.51.51.5,其實就是 1.5L1.5^L1.5L,相當于下圖中 a>1a>1a>1 的情況,是爆炸式增長的趨勢。因此對于一個深度神經網絡,輸出值將爆炸式增長。
相反的,如果權重是 0.50.50.5,即 W[l]=[0.5000.5]W^{[l]} = \begin{bmatrix} 0.5& 0 \\ 0 & 0.5 \\ \end{bmatrix}W[l]=[0.50?00.5?],這項也就變成了 0.5L{0.5}^{L}0.5L,矩陣 y=W[L][0.5000.5](L?1)xy= W^{[L]}\begin{bmatrix} 0.5 & 0 \\ 0 & 0.5 \\\end{bmatrix}^{(L - 1)}xy=W[L][0.50?00.5?](L?1)x,再次忽略 W[L]W^{[L]}W[L],因此每個矩陣都小于1,相當于上圖中 0<a<10<a<10<a<1 的情況。現在我們假設 x1x_{1}x1? 和 x2x_{2}x2? 都是1,經過激活函數的輸出將變成 (12\frac{1}{2}21?,12\frac{1}{2}21?),(14\frac{1}{4}41?,14\frac{1}{4}41?),(18\frac{1}{8}81?,18\frac{1}{8}81?)等等,直到最后一項變成 12L\frac{1}{2^{L}}2L1?,也就是指數下降的情況,因為它是與網絡層數數量 LLL 相關的函數,LLL 越大,經過激活函數的輸出越小,甚至接近于0。因此對于一個深度神經網絡,輸出值將爆炸式減少。
小結一下,直觀理解上,分兩種情況:
- 權重 W?W?W? 只比1略大一點,可能是[0.9000.9]?\begin{bmatrix}0.9 & 0 \\ 0 & 0.9 \\ \end{bmatrix}?[0.90?00.9?]?,深度神經網絡的激活函數將爆炸式增長;
- 權重 W?W?W? 只比1略小一點,可能是[1.1001.1]?\begin{bmatrix}1.1 & 0 \\ 0 & 1.1 \\ \end{bmatrix}?[1.10?01.1?]?,深度神經網絡的激活函數將爆炸式減小。
在深度神經網絡中,激活函數與 LLL 呈指數級增長或呈指數遞減,在這樣一個深度神經網絡中,如果梯度函數也與 LLL 相關的指數增長或遞減,它們的值將會變得極大或極小,從而導致訓練難度上升,尤其是梯度指數小于 LLL 時,梯度下降算法的步長會非常非常小,梯度下降算法將花費很長時間來學習。在很長一段時間內,它曾是訓練深度神經網絡的阻力,雖然有一個不能徹底解決此問題的解決方案,但是還是有一些方法可以提供幫助。
2、神經網絡的權重初始化
針對深度神經網絡產生梯度消失和梯度爆炸的問題,我們想出了一個不完整的解決方案,雖然不能徹底解決問題,卻很有用,即為神經網絡更謹慎地選擇隨機初始化參數。除此之外,初始化還對模型的收斂速度和性能有著至關重要的影響,因為說白了,神經網絡其實就是對權重參數 w 的不停迭代更新,以期達到較好的性能。
那么神經元初始化的方式有哪些?
1_對w隨機初始化
目前最常使用的就是隨機初始化權重,比如常數初始化、正態分布初始化、均勻分布初始化、截斷正態分布初始化、正交矩陣初始化等等。然而這是有弊端的,一旦隨機分布選擇不當,就會導致網絡優化陷入困境,所以很多時候是調參去解決這個問題,避免陷入局部最優,會出現損失函數不收斂等情況。
首先創建了一個10層的神經網絡,非線性變換為 tanh,每一層的參數都是隨機正態分布。
W = tf.Variable(np.random.randn(node_in, node_out))
隨著層數的增加,輸出值迅速向0靠攏,在后幾層中,幾乎所有的輸出值 x 都很接近0!根據反向傳播算法的鏈式法則,梯度等于當前函數的梯度乘以后一層的梯度,這意味著輸出值是計算梯度的一個乘法因子,輸出值接近于0將直接導致梯度很小,使得參數難以被更新。如果把初始值調大一些:W = tf.Variable(np.random.randn(node_in, node_out))。
幾乎所有的值集中在-1或1附近,神經元saturated了!注意到tanh在-1和1附近的梯度都接近0,這同樣導致了梯度太小,參數難以被更新。
2_Xavier初始化
論文地址:Understanding the difficulty of training deep feedforward neural networks
Xavier 初始化可以解決上面的問題!其初始化方式也并不復雜,保持輸入和輸出的方差一致,這樣就避免了所有輸出值都趨向于0。
W = tf.Variable(np.random.randn(node_in, node_out)) / np.sqrt(node_in)
不過在應用 RELU 激活函數時:
后面的趨勢卻是越來越接近0。。。
3_He初始化
論文地址:Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification
He 初始化的思想是:在 ReLU 網絡中,假定每一層有一半的神經元被激活,另一半為0,所以,要保持 variance 不變,只需要在 Xavier 的基礎上再除以2。
W = tf.Variable(np.random.randn(node_in,node_out)) / np.sqrt(node_in/2)
看起來效果非常好,RELU 激活函數中效果不錯。
3、TensorFlow實現權重初始化
1_常量初始化
x = tf.get_variable('x', shape, initializer=tf.constant_initializer(1))2_正態分布初始化
x = tf.get_variable('x', shape,initializer=tf.random_normal_initializer(mean=0.0,stddev=1.0,seed=None,dtype=tf.float32)) y = tf.get_variable('y', shape,initializer=tf.truncated_normal_initializer(mean=0.0,stddev=1.0,seed=None,dtype=tf.float32))3_均勻分布初始化
x = tf.get_variable('x', shape,initializer=tf.random_uniform_initializer(minval=0,maxval=10,seed=None,dtype=tf.float32)) # 或 x = tf.get_variable('x', shape,initializer=tf.uniform_unit_scaling_initializer(factor=1.0,seed=None,dtype=tf.float32))4_截斷正態分布初始化
x = tf.get_variable('x', shape,initializer=tf.truncated_normal_initializer(mean=0.0,stddev=1.0,seed=None,dtype=tf.float32))5_正交矩陣初始化
x = tf.get_variable('x', shape,initializer=tf.orthogonal_initializer(gain=1.0,seed=None,dtype=tf.float32))6_Xavier初始化、He_初始化
在上面給出了具體的代碼,還有:
tf.glorot_uniform_initializer() # 或 tf.glorot_normal_initializer()4、總結
RELU 激活函數初始化推薦使用 He 初始化,tanh 初始化推薦使用 Xavier 初始化。
不過我個人目前用的比較多的是截斷正態分布初始化,其他也都有在用,但是提升不是太明顯,需要嘗試才能確定針對不同問題時是不是能有效的提升,也可能是因為專業不是前端精密行業,還是需要斟酌。
推薦閱讀
- 深度學習入門筆記(一):深度學習引言
- 深度學習入門筆記(二):神經網絡基礎
- 深度學習入門筆記(三):求導和計算圖
- 深度學習入門筆記(四):向量化
- 深度學習入門筆記(五):神經網絡的編程基礎
- 深度學習入門筆記(六):淺層神經網絡
- 深度學習入門筆記(七):深層神經網絡
- 深度學習入門筆記(八):深層網絡的原理
- 深度學習入門筆記(九):深度學習數據處理
- 深度學習入門筆記(十):正則化
- 深度學習入門筆記(十一):權重初始化
- 深度學習入門筆記(十二):深度學習數據讀取
- 深度學習入門筆記(十三):批歸一化(Batch Normalization)
- 深度學習入門筆記(十四):Softmax
- 深度學習入門筆記(十五):深度學習框架(TensorFlow和Pytorch之爭)
- 深度學習入門筆記(十六):計算機視覺之邊緣檢測
- 深度學習入門筆記(十七):深度學習的極限在哪?
- 深度學習入門筆記(十八):卷積神經網絡(一)
- 深度學習入門筆記(十九):卷積神經網絡(二)
- 深度學習入門筆記(二十):經典神經網絡(LeNet-5、AlexNet和VGGNet)
參考文章
- 吳恩達——《神經網絡和深度學習》視頻課程
- https://zhuanlan.zhihu.com/p/25110150
總結
以上是生活随笔為你收集整理的深度学习入门笔记(十一):权重初始化的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: x86、i386、IA-32、amd64
- 下一篇: Android 广告秘籍