1. 程式人生 > 實用技巧 >Ng深度學習筆記 超引數除錯和Batch正則化

Ng深度學習筆記 超引數除錯和Batch正則化

超引數除錯與batch正則化

除錯處理(Tuning process)

訓練深度最難的事情之一是引數的數量。

結果證實一些超引數比其它的更為重要,我認為,最為廣泛的學習應用是 a a a,學習速率是需要除錯的最重要的超引數。

除了 a a a,還有一些引數需要除錯,例如Momentum引數 β \beta β,0.9就是個很好的預設值,還有mini-batch的大小,以確保最優演算法執行有效。

超引數有重要性區別。 a a a無疑是最重要的,接下來是用橙色圈住的那些,然後是用紫色圈住的那些,但這不是嚴格且快速的標準。在這裡插入圖片描述
選擇除錯值: 在早一代的機器學習演算法中,有兩個超引數時常在網格中取樣點,然後系統的研究這些數值。如5×5的網格,實踐證明,網格可以是5×5,也可多可少,但對於這個例子,你可以嘗試這所有的25個點,然後選擇哪個引數效果最好。當引數的數量相對較少時,這個方法很實用。

在深度學習領域,常常隨機選擇點來調整。

給超引數取值時,另一個慣例是採用從粗到細的搜尋:比如在二維的那個例子中,發現效果最好的某個點,接下來要做的是放大這塊小區域(小藍色方框內),然後在其中更密集得取值或隨機取值,在這個藍色的方格中搜索。
在這裡插入圖片描述

為超引數選擇合適的範圍(Using an appropriate scale to pick hyperparameters)

看看這個例子,假設你在搜尋超引數 a a a(學習速率),假設你懷疑其值最小是0.0001或最大是1。如果你畫一條從0.0001到1的數軸,沿其隨機均勻取值,那90%的數值將會落在0.1到1之間,結果就是,在0.1到1之間,應用了90%的資源,而在0.0001到0.1之間,只有10%的搜尋資源。

反而,用對數標尺搜尋超引數的方式會更合理,因此這裡不使用線性軸,分別依次取0.0001,0.001,0.01,0.1,1,在對數軸上均勻隨機取點,這樣,在0.0001到0.001之間,就會有更多的搜尋資源可用。

所以在Python中,使r=-4*np.random.rand(),然後 a a a隨機取值, a = 1 0 r a =10^{r} a=10r,所以, r ∈ [ 4 , 0 ] r \in [ 4,0] r[4,0] a ∈ [ 1 0 − 4 , 1 0 0 ] a \in[10^{-4},10^{0}] a[104,100],最左邊的數字是 1 0 − 4 10^{-4} 104,最右邊是 1 0 0 10^{0} 100

即,在對數座標下取值, a a a為最小值的對數, b b b為最大值的對數,在 a a a b b b間隨意均勻的選取 r r r值,將超引數設定為 1 0 r 10^{r} 10r

另一個棘手的例子是給 β \beta β 取值,用於計算指數的加權平均值。假設 β \beta β是0.9到0.999之間的某個值,也許這就是你想搜尋的範圍。

如果在0.9到0.999區間搜尋,那就不能用線性軸取值。考慮這個問題最好的方法就是探究 1 − β 1-\beta 1β,此值在0.1到0.001區間內。

β \beta β值如果在0.999到0.9995之間,這會對演算法產生巨大影響,對吧?在這兩種情況下,是根據大概10個值取平均。但這裡,它是指數的加權平均值,基於1000個值,現在是2000個值,因為這個公式 1 1 − β \frac{1}{1- \beta} 1β1,當 β \beta β接近1時, β \beta β就會對細微的變化變得很敏感。所以整個取值過程中,需要更加密集地取值,在 β \beta β 接近1的區間內,或者說,當 1 − β 1-\beta 1β 接近於0時,這樣,你就可以更加有效的分佈取樣點,更有效率的探究可能的結果。

超引數除錯的實踐

如何搜尋超引數?

  1. babysit一個模型,通常是有龐大的資料組,但沒有許多計算資源或足夠的CPU和GPU的前提下,可以逐漸改良,觀察它的表現,耐心地除錯學習率,但那通常是因為沒有足夠的計算能力,不能在同一時間試驗大量模型時才採取的辦法。

  2. 同時試驗多種模型。設定了一些超引數,儘管讓它自己執行,或者是一天甚至多天。

