Lecture 6. Neural Tips and Tricks
Lecture 6主要介紹了深度學習應用的一些小技巧,例如多任務訓練、梯度檢測、正則化、多種激活函數、參數初始化、學習速率等。
多任務學習(也叫權重共享)
對比上節課我們學到的神經網絡,多任務學習就是在輸出層用softmax分類器取代標量得分。訓練方法依然採用後向傳播。
神經網絡和傳統機器學習方法的不同在於,深度學習需要同時學習詞向量和權重。
主要思想:我們在訓練多種不同NLP任務(例如NER和POS),可以共享兩個任務的詞向量和隱藏層的權重,只有輸出層的softmax權重不同。損失函數是不同任務損失函數相加,例如:
δ t o t a l = δ P O S + δ N E R \delta^{total} = \delta^{POS} + \delta^{NER} δ t o t a l = δ P O S + δ N E R
參考論文《NLP(almost from scratch, Collobert et al.2011)》
成功的神經網絡的通用步驟是這樣的:
選擇合適的網絡框架
框架:單個詞、固定窗口、詞袋、循環神經網絡、遞歸神經網絡、CNN等;
非線性神經單元
用梯度檢測器檢查實現代碼是否存在bug
參數初始化
優化技巧
檢查模型是否強大到過擬合
如果沒有過擬合,改變模型框架或者模型調大
如果過擬合,請用正則化
下面我們根據這些步驟分別介紹使用技巧。
梯度檢測
梯度檢測我們在第一次作業中用過,從導數的本質上求得參數的梯度,和我們用後向傳播計算得到的梯度對比。公式如下:
f ′ ( θ ) ≈ J ( θ ( i + ) ) − J ( θ ( i − ) ) 2 ϵ f\prime (\theta) \approx \frac{J(\theta^{(i+)}) - J(\theta^{(i-)})}{2\epsilon} f ′ ( θ ) ≈ 2 ϵ J ( θ ( i + ) ) − J ( θ ( i − ) )
其中,θ ( i + ) = θ + ϵ × e i \theta^{(i+)} = \theta + \epsilon \times e_i θ ( i + ) = θ + ϵ × e i
簡單的代碼實現爲:
old_value = x[ix]
x[ix] = old_value + h
fxh = f(x)
x[ix] = old_value
grad[ix] = (fxh - fx) / h
如果梯度檢測失敗了應該怎麼做?修改代碼確定沒有bug!
正則化
正則化前面課程提到的次數也很多,和大多數分類器一樣,神經網絡也需要避免過擬合,使得驗證集和測試集能夠獲得良好的表現。正則化後的損失函數爲:
J R = J + λ ∑ i = 1 L ∣ ∣ W ( i ) ∣ ∣ F J_R = J + \lambda\sum_{i=1}^L||W^{(i)}||_F J R = J + λ i = 1 ∑ L ∣ ∣ W ( i ) ∣ ∣ F
上式中,∣ ∣ W ( i ) ∣ ∣ F ||W^{(i)}||_F ∣ ∣ W ( i ) ∣ ∣ F 是矩陣W ( i ) W^{(i)} W ( i ) 的F F F 範數,λ \lambda λ 是正則化選項的相對權重。
非線性神經元
目前爲止我們討論的非線性神經元有sigmoid,然而在很多應用中有更好的激活函數。常用的有:
Sigmoid
公式:
σ ( z ) = 1 1 + e x p ( − z ) ∈ ( 0 , 1 ) \sigma(z) = \frac{1}{1+exp(-z)} \in (0,1) σ ( z ) = 1 + e x p ( − z ) 1 ∈ ( 0 , 1 )
梯度:
σ ′ ( z ) = σ ( z ) ( 1 − σ ( z ) ) \sigma\prime(z) = \sigma(z)(1-\sigma(z)) σ ′ ( z ) = σ ( z ) ( 1 − σ ( z ) )
Tanh
與sigmoid相比,tanh函數收斂更快,輸出範圍爲-1到1。
公式:
t a n h ( z ) = e x p ( z ) − e x p ( − z ) e x p ( z ) + e x p ( − z ) = 2 σ ( 2 z ) − 1 ∈ ( − 1 , 1 ) tanh(z) = \frac{exp(z)-exp(-z)}{exp(z) + exp(-z)} = 2\sigma(2z) -1 \in (-1,1) t a n h ( z ) = e x p ( z ) + e x p ( − z ) e x p ( z ) − e x p ( − z ) = 2 σ ( 2 z ) − 1 ∈ ( − 1 , 1 )
梯度:
t a n h ′ ( z ) = 1 − t a n h 2 ( z ) tanh\prime(z) = 1 - tanh^2(z) t a n h ′ ( z ) = 1 − t a n h 2 ( z )
Hard Tanh
hard tanh比tanh更容易計算。
公式:
h a r d t a n h ( z ) = { − 1 : z < − 1 z : − 1 ≤ z ≤ 1 1 : z > 1 hardtanh(z) = \begin{cases} -1 &:&z<-1\\z&:&-1\leq z\leq 1\\1&:&z>1\\\end{cases} h a r d t a n h ( z ) = ⎩ ⎪ ⎨ ⎪ ⎧ − 1 z 1 : : : z < − 1 − 1 ≤ z ≤ 1 z > 1
梯度:
h a r d t a n h ′ ( z ) = { 1 : − 1 ≤ z ≤ 1 0 : o t h e r w i s e hardtanh\prime(z) = \begin{cases}1 &:&-1\leq z \leq 1\\0&:&otherwise\end{cases} h a r d t a n h ′ ( z ) = { 1 0 : : − 1 ≤ z ≤ 1 o t h e r w i s e
Soft sign
公式:
s o f t s i g n ( z ) = z 1 + ∣ z ∣ softsign(z) = \frac{z}{1+|z|} s o f t s i g n ( z ) = 1 + ∣ z ∣ z
梯度:
s o f t s i g n ′ ( z ) = s g n ( z ) ( 1 + z ) 2 softsign\prime(z) = \frac{sgn(z)}{(1+z)^2} s o f t s i g n ′ ( z ) = ( 1 + z ) 2 s g n ( z )
其中 s g n ( z ) sgn(z) s g n ( z ) 是符號函數,根據z的不同返回不同,s g n ( z ) = { 1 z > 0 0 z = 0 − 1 z < 0 sgn(z) = \begin{cases}1 &z>0&\\0 &z=0&\\-1 &z<0&\end{cases} s g n ( z ) = ⎩ ⎪ ⎨ ⎪ ⎧ 1 0 − 1 z > 0 z = 0 z < 0
ReLu
ReLu,Rectify Linear Unit,是一種比較流行的激活函數,因爲它的上限不飽和,在計算視覺應用方面獲得成功。
公式:
r e c t ( z ) = m a x ( z , 0 ) rect(z) = max(z, 0) r e c t ( z ) = m a x ( z , 0 )
梯度:
r e c t ′ ( z ) = { 1 : z > 0 0 : o t h e r w i s e rect\prime(z) = \begin{cases}1 &:&z>0\\0 &:&otherwise\end{cases} r e c t ′ ( z ) = { 1 0 : : z > 0 o t h e r w i s e
Leaky ReLu
傳統ReLu激活單元對非正的z不具備傳播誤差的功能,leaky ReLu改進了這一缺陷,使得曉得誤差能夠被後向傳播。
公式:
l e a k y ( z ) = m a x ( z , k ⋅ z ) leaky(z) = max(z, k\cdot z) l e a k y ( z ) = m a x ( z , k ⋅ z ) 其中 0 < k < 1 0<k<1 0 < k < 1
梯度:
l e a k y ′ ( z ) = { 1 : z > 0 k : o t h e r w i s e leaky\prime (z) = \begin{cases}1 &:&z>0\\k &:&otherwise\\\end{cases} l e a k y ′ ( z ) = { 1 k : : z > 0 o t h e r w i s e
MaxOut Network
最近出現的一個非線性網絡,公式:
f i ( z ) = m a x j ∈ [ 1 , k ] z i j f_i(z) = max_{j\in[1,k]}z_{ij} f i ( z ) = m a x j ∈ [ 1 , k ] z i j
z i j = x T W ⋅ ⋅ i j + b i j z_{ij} = x^TW_{\cdot \cdot ij} + b_{ij} z i j = x T W ⋅ ⋅ i j + b i j
這種方法在一些圖片數據集上取得了不錯的效果。
參數初始化
論文《Understanding the difficulty of training deep feedfor-ward neural networks (2010), Xavier et al》中研究了權重和偏置的初始值不同對訓練的影響,結果表明,當權重矩陣 W ∈ R n ( l + 1 ) × n ( l ) W\in R^{n^{(l+1)}\times n^{(l)}} W ∈ R n ( l + 1 ) × n ( l ) 採用以下範圍的均勻分佈來隨機初始化時,對sigmoid和tanh激活函數會得到更低的誤差率和更快的收斂速度:
U [ − 6 n ( l ) + n ( l + 1 ) , 6 n ( l ) + n ( l + 1 ) ] U[-\sqrt{\frac{6}{n^{(l)} + n^{(l+1)}}}, \sqrt{\frac{6}{n^{(l)} + n^{(l+1)}}}] U [ − n ( l ) + n ( l + 1 ) 6 , n ( l ) + n ( l + 1 ) 6 ]
其中,n ( l ) n^{(l)} n ( l ) 表示輸入單元的個數,n l + 1 n^{l+1} n l + 1 表示輸出單元的個數。
目的:維護層層之間激活方差和後向傳播的梯度方差。
學習速率
模型中梯度更新的速度使用學習速率這個變量來控制,在下面公式中,α \alpha α 表示學習速率:
θ n e w = θ o l d − α Δ θ J t ( θ ) \theta^{new} = \theta^{old} - \alpha \Delta_{\theta}J_t(\theta) θ n e w = θ o l d − α Δ θ J t ( θ )
梯度更新的速度並不是越快越好,a l p h a alpha a l p h a 太大,可能會導致無法收斂到最優解。在非凸模型中(我們遇到的大部分模型都是非凸的),很大的學習速率導致損失函數的發散機率更高。
關於學習速率的設置有很多變種,詳細信息可以看講義。
AdaGrad
AdaGrad可以說是標準的SGD,但是隻有一點不同:它的每個參數的學習速率是不同的。每個參數的學習速率依賴於歷史更新信息,換句話說,沒有更新過的參數的學習速率可能更高,用公式表示:
θ t , i = θ t − 1 , i − α ∑ τ = 1 t g τ , i 2 g t , i \theta_{t,i} = \theta_{t-1,i} - \frac{\alpha}{\sqrt{\sum_{\tau = 1}^tg_{\tau,i}^2}}g_{t,i} θ t , i = θ t − 1 , i − ∑ τ = 1 t g τ , i 2 α g t , i
其中,g t , i = ∂ ∂ θ i t J t ( θ ) g_{t,i} = \frac{\partial}{\partial \theta_i^t}J_t(\theta) g t , i = ∂ θ i t ∂ J t ( θ )
簡單的代碼實現:
cache += dx**2
x += - learning_rate * dx / np.sqrt(cache + 1e-8)
其他方法