天天看點

動手學深度學習(十六)——數值穩定性和模型初始化(公式說明)

文章目錄

    • 一、數值穩定性——梯度消失和梯度爆炸
    • 二、多層感覺機器(MLP)中說明梯度爆炸和梯度消失
      • 2.1 梯度爆炸
        • 梯度爆炸的問題
      • 2.2 梯度消失
        • 梯度消失的問題
      • 2.3總結
    • 如何讓訓練更加穩定?
    • 三、模型初始化和激活函數
      • 3.1 權重初始化
      • 3.2 讓每一層的方差都是一個常數
        • Xavier初始化:以多層感覺機為例
        • 假設線性的激活函數
      • 3.3 總結

一、數值穩定性——梯度消失和梯度爆炸

考慮一個具有 L L L層、輸入 x \mathbf{x} x和輸出 o \mathbf{o} o的深層網絡。每一層 l l l由變換 f l f_l fl​定義,該變換的參數為權重 W ( l ) \mathbf{W}^{(l)} W(l),其隐藏變量是 h ( l ) \mathbf{h}^{(l)} h(l)(令 h ( 0 ) = x \mathbf{h}^{(0)} = \mathbf{x} h(0)=x)。

考慮有L層的網絡可以表示為:

h ( l ) = f l ( h ( l − 1 ) )  是以  o = l o s s ∗ f L ∗ … ∗ f 1 ( x ) . \mathbf{h}^{(l)} = f_l (\mathbf{h}^{(l-1)}) \text{ 是以 } \mathbf{o} = loss * f_L * \ldots * f_1(\mathbf{x}). h(l)=fl​(h(l−1)) 是以 o=loss∗fL​∗…∗f1​(x).

計算損失loss關于任何一組參數 W ( l ) \mathbf{W}^{(l)} W(l)的梯度寫為下式:

∂ l o s s ∂ w l = ∂ l o s s ∂ h L ∂ h L ∂ h L − 1 . . . ∂ h l + 1 ∂ h l ∂ h l ∂ w l \frac{\partial loss}{\partial w^l} = \frac{\partial loss}{\partial h^L} \frac{\partial h^L}{\partial h^{L-1}} ... \frac{\partial h_{l+1}}{\partial h^l} \frac{\partial h^l}{\partial w^l} ∂wl∂loss​=∂hL∂loss​∂hL−1∂hL​...∂hl∂hl+1​​∂wl∂hl​

換言之,該梯度是 L − l L-l L−l個矩陣 M ( L ) ⋅ … ⋅ M ( l + 1 ) \mathbf{M}^{(L)} \cdot \ldots \cdot \mathbf{M}^{(l+1)} M(L)⋅…⋅M(l+1)與梯度向量 v ( l ) \mathbf{v}^{(l)} v(l)的乘積。是以,我們容易受到數值下溢問題的影響,當将太多的機率乘在一起時,這些問題經常會出現。在處理機率時,一個常見的技巧是切換到對數空間,即将數值表示的壓力從尾數轉移到指數。不幸的是,我們上面的問題更為嚴重:最初,矩陣 M ( l ) \mathbf{M}^{(l)} M(l) 可能具有各種各樣的特征值。他們可能很小,也可能很大,他們的乘積可能非常大,也可能非常小。

不穩定梯度帶來的風險不止在于數值表示。不穩定梯度也威脅到我們優化算法的穩定性。我們可能面臨一些問題:

  1. 要麼是 梯度爆炸(gradient exploding)問題:參數更新過大,破壞了模型的穩定收斂;
  2. 要麼是 梯度消失(gradient vanishing)問題:參數更新過小,在每次更新時幾乎不會移動,導緻無法學習。

二、多層感覺機器(MLP)中說明梯度爆炸和梯度消失

f l ( h l − 1 ) = σ ( W l h l − 1 ) (1) f_l(h^{l-1}) = \sigma(W^lh^{l-1}) \tag{1} fl​(hl−1)=σ(Wlhl−1)(1) σ \sigma σ 是激活函數