在這裡插入圖片描述

歸一化網路的啟用函式

Batch歸一化:

歸一化輸入特徵可以加快學習過程。

一般歸一化 z ( i ) z^{(i)} z(i)。減去均值再除以標準偏差,為了使數值穩定,通常將 ε \varepsilon ε作為分母,以防 σ = 0 σ=0 σ=0的情況。
在這裡插入圖片描述

所以現在 z z z的每一個分量都含有平均值0和方差1,但也許隱藏單元有了不同的分佈會有意義,所以 z ~ ( i ) = γ z norm ( i ) + β {\tilde{z}}^{(i)}= \gamma z_{\text{norm}}^{(i)} +\beta z~(i)=γznorm(i)+β這裡 γ \gamma γ β \beta β是學習引數,作用是設定 z ~ ( i ) {\tilde{z}}^{(i)} z~(i)的平均值。

如果 γ = σ 2 + ε \gamma= \sqrt{\sigma^{2} +\varepsilon} γ=σ2+ε ,如果 γ \gamma γ等於這個分母項( z norm ( i ) = z ( i ) − μ σ 2 + ε z_{\text{norm}}^{(i)} = \frac{z^{(i)} -\mu}{\sqrt{\sigma^{2} +\varepsilon}} znorm(i)=σ2+ε z(i)μ中的分母), β \beta β等於 μ \mu μ,這裡的這個值是 z norm ( i ) = z ( i ) − μ σ 2 + ε z_{\text{norm}}^{(i)}= \frac{z^{(i)} - \mu}{\sqrt{\sigma^{2} + \varepsilon}} znorm(i)=σ2+ε z(i)μ中的 μ \mu μ,那麼 γ z norm ( i ) + β \gamma z_{\text{norm}}^{(i)} +\beta γznorm(i)+β的作用在於,它會精確轉化這個方程,如果這些成立( γ = σ 2 + ε , β = μ \gamma =\sqrt{\sigma^{2} + \varepsilon},\beta =\mu γ=σ2+ε ,β=μ),那麼 z ~ ( i ) = z ( i ) {\tilde{z}}^{(i)} = z^{(i)} z~(i)=z(i)

通過對 γ \gamma γ β \beta β合理設定,規範化過程,即這四個等式,從根本來說,只是計算恆等函式,通過賦予 γ \gamma γ β \beta β其它值,可以構造含其它平均值和方差的隱藏單元值。

將 Batch Norm 擬合進神經網路(Fitting Batch Norm into a neural network)

神經網路中,每個單元負責計算計算z,然後應用其到啟用函式中再計算a,每個圓圈代表著兩步的計算過程。

如果你沒有應用Batch歸一化,你會把輸入 X X X擬合到第一隱藏層,然後首先計算 z [ 1 ] z^{[1]} z[1],這是由 w [ 1 ] w^{[1]} w[1] b [ 1 ] b^{[1]} b[1]兩個引數控制的。接著,通常而言,你會把 z [ 1 ] z^{[1]} z[1]擬合到啟用函式以計算 a [ 1 ] a^{[1]} a[1]。但Batch歸一化的做法是將 z [ 1 ] z^{[1]} z[1]值進行Batch歸一化,簡稱BN,此過程將由 β [ 1 ] {\beta}^{[1]} β[1] γ [ 1 ] \gamma^{[1]} γ[1]兩引數控制,這一操作會給你一個新的規範化的 z [ 1 ] z^{[1]} z[1]值( z ~ [ 1 ] {\tilde{z}}^{[1]} z~[1]),然後將其輸入啟用函式中得到 a [ 1 ] a^{[1]} a[1],即 a [ 1 ] = g [ 1 ] ( z ~ [ l ] ) a^{[1]} = g^{[1]}({\tilde{z}}^{[ l]}) a[1]=g[1](z~[l])
在這裡插入圖片描述

