目錄
- 第二門課: 改善深層神經網絡:超參數調試、正 則 化 以 及 優 化 (Improving Deep Neural Networks:Hyperparameter tuning, Regularization and Optimization)
- 第三周: 超 參 數 調 試 、 Batch 正 則 化 和 程 序 框 架(Hyperparameter tuning)
- 3.4 歸一化網絡的激活函數(Normalizing activations in a network)
- 3.5 將 Batch Norm 擬合進神經網絡(Fitting Batch Norm into a neural network)
第二門課: 改善深層神經網絡:超參數調試、正 則 化 以 及 優 化 (Improving Deep Neural Networks:Hyperparameter tuning, Regularization and Optimization)
第三周: 超 參 數 調 試 、 Batch 正 則 化 和 程 序 框 架(Hyperparameter tuning)
3.4 歸一化網絡的激活函數(Normalizing activations in a network)
在深度學習興起后,最重要的一個思想是它的一種算法,叫做 Batch 歸一化,由 Sergey loffe和Christian Szegedy 兩位研究者創造。Batch歸一化會使你的參數搜索問題變得很容易,使神經網絡對超參數的選擇更加穩定,超參數的范圍會更加龐大,工作效果也很好,也會是你的訓練更加容易,甚至是深層網絡。讓我們來看看 Batch 歸一化是怎么起作用的吧。
當訓練一個模型,比如 logistic 回歸時,你也許會記得,歸一化輸入特征可以加快學習過程。你計算了平均值,從訓練集中減去平均值,計算了方差,接著根據方差歸一化你的數據集,在之前的視頻中我們看到,這是如何把學習問題的輪廓,從很長的東西,變成更圓的東西,更易于算法優化。所以這是有效的,對 logistic 回歸和神經網絡的歸一化輸入特征值而言。
那么更深的模型呢?你不僅輸入了特征值𝑥,而且這層有激活值 a [ 1 ] a^{[1]} a[1],這層有激活值 a [ 2 ] a^{[2]} a[2]等等。如果你想訓練這些參數,比如 w [ 3 ] w^{[3]} w[3], b [ 3 ] b^{[3]} b[3],那歸一化 a [ 2 ] a^{[2]} a[2]的平均值和方差豈不是很好?以便使 w [ 3 ] w^{[3]} w[3], b [ 3 ] b^{[3]} b[3]的訓練更有效率。在 logistic 回歸的例子中,我們看到了如何歸一化 x 1 x_1 x1?, x 2 x_2 x2?, x 3 x_3 x3?,會幫助你更有效的訓練w和b。
所以問題來了,對任何一個隱藏層而言,我們能否歸一化a值,在此例中,比如說 a [ 2 ] a^{[2]} a[2]的值,但可以是任何隱藏層的,以更快的速度訓練 w [ 3 ] w^{[3]} w[3], b [ 3 ] b^{[3]} b[3],因為 a [ 2 ] a^{[2]} a[2]是下一層的輸入值,所以就會影響 w [ 3 ] w^{[3]} w[3], b [ 3 ] b^{[3]} b[3]的訓練。簡單來說,這就是 Batch 歸一化的作用。盡管嚴格來說,我們真正歸一化的不是 a [ 2 ] a^{[2]} a[2],而是 z [ 2 ] z^{[2]} z[2],深度學習文獻中有一些爭論,關于在激活函數之前是否應該將值 z [ 2 ] z^{[2]} z[2]歸一化,或是否應該在應用激活函數 a [ 2 ] a^{[2]} a[2]后再規范值。實踐中,經常做的是歸一化 z [ 2 ] z^{[2]} z[2],所以這就是我介紹的版本,我推薦其為默認選擇,那下面就是 Batch 歸一化的使用方法。
在神經網絡中,已知一些中間值,假設你有一些隱藏單元值,從 z ( 1 ) z^{(1)} z(1)到 z ( m ) z^{(m)} z(m),這些來源于隱藏層,所以這樣寫會更準確,
即 z [ l ] ( i ) z^{[l](i)} z[l](i)為隱藏層,𝑖從 1 到𝑚,但這樣書寫,我要省略𝑙及方括號,以便簡化這一行的符號。所以已知這些值,如下,你要計算平均值,強調一下,所有這些都是針對𝑙層,但我省略𝑙及方括號,然后用正如你常用的那個公式計算方差,接著,你會取每個𝑧(𝑖)值,使其規范化,方法如下,減去均值再除以標準偏差,為了使數值穩定,通常將 ? \epsilon ?作為分母,以防防𝜎 = 0的情況。
所以現在我們已把這些z值標準化,化為含平均值 0 和標準單位方差,所以𝑧的每一個分量都含有平均值 0 和方差 1,但我們不想讓隱藏單元總是含有平均值 0 和方差 1,也許隱藏單元有了不同的分布會有意義,所以我們所要做的就是計算,我們稱之為 z ^ ( i ) \hat{z}^{(i)} z^(i), z ^ ( i ) = γ z n o r m ( i ) + β \hat{z}^{(i)} = \gamma z_{norm}^{(i)} +\beta z^(i)=γznorm(i)?+β,這里𝛾和𝛽是你模型的學習參數,所以我們使用梯度下降或一些其它類似梯度下降的算法,比如 Momentum 或者 Nesterov,Adam,你會更新𝛾和𝛽,正如更新神經網絡的權重一樣。
請注意𝛾和𝛽的作用是,你可以隨意設置𝑧?(𝑖)的平均值,事實上,如果 γ = σ 2 + ? \gamma = \sqrt{\sigma^2 + \epsilon} γ=σ2+?? ,如果𝛾等于這個分母項( z n o r m ( i ) = z ( i ) ? μ σ 2 + ? z_{norm}^{(i)} =\frac{z^{(i)} -\mu}{\sqrt{\sigma^2 + \epsilon}} znorm(i)?=σ2+??z(i)?μ?中的分母), β \beta β等于 μ \mu μ,這里的這個值是 z n o r m ( i ) = z ( i ) ? μ σ 2 + ? z_{norm}^{(i)} =\frac{z^{(i)} -\mu}{\sqrt{\sigma^2 + \epsilon}} znorm(i)?=σ2+??z(i)?μ?中的 μ \mu μ,那么 γ z n o r m ( i ) + β \gamma z_{norm}^{(i)} + \beta γznorm(i)?+β的作用在于,它會精確轉化這個方程,如果這些成立( γ = σ 2 + ? \gamma = \sqrt{\sigma^2 + \epsilon} γ=σ2+??, β = μ \beta =\mu β=μ),那么 z ^ ( i ) = z ( i ) \hat{z}^{(i)} = z^{(i)} z^(i)=z(i)。
通過對𝛾和𝛽合理設定,規范化過程,即這四個等式,從根本來說,只是計算恒等函數,通過賦予𝛾和𝛽其它值,可以使你構造含其它平均值和方差的隱藏單元值。
所以,在網絡匹配這個單元的方式,之前可能是用 z ( 1 ) z^{(1)} z(1), z ( 2 ) z^{(2)} z(2)等等,現在則會用 z ^ i \hat{z}^{i} z^i取代 z ( i ) z^{(i)} z(i),方便神經網絡中的后續計算。如果你想放回[𝑙],以清楚的表明它位于哪層,你可以把它放這。
所以我希望你學到的是,歸一化輸入特征X是怎樣有助于神經網絡中的學習,Batch 歸一化的作用是它適用的歸一化過程,不只是輸入層,甚至同樣適用于神經網絡中的深度隱藏層。你應用 Batch 歸一化了一些隱藏單元值中的平均值和方差,不過訓練輸入和這些隱藏單元值的一個區別是,你也許不想隱藏單元值必須是平均值 0 和方差 1。
比如,如果你有 sigmoid 激活函數,你不想讓你的值總是全部集中在這里,你想使它們有更大的方差,或不是 0 的平均值,以便更好的利用非線性的 sigmoid 函數,而不是使所有的值都集中于這個線性版本中,這就是為什么有了𝛾和𝛽兩個參數后,你可以確保所有的 z ( i ) z^{(i)} z(i)值可以是你想賦予的任意值,或者它的作用是保證隱藏的單元已使均值和方差標準化。那里,均值和方差由兩參數控制,即𝛾和𝛽,學習算法可以設置為任何值,所以它真正的作用是,使隱藏單元值的均值和方差標準化,即 z ( i ) z^{(i)} z(i)有固定的均值和方差,均值和方差可以是 0 和 1,也可以是其它值,它是由𝛾和𝛽兩參數控制的。
我希望你能學會怎樣使用 Batch 歸一化,至少就神經網絡的單一層而言,在下一個視頻中,我會教你如何將 Batch 歸一化與神經網絡甚至是深度神經網絡相匹配。對于神經網絡許多不同層而言,又該如何使它適用,之后,我會告訴你,Batch 歸一化有助于訓練神經網絡的原因。所以如果覺得 Batch 歸一化起作用的原因還顯得有點神秘,那跟著我走,在接下來的兩個視頻中,我們會弄清楚。
3.5 將 Batch Norm 擬合進神經網絡(Fitting Batch Norm into a neural network)
你已經看到那些等式,它可以在單一隱藏層進行 Batch 歸一化,接下來,讓我們看看它是怎樣在深度網絡訓練中擬合的吧。
假設你有一個這樣的神經網絡,我之前說過,你可以認為每個單元負責計算兩件事。第一,它先計算z,然后應用其到激活函數中再計算a,所以我可以認為,每個圓圈代表著兩步的計算過程。同樣的,對于下一層而言,那就是 z 1 [ 2 ] z_1^{[2]} z1[2]?和 z 2 [ 2 ] z_2^{[2]} z2[2]?等。所以如果你沒有應用 Batch 歸一化,你會把輸入𝑋擬合到第一隱藏層,然后首先計算 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 ] \hat{z}^[1] z^[1]),然后將其輸入激活函數中得到 a [ 1 ] a^{[1]} a[1],即 a [ 1 ] = g [ 1 ] ( z ^ [ l ] ) a^{[1]} = g^{[1]}(\hat{z}^{[l]}) a[1]=g[1](z^[l])。
現在,你已在第一層進行了計算,此時 Batch 歸一化發生在𝑧的計算和𝑎之間,接下來,你需要應用 a [ 1 ] a^{[1]} a[1]值來計算 z [ 2 ] z^{[2]} z[2],此過程是由 w [ 2 ] w^{[2]} w[2]和 b [ 2 ] b^{[2]} b[2]控制的。與你在第一層所做的類似,你會將 z [ 2 ] z^{[2]} z[2]進行 Batch 歸一化,現在我們簡稱 BN,這是由下一層的 Batch 歸一化參數所管制的,即 β [ 2 ] \beta^{[2]} β[2]和 γ [ 2 ] \gamma^{[2]} γ[2],現在你得到 z ^ [ 2 ] \hat{z}^{[2]} z^[2],再通過激活函數計算出 a [ 2 ] a^{[2]} a[2]等等。
所以需要強調的是 Batch 歸一化是發生在計算𝑧和𝑎之間的。直覺就是,與其應用沒有歸一化的𝑧值,不如用歸一過的 z ^ \hat{z} z^,這是第一層( z ^ [ 1 ] \hat{z}^{[1]} z^[1])。第二層同理,與其應用沒有規范過的 z [ 2 ] z^{[2]} z[2]值,不如用經過方差和均值歸一后的 z ^ [ 2 ] \hat{z}^{[2]} z^[2]。所以,你網絡的參數就會是 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 歸一化的每一層而言。需要澄清的是,請注意,這里的這些 β \beta β( β [ 1 ] \beta^{[1]} β[1], β [ 2 ] \beta^{[2]} β[2]等等)和超參數 β \beta β沒有任何關系,下一張幻燈片中會解釋原因,后者是用于 Momentum 或計算各個指數的加權平均值。Adam 論文的作者,在論文里用 β \beta β代表超參數。Batch 歸一化論文的作者,則使用 β \beta β代表此參數( β [ 1 ] \beta^{[1]} β[1], β [ 2 ] \beta^{[2]} β[2]等等),但這是兩個完全不同的 β \beta β。我在兩種情況下都決定使用 β \beta β,以便你閱讀那些原創的論文,但 Batch 歸一化學習參數 β [ 1 ] \beta^{[1]} β[1], β [ 2 ] \beta^{[2]} β[2]等等和用于 Momentum、Adam、RMSprop 算法中的𝛽不同。
所以現在,這是你算法的新參數,接下來你可以使用想用的任何一種優化算法,比如使用梯度下降法來執行它。
舉個例子,對于給定層,你會計算 d β [ l ] d\beta^{[l]} dβ[l],接著更新參數 β \beta β為 β [ l ] \beta^{[l]} β[l] = β [ l ] \beta^{[l]} β[l] ? α d β [ l ] \alpha d\beta^{[l]} αdβ[l]。你也可以使用 Adam 或 RMSprop 或 Momentum,以更新參數 β \beta β和𝛾,并不是只應用梯度下降法。
即使在之前的視頻中,我已經解釋過 Batch 歸一化是怎么操作的,計算均值和方差,減去均值,再除以方差,如果它們使用的是深度學習編程框架,通常你不必自己把 Batch 歸一化步驟應用于 Batch 歸一化層。因此,探究框架,可寫成一行代碼,比如說,在 TensorFlow框架中,你可以用這個函數(tf.nn.batch_normalization)來實現 Batch 歸一化,我們稍后講解,但實踐中,你不必自己操作所有這些具體的細節,但知道它是如何作用的,你可以更好的理解代碼的作用。但在深度學習框架中,Batch 歸一化的過程,經常是類似一行代碼的東西。
所以,到目前為止,我們已經講了 Batch 歸一化,就像你在整個訓練站點上訓練一樣,或就像你正在使用 Batch 梯度下降法。
實踐中,Batch 歸一化通常和訓練集的 mini-batch 一起使用。你應用 Batch 歸一化的方式就是,你用第一個 mini-batch(X^{{1}}),然后計算 z [ 1 ] z^{[1]} z[1],這和上張幻燈片上我們所做的一樣,應用參數 w [ 1 ] w^{[1]} w[1]和 b [ 1 ] b^{[1]} b[1],使用這個 m i n i ? b a t c h ( X 1 ) mini-batch(X^{{1}}) mini?batch(X1)。接著,繼續第二個 mini-batch(X^{{2}}),接著Batch 歸一化會減去均值,除以標準差,由 β [ 1 ] \beta^{[1]} β[1]和 γ [ 1 ] \gamma^{[1]} γ[1]重新縮放,這樣就得到了 z ^ [ 1 ] \hat{z}^{[1]} z^[1],而所有的這些都是在第一個 mini-batch 的基礎上,你再應用激活函數得到 a [ 1 ] a^{[1]} a[1]。然后用 w [ 2 ] w^{[2]} w[2]和 b [ 2 ] b^{[2]} b[2]計算 z [ 2 ] z^{[2]} z[2],等等,所以你做的這一切都是為了在第一個 mini-batch( X 1 X^{{1}} X1)上進行一步梯度下降法。
類似的工作,你會在第二個 mini-batch(KaTeX parse error: Expected 'EOF', got '}' at position 7: X^[{2}}?)上計算 z [ 1 ] z^{[1]} z[1],然后用 Batch 歸一化來計算 z ^ [ 1 ] \hat{z}^{[1]} z^[1],所以 Batch 歸一化的此步中,你用第二個 mini-batch(KaTeX parse error: Expected 'EOF', got '}' at position 7: X^[{2}}?)中的數據使 z ^ [ 1 ] \hat{z}^{[1]} z^[1]歸一化,這里的 Batch 歸一化步驟也是如此,讓我們來看看在第二個 mini-batch( X 2 X^{{2}} X2)中的例子,在mini-batch 上計算 z [ 1 ] z^{[1]} z[1]的均值和方差,重新縮放的 β \beta β和 γ \gamma γ得到 z [ 1 ] z^{[1]} z[1],等等。
然后在第三個 mini-batch( X 3 X^{{3}} X3)上同樣這樣做,繼續訓練。
現在,我想澄清此參數的一個細節。先前我說過每層的參數是 w [ l ] w^{[l]} w[l]和 b [ l ] b^{[l]} b[l],還有 β [ l ] \beta^{[l]} β[l]和 γ [ l ] \gamma^{[l]} γ[l],請注意計算𝑧的方式如下, z [ l ] z^{[l]} z[l] = w [ l ] a [ l ? 1 ] + b [ l ] w^{[l]}a^{[l?1]} + b^{[l]} w[l]a[l?1]+b[l],但 Batch 歸一化做的是,它要看這個 mini-batch,先將 z [ l ] z^{[l]} z[l]歸一化,結果為均值 0 和標準方差,再由 β \beta β和 γ \gamma γ重縮放,但這意味著,無論 b [ l ] b^{[l]} b[l]的值是多少,都是要被減去的,因為在 Batch 歸一化的過程中,你要計算 z [ l ] z^{[l]} z[l]的均值,再減去平均值,在此例中的 mini-batch 中增加任何常數,數值都不會改變,因為加上的任何常數都將會被均值減去所抵消。
所以,如果你在使用 Batch 歸一化,其實你可以消除這個參數( b [ l ] b^{[l]} b[l]),或者你也可以,暫時把它設置為 0,那么,參數變成 z [ l ] z^{[l]} z[l] = w [ l ] a [ l ? 1 ] w^{[l]}a^{[l?1]} w[l]a[l?1],然后你計算歸一化的 z [ l ] z^{[l]} z[l], z ^ [ l ] \hat{z}^{[l]} z^[l] = γ [ l ] \gamma^{[l]} γ[l] z [ l ] z^{[l]} z[l]+ β [ l ] \beta^{[l]} β[l],你最后會用參數 β [ l ] \beta^{[l]} β[l],以便決定 z ^ [ l ] \hat{z}^{[l]} z^[l]的取值,這就是原因。
所以總結一下,因為 Batch 歸一化超過了此層 z [ l ] z^{[l]} z[l]的均值,𝑏[𝑙]這個參數沒有意義,所以,你必須去掉它,由 β [ l ] \beta^{[l]} β[l]代替,這是個控制參數,會影響轉移或偏置條件。
最后,請記住 z [ l ] z^{[l]} z[l]的維數,因為在這個例子中,維數會是( n [ l ] n^{[l]} n[l], 1), β [ l ] \beta^{[l]} β[l]的尺寸為( n [ l ] n^{[l]} n[l], 1),如果是 l 層隱藏單元的數量,那 β [ l ] \beta^{[l]} β[l]和 γ [ l ] \gamma^{[l]} γ[l]的維度也是( n [ l ] n^{[l]} n[l], 1),因為這是你隱藏層的數量,你有 n [ l ] n^{[l]} n[l]隱藏單元,所以 β [ l ] \beta^{[l]} β[l]和 γ [ l ] \gamma^{[l]} γ[l]用來將每個隱藏層的均值和方差縮放為網絡想要的值。
讓我們總結一下關于如何用 Batch 歸一化來應用梯度下降法,假設你在使用 mini-batch梯度下降法,你運行𝑡 = 1到 batch 數量的 for 循環,你會在 mini-batch X t X^{{t}} Xt上應用正向 prop,每個隱藏層都應用正向 prop,用 Batch 歸一化代替 z [ l ] z^{[l]} z[l]為 z ^ [ l ] \hat{z}^{[l]} z^[l]。接下來,它確保在這個 mini-batch 中,𝑧值有歸一化的均值和方差,歸一化均值和方差后是 z ^ [ l ] \hat{z}^{[l]} z^[l],然后,你用反向 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]。盡管嚴格來說,因為你要去掉𝑏,這部分其實已經去掉了。最后,你更新這些參數: w [ l ] w^{[l]} w[l]= w [ l ] ? α d w [ l ] w^{[l]} ? \alpha dw^{[l]} w[l]?αdw[l],和以前一樣, β [ l ] \beta^{[l]} β[l]= β [ l ] ? α d β [ l ] \beta^{[l]} ?\alpha d\beta^{[l]} β[l]?αdβ[l],對于𝛾也是如此 γ [ l ] \gamma^{[l]} γ[l]= γ [ l ] ? α d γ [ l ] \gamma^{[l]} ? \alpha d\gamma^{[l]} γ[l]?αdγ[l]。
如果你已將梯度計算如下,你就可以使用梯度下降法了,這就是我寫到這里的,但也適用于有 Momentum、RMSprop、Adam 的梯度下降法。與其使用梯度下降法更新 mini-batch,你可以使用這些其它算法來更新,我們在之前幾個星期中的視頻中討論過的,也可以應用其它的一些優化算法來更新由 Batch 歸一化添加到算法中的 β \beta β 和 γ \gamma γ參數。
我希望,你能學會如何從頭開始應用 Batch 歸一化,如果你想的話。如果你使用深度學習編程框架之一,我們之后會談。希望,你可以直接調用別人的編程框架,這會使 Batch歸一化的使用變得很容易。
現在,以防 Batch 歸一化仍然看起來有些神秘,尤其是你還不清楚為什么其能如此顯著的加速訓練,我們進入下一個視頻,詳細討論 Batch 歸一化為何效果如此顯著,它到底在做什么。