∂ h l ∂ h l − 1 = d i a g ( σ ′ ( W l h l − 1 ) ) ( W l ) T (2) \frac{\partial h^l}{\partial h^{l-1}} = diag(\sigma '(W^lh^{l-1}))(W^l)^T \tag{2} ∂hl−1∂hl​=diag(σ′(Wlhl−1))(Wl)T(2)

∏ i = l L − 1 ∂ h i + 1 ∂ h i = ∏ i = l L − 1 d i a g ( σ ′ ( W l h l − 1 ) ) ( W l ) T (3) \prod_{i=l}^{L-1}\frac{\partial h^{i+1}}{\partial h^{i}} = \prod_{i=l}^{L-1}diag(\sigma '(W^lh^{l-1}))(W^l)^T \tag{3} i=l∏L−1​∂hi∂hi+1​=i=l∏L−1​diag(σ′(Wlhl−1))(Wl)T(3)

2.1 梯度爆炸

使用relu作為激活函數

σ ( x ) = m a x ( 0 , x ) a n d σ ′ ( x ) = { 1 , x > 0 0 , o t h e r w i s e (4) \sigma(x) = max(0,x) \quad and \quad \sigma '(x) = \begin{cases} 1,\quad x>0\\ 0, \quad otherwise \end{cases} \tag{4} σ(x)=max(0,x)andσ′(x)={1,x>00,otherwise​(4)

  • ∏ i = l L − 1 ∂ h i + 1 ∂ h i = ∏ i = l L − 1 d i a g ( σ ′ ( W l h l − 1 ) ) ( W l ) T \prod_{i=l}^{L-1}\frac{\partial h^{i+1}}{\partial h^{i}} = \prod_{i=l}^{L-1}diag(\sigma '(W^lh^{l-1}))(W^l)^T ∏i=lL−1​∂hi∂hi+1​=∏i=lL−1​diag(σ′(Wlhl−1))(Wl)T  的一些元素來自  ∏ i = l L − 1 ( W i ) T \prod_{i=l}^{L-1}(W^i)^T ∏i=lL−1​(Wi)T   如果

    L-l

    很大,最終得到的梯度的值非常大
M = torch.normal(0, 1, size=(4, 4))
print('一個矩陣 \n', M)
for i in range(100):
    M = torch.mm(M, torch.normal(0, 1, size=(4, 4)))

print('乘以100個矩陣後\n', M)
           
動手學深度學習(十六)——數值穩定性和模型初始化(公式說明)

梯度爆炸的問題

  1. 超出值域(infinity):對于16位浮點數尤其嚴重(數值區間為:6e5 - -6e4)
  2. 對學習率非常敏感
    • 學習了太大 -> 大參數值 ->更大的梯度
    • 學習率太小 -> 訓練無進展
    • 需要在訓練的過程中不斷調整學習率

2.2 梯度消失

使用sigmoid作為激活函數:

σ ( x ) = 1 1 − e x (5) \sigma (x) = \frac{1}{1-e^x} \tag{5} σ(x)=1−ex1​(5)

sigmoid激活函數的導數為:

σ ′ ( x ) = σ ( x ) ( 1 − σ ( x ) ) (6) \sigma '(x) = \sigma (x)(1-\sigma(x)) \tag{6} σ′(x)=σ(x)(1−σ(x))(6)

∏ i = l L − 1 ∂ h i + 1 ∂ h i = ∏ i = l L − 1 d i a g ( σ ′ ( W l h l − 1 ) ) ( W l ) T \prod_{i=l}^{L-1}\frac{\partial h^{i+1}}{\partial h^{i}} = \prod_{i=l}^{L-1}diag(\sigma '(W^lh^{l-1}))(W^l)^T ∏i=lL−1​∂hi∂hi+1​=∏i=lL−1​diag(σ′(Wlhl−1))(Wl)T   的元素是

L-l

個小數值進行乘 0. 8 100 ≈ 2 × 1 0 − 10 0.8^{100} \approx 2 \times 10^{-10} 0.8100≈2×10−10

# 下面這是sigmoid激活函數的圖像和其導數圖像,可以看到sigmoid函數的導數在輸入較大的時候輸出接近于0
%matplotlib inline
import torch
from d2l import torch as d2l

x = torch.arange(-8.0, 8.0, 0.1, requires_grad=True)
y = torch.sigmoid(x)
y.backward(torch.ones_like(x))

d2l.plot(x.detach().numpy(), [y.detach().numpy(), x.grad.numpy()],
         legend=['sigmoid', 'gradient'], figsize=(4.5, 2.5))
           
動手學深度學習(十六)——數值穩定性和模型初始化(公式說明)

梯度消失的問題

  1. 梯度值變為0(對16位浮點數非嚴重)
  2. 訓練沒有進展(無論怎麼選擇學習率都是沒有用的)
  3. 對于底層影響巨大
    • 一個模型可能僅僅隻有頂層訓練得較好
    • 限制了網絡的深度

2.3總結

  1. 當數值過大或者過小的時候都會導緻數值問題
  2. 常發生在深度模型之中,因為其會對n個數進行累乘

如何讓訓練更加穩定?

  1. 讓梯度值在合理的範圍之内(限制)
  2. 将乘法變為加法(梯度計算就會由連乘變為累加):ResNet,LSTM
  3. 歸一化(梯度歸一化、梯度裁減)
  4. 合理的權重初始化和激活函數

三、模型初始化和激活函數

目前為止,模型的參數都是根據某種預先指定的分布設計的,我們認為是理所當然的,卻忽略了如何作出這些選擇的細節。

但是,初始化方案的選擇在神經網絡學習中起着非常重要的作用,其對保持數值穩定性至關重要。

初始化方案的選擇和非線性激活函數的選擇相結合,決定了優化算收斂的速度有多塊,糟糕的選擇會導緻我們在訓練時遇到梯度爆炸或者梯度消失。

3.1 權重初始化

在合理值的區間随機初始化參數

在訓練開始的時候更容易有數值不穩定

  • 遠離最優解的地方損失函數表面可能很複雜
  • 最優解附近比表面會比較平

使用 N ( 0 , 0.01 ) N(0,0.01) N(0,0.01)初始化小網絡沒有問題,但是不能保證深度神經網絡

3.2 讓每一層的方差都是一個常數

  1. 将每層的輸出和梯度都看作随機變量
  2. 讓它們的均值和方差都保持一緻

正向

E [ h i l ] = 0 V a r [ h i l ] = a (3.1) E[h_{i}^{l}] = 0 \quad Var[h_{i}^{l}] = a \tag{3.1} E[hil​]=0Var[hil​]=a(3.1)

反向

E [ ∂ L o s s h i l ] = 0 V a r [ ∂ L o s s h i l ] = b (3.2) E[\frac{\partial{Loss}}{h_{i}^{l}}] = 0 \quad Var[\frac{\partial{Loss}}{h_{i}^{l}}] = b \tag{3.2} E[hil​∂Loss​]=0Var[hil​∂Loss​]=b(3.2)

Xavier初始化:以多層感覺機為例

如果不加上非線性全連接配接層:該層 n i n n_\mathrm{in} nin​輸入 x j x_j xj​及其相關權重 w i j w_{ij} wij​,輸出由下式給出

o i = ∑ j = 1 n i n w i j x j (3.3) o_{i} = \sum_{j=1}^{n_\mathrm{in}} w_{ij} x_j \tag{3.3} oi​=j=1∑nin​​wij​xj​(3.3)

權重 w i j w_{ij} wij​都是從同一分布中獨立抽取的。此外,讓我們假設該分布具有零均值和方差 σ 2 \sigma^2 σ2。請注意,這并不意味着分布必須是高斯的,隻是均值和方差需要存在。現在,讓我們假設層 x j x_j xj​的輸入也具有零均值和方差 γ 2 \gamma^2 γ2,并且它們獨立于 w i j w_{ij} wij​并且彼此獨立。在這種情況下,我們可以按如下方式計算 o i o_i oi​的平均值和方差:

E [ o i ] = ∑ j = 1 n i n E [ w i j x j ] = ∑ j = 1 n i n E [ w i j ] E [ x j ] = 0 , V a r [ o i ] = E [ o i 2 ] − ( E [ o i ] ) 2 = ∑ j = 1 n i n E [ w i j 2 x j 2 ] − 0 = ∑ j = 1 n i n E [ w i j 2 ] E [ x j 2 ] = n i n σ 2 γ 2 . (3.4) \begin{aligned} E[o_i] & = \sum_{j=1}^{n_\mathrm{in}} E[w_{ij} x_j] \\&= \sum_{j=1}^{n_\mathrm{in}} E[w_{ij}] E[x_j] \\&= 0,\tag{3.4} \\ \mathrm{Var}[o_i] & = E[o_i^2] - (E[o_i])^2 \\ & = \sum_{j=1}^{n_\mathrm{in}} E[w^2_{ij} x^2_j] - 0 \\ & = \sum_{j=1}^{n_\mathrm{in}} E[w^2_{ij}] E[x^2_j] \\ & = n_\mathrm{in} \sigma^2 \gamma^2. \end{aligned} E[oi​]Var[oi​]​=j=1∑nin​​E[wij​xj​]=j=1∑nin​​E[wij​]E[xj​]=0,=E[oi2​]−(E[oi​])2=j=1∑nin​​E[wij2​xj2​]−0=j=1∑nin​​E[wij2​]E[xj2​]=nin​σ2γ2.​(3.4)

保持方差不變的一種方法是設定 n i n σ 2 = 1 n_\mathrm{in} \sigma^2 = 1 nin​σ2=1。現在考慮反向傳播過程,我們面臨着類似的問題,盡管梯度是從更靠近輸出的層傳播的。使用與正向傳播相同的推理,我們可以看到,除非 n o u t σ 2 = 1 n_\mathrm{out} \sigma^2 = 1 nout​σ2=1,否則梯度的方差可能會增大,其中 n o u t n_\mathrm{out} nout​是該層的輸出的數量。這使我們進退兩難:我們不可能同時滿足這兩個條件。相反,我們隻需滿足:

1 2 ( n i n + n o u t ) σ 2 = 1  或等價于  σ = 2 n i n + n o u t . (3.5) \begin{aligned} \frac{1}{2} (n_\mathrm{in} + n_\mathrm{out}) \sigma^2 = 1 \text{ 或等價于 } \sigma = \sqrt{\frac{2}{n_\mathrm{in} + n_\mathrm{out}}}. \end{aligned} \tag{3.5} 21​(nin​+nout​)σ2=1 或等價于 σ=nin​+nout​2​

​.​(3.5)

這就是現在标準且實用的Xavier初始化的基礎,它以其提出者

Glorot.Bengio.2010

第一作者的名字命名。通常,Xavier初始化從均值為零,方差 σ 2 = 2 n i n + n o u t \sigma^2 = \frac{2}{n_\mathrm{in} + n_\mathrm{out}} σ2=nin​+nout​2​的高斯分布中采樣權重。我們也可以利用Xavier的直覺來選擇從均勻分布中抽取權重時的方差。注意均勻分布 U ( − a , a ) U(-a, a) U(−a,a)的方差為 a 2 3 \frac{a^2}{3} 3a2​。将 a 2 3 \frac{a^2}{3} 3a2​代入到 σ 2 \sigma^2 σ2的條件中,将得到初始化的建議:

U ( − 6 n i n + n o u t , 6 n i n + n o u t ) (3.6) U\left(-\sqrt{\frac{6}{n_\mathrm{in} + n_\mathrm{out}}}, \sqrt{\frac{6}{n_\mathrm{in} + n_\mathrm{out}}}\right) \tag{3.6} U(−nin​+nout​6​

​,nin​+nout​6​

​)(3.6)

盡管上述數學推理中,不存在非線性的假設在神經網絡中很容易被違反,但Xavier初始化方法在實踐中被證明是有效的。

假設線性的激活函數

假設 σ ( x ) = α x + β (3.7) \sigma(x) = \alpha x + \beta \tag{3.7} σ(x)=αx+β(3.7)

h ′ = W l h l − 1 a n d h l = σ ( h ′ ) (3.8) h' = W^lh^{l-1} \quad and \quad h^l = \sigma(h') \tag{3.8} h′=Wlhl−1andhl=σ(h′)(3.8)

那麼此層輸出的均值和方差可以表示為:

E [ h i l ] = E [ α h i ′ + β ] = β (3.9) E[h_{i}^{l}] = E[\alpha h_i'+\beta] = \beta \tag{3.9} E[hil​]=E[αhi′​+β]=β(3.9)

V a r [ h i l ] = E [ ( h i l ) 2 ] − E [ ( h i l ) ] 2 = E [ ( α h i ′ + β ) 2 ] − β 2 = E [ α 2 ( h i ′ ) 2 + 2 α β h i ′ + β 2 ] − β 2 = α 2 V a r [ h i ′ ] (3.10) \begin{aligned} Var[h_{i}^{l}] &= E[(h_{i}^{l})^2] - E[(h_{i}^{l})]^2\\ & = E[(\alpha h_i' +\beta)^2] - \beta ^2\\ & = E[\alpha ^2(h_i')^2 + 2\alpha \beta h_i' + \beta^2] - \beta^2\\ & = \alpha^2Var[h_i'] \end{aligned} \tag{3.10} Var[hil​]​=E[(hil​)2]−E[(hil​)]2=E[(αhi′​+β)2]−β2=E[α2(hi′​)2+2αβhi′​+β2]−β2=α2Var[hi′​]​(3.10)

如果說要讓激活函數不改變均值和方差,那麼: β = 0 α = 1 \beta = 0 \quad \alpha = 1 β=0α=1

那麼激活函數就等于本身了

反向一下看看

假設 σ ( x ) = α x + β (3.7) \sigma(x) = \alpha x + \beta \tag{3.7} σ(x)=αx+β(3.7)

h ′ = W l h l − 1 a n d h l = σ ( h ′ ) (3.8) h' = W^lh^{l-1} \quad and \quad h^l = \sigma(h') \tag{3.8} h′=Wlhl−1andhl=σ(h′)(3.8)

∂ l o s s ∂ h ′ = ∂ l o s s ∂ h l ( W l ) T a n d ∂ l o s s ∂ h l − 1 = α ∂ l o s s ∂ h ′ (3.11) \frac{\partial loss}{\partial{h'}} = \frac{\partial loss}{\partial{h^l}}(W^l)^T \quad and \quad \frac{\partial loss}{\partial{h^{l-1}}} = \alpha \frac{\partial loss}{\partial{h'}} \tag{3.11} ∂h′∂loss​=∂hl∂loss​(Wl)Tand∂hl−1∂loss​=α∂h′∂loss​(3.11)

E [ ∂ l o s s ∂ h i l − 1 ] = 0 (3.12) E[\frac{\partial{loss}}{\partial h_i^{l-1}}] = 0 \tag{3.12} E[∂hil−1​∂loss​]=0(3.12)

V a r [ ∂ l o s s ∂ h i l − 1 ] = α 2 V a r [ ∂ l o s s ∂ h j ′ ] (3.13) Var[\frac{\partial{loss}}{\partial h_i^{l-1}}] = \alpha^2Var[\frac{\partial loss}{\partial h_j'}] \tag{3.13} Var[∂hil−1​∂loss​]=α2Var[∂hj′​∂loss​](3.13)

那麼 β = 0 α = 1 \beta = 0 \quad \alpha = 1 β=0α=1

3.3 總結

  1. 合理的權重初始值和激活函數的選擇可以提升數值的穩定性

繼續閱讀