Batch歸一化是發生在計算 z z z a a a之間的。直覺就是,與其應用沒有歸一化的 z z z值,不如用歸一過的 z ~ \tilde{z} z~,這是第一層( z ~ [ 1 ] {\tilde{z}}^{[1]} z~[1])。所以網路的引數就會是 w [ 1 ] w^{[1]} w[1] b [ 1 ] b^{[1]} b[1] w [ 2 ] w^{[2]} w[2] b [ 2 ] b^{[2]} b[2]等等,我們將要去掉這些引數。但現在,想象引數 w [ 1 ] w^{[1]} w[1] b [ 1 ] b^{[1]} b[1] w [ l ] w^{[l]} w[l] b [ l ] b^{[l]} b[l],我們將另一些引數加入到此新網路中 β [ 1 ] {\beta}^{[1]} β[1] β [ 2 ] {\beta}^{[2]} β[2] γ [ 1 ] \gamma^{[1]} γ[1] γ [ 2 ] \gamma^{[2]} γ[2]等等。對於應用Batch歸一化的每一層而言。

接下來可以使用優化演算法。

實踐中,Batch歸一化通常和訓練集的mini-batch一起使用。

一個細節: z [ l ] = w [ l ] a [ l − 1 ] + b [ l ] z^{[l]} =w^{[l]}a^{\left\lbrack l - 1 \right\rbrack} +b^{[l]} z[l]=w[l]a[l1]+b[l],將 z [ l ] z^{[l]} z[l]歸一化,結果為均值0和標準方差,再由 β \beta β γ \gamma γ重縮放。但這意味著,無論 b [ l ] b^{[l]} b[l]的值是多少,都是要被減去的。所以,在使用Batch歸一化時,其實你可以消除這個引數( b [ l ] b^{[l]} b[l]),或暫時把它設定為0。

那麼,引數變成 z [ l ] = w [ l ] a [ l − 1 ] z^{[l]} = w^{[l]}a^{\left\lbrack l - 1 \right\rbrack} z[l]=w[l]a[l1] z ~ [ l ] = γ [ l ] z [ l ] + β [ l ] {\tilde{z}}^{[l]} = \gamma^{[l]}z^{[l]} + {\beta}^{[l]} z~[l]=γ[l]z[l]+β[l]

最後,請記住 z [ l ] z^{[l]} z[l]的維數,因為在這個例子中,維數會是 ( n [ l ] , 1 ) (n^{[l]},1) (n[l],1) b [ l ] b^{[l]} b[l]的尺寸為 ( n [ l ] , 1 ) (n^{[l]},1) (n[l],1),如果是l層隱藏單元的數量,那 β [ l ] {\beta}^{[l]} β[l] γ [ l ] \gamma^{[l]} γ[l]的維度也是 ( n [ l ] , 1 ) (n^{[l]},1) (n[l],1)

關於如何用Batch歸一化來應用梯度下降法:(假設使用mini-batch梯度下降法,執行 t = 1 t=1 t=1到batch數量的for迴圈)

  1. 在mini-batch X { t } X^{\{t \}} X{t}上應用正向prop,每個隱藏層都應用正向prop,用Batch歸一化 z ~ [ l ] {\tilde{z}}^{[l]} z~[l]
  2. 反向prop計算 d w [ l ] dw^{[l]} dw[l] d b [ l ] db^{[l]} db[l],及所有l層所有的引數, d β [ l ] d{\beta}^{[l]} dβ[l] d γ [ l ] d\gamma^{[l]} dγ[l]。儘管嚴格來說,因為你要去掉 b b b,這部分其實已經去掉了。
  3. 更新這些引數: w [ l ] = w [ l ] − αd w [ l ] w^{[l]} = w^{[l]} -\text{αd}w^{[l]} w[l]=w[l]αdw[l] β [ l ] = β [ l ] − α d β [ l ] {\beta}^{[l]} = {\beta}^{[l]} - {αd}{\beta}^{[l]} β[l]=β[l]αdβ[l] γ [ l ] = γ [ l ] − α d γ [ l ] \gamma^{[l]} = \gamma^{[l]} -{αd}\gamma^{[l]} γ[l]=γ[l]αdγ[l]

