CS224D 課程學習筆記 L06

Lecture 6. Neural Tips and Tricks


Lecture 6主要介紹了深度學習應用的一些小技巧,例如多任務訓練、梯度檢測、正則化、多種激活函數、參數初始化、學習速率等。

多任務學習(也叫權重共享)

對比上節課我們學到的神經網絡,多任務學習就是在輸出層用softmax分類器取代標量得分。訓練方法依然採用後向傳播。

神經網絡和傳統機器學習方法的不同在於,深度學習需要同時學習詞向量和權重。

主要思想:我們在訓練多種不同NLP任務(例如NER和POS),可以共享兩個任務的詞向量和隱藏層的權重,只有輸出層的softmax權重不同。損失函數是不同任務損失函數相加,例如:

δtotal=δPOS+δNER\delta^{total} = \delta^{POS} + \delta^{NER}

參考論文《NLP(almost from scratch, Collobert et al.2011)》

成功的神經網絡的通用步驟是這樣的:

  1. 選擇合適的網絡框架
    1. 框架:單個詞、固定窗口、詞袋、循環神經網絡、遞歸神經網絡、CNN等;
    2. 非線性神經單元
  2. 用梯度檢測器檢查實現代碼是否存在bug
  3. 參數初始化
  4. 優化技巧
  5. 檢查模型是否強大到過擬合
    1. 如果沒有過擬合,改變模型框架或者模型調大
    2. 如果過擬合,請用正則化

下面我們根據這些步驟分別介紹使用技巧。

梯度檢測

梯度檢測我們在第一次作業中用過,從導數的本質上求得參數的梯度,和我們用後向傳播計算得到的梯度對比。公式如下:

f(θ)J(θ(i+))J(θ(i))2ϵf\prime (\theta) \approx \frac{J(\theta^{(i+)}) - J(\theta^{(i-)})}{2\epsilon}

其中,θ(i+)=θ+ϵ×ei\theta^{(i+)} = \theta + \epsilon \times e_i

簡單的代碼實現爲:

old_value = x[ix]
x[ix] = old_value + h 
fxh = f(x) 
x[ix] = old_value
grad[ix] = (fxh - fx) / h

如果梯度檢測失敗了應該怎麼做?修改代碼確定沒有bug!

正則化

正則化前面課程提到的次數也很多,和大多數分類器一樣,神經網絡也需要避免過擬合,使得驗證集和測試集能夠獲得良好的表現。正則化後的損失函數爲:

JR=J+λi=1LW(i)FJ_R = J + \lambda\sum_{i=1}^L||W^{(i)}||_F

上式中,W(i)F||W^{(i)}||_F是矩陣W(i)W^{(i)}FF範數,λ\lambda是正則化選項的相對權重。

非線性神經元

目前爲止我們討論的非線性神經元有sigmoid,然而在很多應用中有更好的激活函數。常用的有:

Sigmoid

公式:

σ(z)=11+exp(z)(0,1)\sigma(z) = \frac{1}{1+exp(-z)} \in (0,1)

梯度:

σ(z)=σ(z)(1σ(z))\sigma\prime(z) = \sigma(z)(1-\sigma(z))

Tanh

與sigmoid相比,tanh函數收斂更快,輸出範圍爲-1到1。

公式:

tanh(z)=exp(z)exp(z)exp(z)+exp(z)=2σ(2z)1(1,1)tanh(z) = \frac{exp(z)-exp(-z)}{exp(z) + exp(-z)} = 2\sigma(2z) -1 \in (-1,1)

梯度:

tanh(z)=1tanh2(z)tanh\prime(z) = 1 - tanh^2(z)

Hard Tanh

hard tanh比tanh更容易計算。

公式:

hardtanh(z)={1:z<1z:1z11:z>1hardtanh(z) = \begin{cases} -1 &:&z<-1\\z&:&-1\leq z\leq 1\\1&:&z>1\\\end{cases}

梯度:

hardtanh(z)={1:1z10:otherwisehardtanh\prime(z) = \begin{cases}1 &:&-1\leq z \leq 1\\0&:&otherwise\end{cases}

Soft sign

公式:

softsign(z)=z1+zsoftsign(z) = \frac{z}{1+|z|}

梯度:

softsign(z)=sgn(z)(1+z)2softsign\prime(z) = \frac{sgn(z)}{(1+z)^2}

​ 其中 sgn(z)sgn(z)是符號函數,根據z的不同返回不同,sgn(z)={1z>00z=01z<0sgn(z) = \begin{cases}1 &z>0&\\0 &z=0&\\-1 &z<0&\end{cases}

ReLu

ReLu,Rectify Linear Unit,是一種比較流行的激活函數,因爲它的上限不飽和,在計算視覺應用方面獲得成功。

公式:

rect(z)=max(z,0)rect(z) = max(z, 0)

梯度:

rect(z)={1:z>00:otherwiserect\prime(z) = \begin{cases}1 &:&z>0\\0 &:&otherwise\end{cases}

Leaky ReLu

傳統ReLu激活單元對非正的z不具備傳播誤差的功能,leaky ReLu改進了這一缺陷,使得曉得誤差能夠被後向傳播。

公式:

leaky(z)=max(z,kz)leaky(z) = max(z, k\cdot z) 其中 0<k<10<k<1

梯度:

leaky(z)={1:z>0k:otherwiseleaky\prime (z) = \begin{cases}1 &:&z>0\\k &:&otherwise\\\end{cases}

MaxOut Network

最近出現的一個非線性網絡,公式:

fi(z)=maxj[1,k]zijf_i(z) = max_{j\in[1,k]}z_{ij}

zij=xTWij+bijz_{ij} = x^TW_{\cdot \cdot ij} + b_{ij}

這種方法在一些圖片數據集上取得了不錯的效果。

參數初始化

論文《Understanding the difficulty of training deep feedfor-ward neural networks (2010), Xavier et al》中研究了權重和偏置的初始值不同對訓練的影響,結果表明,當權重矩陣 WRn(l+1)×n(l)W\in R^{n^{(l+1)}\times n^{(l)}}採用以下範圍的均勻分佈來隨機初始化時,對sigmoid和tanh激活函數會得到更低的誤差率和更快的收斂速度:

U[6n(l)+n(l+1),6n(l)+n(l+1)]U[-\sqrt{\frac{6}{n^{(l)} + n^{(l+1)}}}, \sqrt{\frac{6}{n^{(l)} + n^{(l+1)}}}]

其中,n(l)n^{(l)}表示輸入單元的個數,nl+1n^{l+1}表示輸出單元的個數。

目的:維護層層之間激活方差和後向傳播的梯度方差。

學習速率

模型中梯度更新的速度使用學習速率這個變量來控制,在下面公式中,α\alpha表示學習速率:

θnew=θoldαΔθJt(θ)\theta^{new} = \theta^{old} - \alpha \Delta_{\theta}J_t(\theta)

梯度更新的速度並不是越快越好,alphaalpha太大,可能會導致無法收斂到最優解。在非凸模型中(我們遇到的大部分模型都是非凸的),很大的學習速率導致損失函數的發散機率更高。

關於學習速率的設置有很多變種,詳細信息可以看講義。

AdaGrad

AdaGrad可以說是標準的SGD,但是隻有一點不同:它的每個參數的學習速率是不同的。每個參數的學習速率依賴於歷史更新信息,換句話說,沒有更新過的參數的學習速率可能更高,用公式表示:

θt,i=θt1,iατ=1tgτ,i2gt,i\theta_{t,i} = \theta_{t-1,i} - \frac{\alpha}{\sqrt{\sum_{\tau = 1}^tg_{\tau,i}^2}}g_{t,i}

​ 其中,gt,i=θitJt(θ)g_{t,i} = \frac{\partial}{\partial \theta_i^t}J_t(\theta)

簡單的代碼實現:

cache += dx**2
x += - learning_rate * dx / np.sqrt(cache + 1e-8)

其他方法

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章