Batch Norm 為什麼奏效?

  • 歸一化輸入特徵值加速學習。Batch歸一化不僅僅作用於這裡的輸入值,還有隱藏單元的值。
  • 使權重比網路更滯後或更深層。
    • *covariate shift: 已經學習了 x x x y y y 的對映,則 x x x 的分佈改變了後可能需要重新訓練你的學習演算法。

    • Batch歸一化做的,是它減少了這些隱藏值分佈變化的數量。Batch歸一化可以確保無論其怎樣變化 z 1 [ 2 ] z_{1}^{[2]} z1[2] z 2 [ 2 ] z_{2}^{[2]} z2[2]的均值和方差保持不變,所以即使 z 1 [ 2 ] z_{1}^{[2]} z1[2] z 2 [ 2 ] z_{2}^{[2]} z2[2]的值改變,至少他們的均值和方差是由 β [ 2 ] {\beta}^{[2]} β[2] γ [ 2 ] \gamma^{[2]} γ[2]決定的值。它限制了在前層的引數更新,會影響數值分佈的程度,第三層看到的這種情況,因此得到學習。它減弱了前層引數的作用與後層引數的作用之間的聯絡,它使得網路每層都可以自己學習,稍稍獨立於其它層,這有助於加速整個網路的學習。

  • Batch歸一化有輕微的正則化效果。

測試時的 Batch Norm(Batch Norm at test time)

在測試時可能需要對每個樣本逐一處理。
在這裡插入圖片描述
在訓練時,這些就是用來執行Batch歸一化的等式。用於調節計算的 μ \mu μ σ 2 \sigma^{2} σ2是在整個mini-batch上進行計算,但是在測試時,需要用其它方式來得到 μ \mu μ σ 2 \sigma^{2} σ2。一個樣本的均值和方差沒有意義。

那麼就需要單獨估算 μ \mu μ σ 2 \sigma^{2} σ2,在典型的Batch歸一化運用中,你需要用一個指數加權平均來估算,這個平均數涵蓋了所有mini-batch。

選擇 l l l層,假設我們有mini-batch, X [ 1 ] X^{[1]} X[1] X [ 2 ] X^{[2]} X[2] X [ 3 ] X^{[3]} X[3]……以及對應的 y y y值等等,那麼在為 l l l層訓練 X 1 X^{{ 1}} X1時,你就得到了 μ [ l ] \mu^{[l]} μ[l] μ [ l ] → μ { 1 } [ l ] \mu^{[l]} \rightarrow \mu^{\{1 \}[l]} μ[l]μ{1}[l])。當你訓練第二個mini-batch,在這一層和這個mini-batch中,你就會得到第二個 μ \mu μ μ 2 [ l ] \mu^{{2}[l]} μ2[l])值。然後在這一隱藏層的第三個mini-batch,你得到了第三個 μ \mu μ μ { 3 } [ l ] \mu^{\{3 \}[l]} μ{3}[l])值。正如我們之前用的指數加權平均來計算 θ 1 \theta_{1} θ1 θ 2 \theta_{2} θ2 θ 3 \theta_{3} θ3的均值,當時是試著計算當前氣溫的指數加權平均,你會這樣來追蹤你看到的這個均值向量的最新平均值,於是這個指數加權平均就成了對這一隱藏層的 z z z均值的估值。同樣的,你可以用指數加權平均來追蹤你在這一層的第一個mini-batch中所見的 σ 2 \sigma^{2} σ2的值,以及第二個mini-batch中所見的 σ 2 \sigma^{2} σ2的值等等。

因此在用不同的mini-batch訓練神經網路時,能夠得到所檢視的每一層的 μ \mu μ σ 2 \sigma^{2} σ2的平均數的實時數值。

最後在測試時,對應這個等式( z norm ( i ) = z ( i ) − μ σ 2 + ε z_{\text{norm}}^{(i)} = \frac{z^{(i)} -\mu}{\sqrt{\sigma^{2} +\varepsilon}} znorm(i)=σ2+ε z(i)μ),你只需要用你的 z z z值來計算 z norm ( i ) z_{\text{norm}}^{(i)} znorm(i),用 μ \mu μ σ 2 \sigma^{2} σ2的指數加權平均,用你手頭的最新數值來做調整,然後你可以用左邊我們剛算出來的 z norm z_{\text{norm}} znorm和你在神經網路訓練過程中得到的 β \beta β γ \gamma γ引數來計算你那個測試樣本的 z ~ \tilde{z} z~值。

總結一下就是,在訓練時, μ \mu μ σ 2 \sigma^{2} σ2是在整個mini-batch上計算出來,但在測試時需要逐一處理樣本,方法是根據訓練集估算 μ \mu μ σ 2 \sigma^{2} σ2,理論上你可以在最終的網路中執行整個訓練集來得到 μ \mu μ σ 2 \sigma^{2} σ2,但在實際操作中,通常運用指數加權平均來追蹤在訓練過程中你看到的 μ \mu μ σ 2 \sigma^{2} σ2的值。

Softmax 迴歸(Softmax regression)

在這裡插入圖片描述

假設你算出了 z [ l ] z^{[l]} z[l] z [ l ] z^{[l]} z[l]是一個四維向量,假設為 z [ l ] = [ 5 2 − 1 3 ] z^{[l]} = \begin{bmatrix} 5 \\ 2 \\ - 1 \\ 3 \ \end{bmatrix} z[l]=5213,我們要做的就是用這個元素取冪方法來計算 t t t,所以 t = [ e 5 e 2 e − 1 e 3 ] = [ 148.4 7.4 0.4 20.1 ] t =\begin{bmatrix} e^{5} \\ e^{2} \\ e^{- 1} \\ e^{3} \ \end{bmatrix} = \begin{bmatrix} 148.4 \\ 7.4 \\ 0.4 \\ 20.1 \\ \end{bmatrix} t=e5e2e1e3=148.47.40.420.1,我們從向量 t t t得到向量 a [ l ] a^{[l]} a[l]就只需要將這些專案歸一化,使總和為1。如果你把 t t t的元素都加起來,把這四個數字加起來,得到176.3,最終 a [ l ] = t 176.3 a^{[l]} = \frac{t} {176.3} a[l]=176.3t, 輸出 a [ l ] a^{[l]} a[l],也就是 y ^ \hat y y^,是一個4×1維向量,這個4×1向量的元素就是我們算出來的這四個數字( [ 0.842 0.042 0.002 0.114 ] \begin{bmatrix} 0.842 \\ 0.042 \\ 0.002 \\ 0.114 \\ \end{bmatrix} 0.8420.0420.0020.114),所以這種演算法通過向量 z [ l ] z^{[l]} z[l]計算出總和為1的四個概率。

之前啟用函式都是接受單行數值輸入, Softmax啟用函式的特殊之處在於,因為需要將所有可能的輸出歸一化,就需要輸入一個向量,最後輸出一個向量。

那麼Softmax分類器還可以代表其它的什麼東西麼?
這個例子中(左邊圖),原始輸入只有 x 1 x_{1} x1 x 2 x_{2} x2,一個 C = 3 C=3 C=3個輸出分類的Softmax層能夠代表這種型別的決策邊界,請注意這是幾條線性決策邊界,但這使得它能夠將資料分到3個類別中,在這張圖表中,我們所做的是選擇這張圖中顯示的訓練集,用資料的3種輸出標籤來訓練Softmax分類器,圖中的顏色顯示了Softmax分類器的輸出的閾值,輸入的著色是基於三種輸出中概率最高的那種。因此我們可以看到這是logistic迴歸的一般形式,有類似線性的決策邊界,但有超過兩個分類,分類不只有0和1,而是可以是0,1或2。
在這裡插入圖片描述
Softmax迴歸或Softmax啟用函式將logistic啟用函式推廣到 C C C類,而不僅僅是兩類,如果 C = 2 C=2 C=2,那麼 C = 2 C=2 C=2的Softmax實際上變回了logistic迴歸。

訓練一個 Softmax 分類器

先定義訓練神經網路使會用到的損失函式。舉個例子某個樣本目標輸出真實標籤是 [ 0 1 0 0 ] \begin{bmatrix} 0 \\ 1 \\ 0 \\ 0 \\ \end{bmatrix} 0100,這表示這是一張貓的圖片,因為它屬於類1(我把貓加做類1,狗為類2,小雞是類3),假設神經網路輸出的是 y ^ \hat y y^ y ^ \hat y y^是一個包括總和為1的概率的向量, y = [ 0.3 0.2 0.1 0.4 ] y = \begin{bmatrix} 0.3 \\ 0.2 \\ 0.1 \\ 0.4 \\ \end{bmatrix} y=0.30.20.10.4,對於這個樣本神經網路的表現不佳,這實際上是一隻貓,但卻只分配到20%是貓的概率。

來看上面的單個樣本來更好地理解整個過程。在Softmax分類中,我們一般用到的損失函式是 L ( y ^ , y ) = − ∑ j = 1 4 y j l o g y ^ j L(\hat y,y ) = - \sum_{j = 1}^{4}{y_{j}log\hat y_{j}} L(y^,y)=j=14yjlogy^j。在這個樣本中 y 1 = y 3 = y 4 = 0 y_{1} =y_{3} = y_{4} = 0 y1=y3=y4=0,只有 y 2 = 1 y_{2} =1 y2=1,如果你看這個求和,所有含有值為0的 y j y_{j} yj的項都等於0,最後 L ( y ^ , y ) = − ∑ j = 1 4 y j log ⁡ y ^ j = − y 2 l o g y ^ 2 = − l o g y ^ 2 L\left( \hat y,y \right) = - \sum_{j = 1}^{4}{y_{j}\log \hat y_{j}} = - y_{2}{\ log} \hat y_{2} = - {\ log} \hat y_{2} L(y^,y)=j=14yjlogy^j=y2logy^2=logy^2

因為梯度下降法是用來減少訓練集的損失的,所以就需要使 y ^ 2 \hat y_{2} y^2儘可能大,但不可能比1大。

整個訓練集的損失 J J J
J ( w [ 1 ] , b [ 1 ] , … … ) = 1 m ∑ i = 1 m L ( y ^ ( i ) , y ( i ) ) J( w^{[1]},b^{[1]},\ldots\ldots) = \frac{1}{m}\sum_{i = 1}^{m}{L( \hat y^{(i)},y^{(i)})} J(w[1],b[1],)=m1i=1mL(y^(i),y(i))用梯度下降法,使這裡的損失最小化。

最後還有一個實現細節,注意因為 C = 4 C=4 C=4 y y y是一個4×1向量, y y y也是一個4×1向量,如果你實現向量化,矩陣大寫 Y Y Y就是 [ y ( 1 ) y ( 2 ) … … y ( m ) ] \lbrack y^{(1)}\text{}y^{(2)}\ldots\ldots\ y^{\left( m \right)}\rbrack [y(1)y(2)y(m)],例如如果上面這個樣本是你的第一個訓練樣本,那麼矩陣 Y = [ 0 0 1 … 1 0 0 … 0 1 0 … 0 0 0 … ] Y =\begin{bmatrix} 0 & 0 & 1 & \ldots \\ 1 & 0 & 0 & \ldots \\ 0 & 1 & 0 & \ldots \\ 0 & 0 & 0 & \ldots \ \end{bmatrix} Y=010000101000,那麼這個矩陣 Y Y Y最終就是一個 4 × m 4×m 4×m維矩陣。類似的, Y ^ = [ y ^ ( 1 ) y ^ ( 2 ) … … y ^ ( m ) ] \hat{Y} = \lbrack{\hat{y}}^{(1)}{\hat{y}}^{(2)} \ldots \ldots\ {\hat{y}}^{(m)}\rbrack Y^=[y^(1)y^(2)y^(m)],這個其實就是 y ^ ( 1 ) {\hat{y}}^{(1)} y^(1) a l = y ( 1 ) = [ 0.3 0.2 0.1 0.4 ] a^{l} = y^{(1)} = \begin{bmatrix} 0.3 \\ 0.2 \\ 0.1 \\ 0.4 \\ \end{bmatrix} al=y(1)=0.30.20.10.4),或是第一個訓練樣本的輸出,那麼 Y ^ = [ 0.3 … 0.2 … 0.1 … 0.4 … ] \hat{Y} = \begin{bmatrix} 0.3 & \ldots \\ 0.2 & \ldots \\ 0.1 & \ldots \\ 0.4 & \ldots \\ \end{bmatrix} Y^=0.30.20.10.4 Y ^ \hat{Y} Y^本身也是一個 4 × m 4×m 4×m維矩陣。