Batch Normlization(BN)
為什麼要進行 BN
防止深度神經網路,每一層得引數更新會導致上層的輸入資料發生變化,通過層層疊加,高層的輸入分佈變化會十分劇烈,這就使得高層需要不斷去重新適應底層的引數更新。為了訓好模型,我們需要非常謹慎地去設定學習率、初始化權重、以及儘可能細緻的引數更新策略。
另外對一些啟用函式具有飽和區,比如 sigmoid 函式的輸入較大和較小,此時的梯度很小,這會導致權重更新十分緩慢。又比如下圖的 tanh 函式:
如果輸入的數值沒有 BN 那麼資料可能在兩側的比較多,有了 BN 會將其對映至中間區域,可見其梯度較大,能更快收斂。其實這也防止了梯度消失。由於其不再由一個樣本來影響結果,每個樣本都會收到一個 batch 裡面的其他資料影響,實際上也是進行了正則化,防止過擬合。
常見的幾種 Normlization
Batch Normalization(BN)
公式如下:
\[\begin{aligned}
\mu_i &\leftarrow \frac{1}{NHW}\sum x_i \\
\sigma_i^2 &\leftarrow \frac{1}{NHW}\sum (x_i - u_i)^2 \\
\hat{x}_i &\leftarrow \frac{x_i - u_i}{\sqrt{\sigma_i^2 + \epsilon}} \\
y_i &\leftarrow \gamma \hat{x}_i + \beta = BN(x)
\end{aligned}
\]
不妨拿一個 shape 為 [N, C, H, W] tensor 的為例(即 batch = N),計算一個 batch 內各個 tensor 相同的通道的均值和方差,虛擬碼如下:
for i in range(input.shape[1]):
u = mean(input[:, i, :, :]) # 參與計算的資料為這個通道的所有資料,資料量為 N * H * W
sig_s = mean((input[:, i, :, :] - u)**2)
input[:, i, :, :] = (input[:, i, :, :] - u) / sqrt(sig_S + e)
input = gamma * input + beta # gamma with shape [1, C, 1, 1]
其缺點也容易看出來就是當 batch-size 太小統計時統計就無意義了,等於只統計了 batch 裡面的一個 tensor 的一個通道的資料。
Layer Normalization(LN)
公式如下:
\[\begin{aligned}
\mu_i &\leftarrow \frac{1}{CHW}\sum x_i \\
\sigma_i^2 &\leftarrow \frac{1}{CHW}\sum (x_i - u_i)^2 \\
\hat{x}_i &\leftarrow \frac{x_i - u_i}{\sqrt{sigma_i^2 + \epsilon}} \\
y_i &\leftarrow \gamma \hat{x}_i + \beta = LN(x)
\end{aligned}
\]
LN 不對 batch 的數值進行依賴,非常適用 RNN 網路加速,對於 RNN 來說,sequence 的長度不一致,換句話說 RNN 的深度不固定,不同的 time-step 需要儲存不同的 statics 特徵,可能存在一個特殊 sequence 比其長很多,這對統計 batch 的 BN 很不友好,LN 可以很好解決這個問題,虛擬碼如下:
for i in range(input.shape[0]):
u = mean(input[i]) # 參與計算的資料為這個通道的所有資料,資料量為 C * H * W
sig_s = mean((input[i] - u)**2)
input[i] = (input[i] - u) / sqrt(sig_S + e)
input = gamma * input + beta # gamma with shape [N, 1, 1, 1]
其實很簡單就是統計一個樣本的所有資訊。
Instance Normalization(IN)
公式如下:
\[\begin{aligned}
\mu_{ij} &\leftarrow \frac{1}{HW}\sum x_{ij} \\
\sigma_{ij}^2 &\leftarrow \frac{1}{HW}\sum (x_{ij} - u_{ij})^2 \\
\hat{x}_{ij} &\leftarrow \frac{x_{ij} - u_{ij}}{\sqrt{\sigma_{ij}^2 + \epsilon}} \\
y_{ij} &\leftarrow \gamma \hat{x}_{ij} + \beta = IN(x)
\end{aligned}
\]
其虛擬碼如下:
for i in range(input.shape[0]):
for j in range(input.shape[1]):
u = mean(input[i, j]) # 參與計算的資料為這個通道的所有資料,資料量為 H * W
sig_s = mean((input[i, j] - u)**2)
input[i, j] = (input[i, j] - u) / sqrt(sig_S + e)
input = gamma * input + beta # gamma with shape [N, C, 1, 1]
IN 是對每個影像的每個通道進行歸一化,其實有點像 BN 的 batch 為 1 的時候,常常用於影像的風格轉換。
Group Normalization(GN)
公式如下:
\[\begin{aligned}
\mu_{ij} &\leftarrow \frac{1}{(C // G)HW}\sum x_{ij} \\
\sigma_{ij}^2 &\leftarrow \frac{1}{(C // G)HW}\sum (x_{ij} - u_{ij})^2 \\
\hat{x}_{ij} &\leftarrow \frac{x_{ij} - u_{ij}}{\sqrt{\sigma_{ij}^2 + \epsilon}} \\
y_{ij} &\leftarrow \gamma \hat{x}_{ij} + \beta = GN(x)
\end{aligned}
\]
其虛擬碼如下:
N, C, H, W = input.shape
assert C % G == 0
input = input.reshape([N, G, C // G, H, W])
for i in range(N):
for j in range(G):
u = mean(input[i, j]) # 參與計算的資料為這個通道的所有資料,資料量為 C // G * H * W
sig_s = mean((input[i, j] - u)**2)
input[i, j] = (input[i, j] - u) / sqrt(sig_S + e)
input = input.reshape([N, C, H, W])
input = gamma * input + beta # gamma with shape [1, C, 1, 1]
GN 在 batch-size 比較小的時候也能奏效,原因就是因為它通過把通道數來進行分組使得在統計的時候,即便 batch-size 比較小也能統計到比較多的其他樣本或者自己其他通道的資訊。
權重初始化
初始化的作用
在深度學習中,神經網路的權重初始化方法(weight initialization)對模型的收斂速度和效能有著至關重要的影響。模型的訓練,簡而言之,就是對權重引數 W 的不停迭代更新,以期達到更好的效能。而隨著網路深度(層數)的增加,訓練中極易出現梯度消失或者梯度爆炸等問題。
初始化的結果基本條件
首先,我們不能讓權重的梯度為 0,很顯然權重梯度為 0,權重將不再更新。然而又知道有些啟用函式是有飽和區的。簡而言之,在這個區值的梯度基本為 0,很難進行梯度更新。引數初始化需要注意:
全零初始化是否可行
線上性迴歸,logistics 迴歸的時候,基本上都是把引數初始化為 0,我們的模型也能夠很好的工作(可初始化為0的模型)。然後在神經網路中,把W初始化為 0 是不可以的。這是因為如果把 W 初始化 0,那麼在前向傳播過程中,每一層的神經元學到的東西都是一樣的(啟用值均為 0),而在 bp 的時候,不同維度的引數會得到相同的更新,因為他們的 gradient 相同,稱之為“對稱失效”。
以上的話可以簡單認為在神經網路的全零初始化會使引數更新一致,然後由於引數的值也都一樣,所以一層的所有引數退化為一個。然後沒有隱藏層或者邏輯迴歸時,可以將其全零初始化。
標準隨機初始化
這裡常用的有正態分佈、均勻分佈等。它們的引數均值都在 0 的附近,然後有正有負,一般會把引數設定為接近 0 的很小的隨機數。隨機初始化也有缺點:當神經網路的層數增多時,會發現越往後面的層的啟用函式(使用 tanh )的輸出值幾乎都接近於 0:
總結來說,一般的隨機初始化存在後層網路啟用函式的輸出值趨近於 0 的問題,且網路輸出資料分佈的方差會受每層神經元個數的影響(隨之改變)。雖然上訴的輸出資料均值都接近於 0,但是由於方差的改變導致最後整個輸出資料也接近於 0。針對這些問題,Glorot 等人提出在初始化的同時加上對方差大小的規範化。這樣不僅獲得了更快的收斂速度,而且維持了輸入輸出資料分佈方差的一致性,也避免了後面層的啟用函式的輸出值趨向於 0 的問題。
Glorot 條件
優秀的初始化應該保證以下兩個條件:
♠ 各個層的啟用值 h(輸出值) 的方差要保持一致,即 \(\forall (i,j): Var(h^i) = Var(h^j)\)
♥各個層對狀態 z 的梯度的方差要保持一致,即 \(\forall (i,j): Var(\frac{\partial Cost}{\partial z^i}) = Var(\frac{\partial Cost}{\partial z^j})\)
其實是一個保證前向時資料基本分佈不變,一個保證反向時資料基本分佈不變
關於方差的三個事實
既然要保持上面的兩個方差在各個網路層中不改變,那也就是它實際上是會改變的,關於為什麼會改變的公式推導,後面詳細說明,這裡直接引入三個基本的客觀事實(兩有關一無關):
- 各個層啟用值 h(輸出值)的方差與網路的層數有關;
- 關於狀態 z 的梯度的方差與網路的層數有關;
- 各個層權重引數W的梯度的方差與層數無關;
可參見論文《Understanding the difficulty of training deep feedforward neural networks》
初始化的幾點要求
- 引數不能全部初始化為 0,也不能全部初始化同一個值;
- 最好保證引數初始化的均值為 0,正負交錯,正負引數大致上數量相等;
- 初始化引數不能太大或者是太小,引數太小會導致特徵在每層間逐漸縮小而難以產生作用,引數太大會導致資料在逐層間傳遞時逐漸放大而導致梯度消失發散,不能訓練;
Xavier 初始化
其認為各層的啟用值和狀態梯度的方差在傳播過程中的方差應該保持一致。即:
\[\begin{aligned}
\forall (i, j),Var(x^i) &= Var(x^j) \\
\forall (i, j),Var\Big(\frac{\partial Cost}{\partial y^i}\Big) &= Var \Big(\frac{\partial Cost}{\partial y^j}\Big)
\end{aligned}
\]
這兩個條件也稱為 Glorot 條件。首先給出關於狀態得梯度和關於權重的梯度及部分推導:
\[\begin{aligned}
\pmb{x}^{i+1} &= f(\pmb{y}^i) \\
\pmb{y}^{i+1} &= \pmb{W}^{i+1} \times \pmb{x}^{i+1} \\
\frac{\partial Cost}{\partial y^i_k} &= \frac{\partial Cost}{\partial \pmb{y}^{i+1}}\frac{\partial \pmb{y}^{i+1}}{\partial \pmb{x}^{i+1}} \frac{\partial \pmb{x}^{i+1}}{\partial f(\pmb{y}^i)} \frac{\partial f(\pmb{y}^i)}{\partial \pmb{y}^i} \frac{\partial \pmb{y}^i}{\partial y^i_k} \\
\frac{\partial Cost}{\partial w^i_{l,k}} &= \frac{\partial Cost}{\partial y^i_k} \frac{\partial y^i_k}{\partial w^i_{l,k}}
\end{aligned}
\]
首先 \(y^i_k\) 代表第 \(i\) 層的,輸出的第 \(k\) 個(目前先假設輸入輸出都是一維向量,且輸入的方差一致),\(f(x)\) 是啟用函式,另外做如下假設:
- 啟用函式對稱:便於假設每層的輸入均值為 0 (加上每層權重均值為 0,輸入均值也就為 0)
- \(f^{\prime}(0) = 1\)
- 初始時,狀態值都落線上性區域有 \(f(y^i_k) = y^i_k \quad f^{\prime}(y^i_k) = 1\)
將上式進行簡化:
\[\begin{aligned}
\frac{\partial Cost}{\partial y^i_k} &= \frac{\partial Cost}{\partial \pmb{y}^{i+1}}\frac{\partial \pmb{y}^{i+1}}{\partial \pmb{x}^{i+1}} \frac{\partial \pmb{x}^{i+1}}{\partial f(\pmb{y}^i)} \frac{\partial f(\pmb{y}^i)}{\partial \pmb{y}^i} \frac{\partial \pmb{y}^i}{\partial y^i_k} \\
&= \frac{\partial Cost}{\partial \pmb{y}^{i+1}} (\pmb{W}^{i+1})^{\top} \cdot 1 \cdot f^{\prime}(\pmb{y}^i) \cdot \pmb{e}^i_k \\
&= \frac{\partial Cost}{\partial \pmb{y}^{i+1}} (\pmb{W}^{i+1})^{\top} \cdot 1 \cdot 1 \cdot \pmb{e}^i_k \\
& = \frac{\partial Cost}{\partial \pmb{y}^{i+1}} (\pmb{W}^{i+1})^{\top}_{.,k} \\
\frac{\partial Cost}{\partial w^i_{k,l}} &= \frac{\partial Cost}{\partial y^i_k} \frac{\partial y^i_k}{\partial w^i_{k,l}} \\
&= \frac{\partial Cost}{\partial y^i_k} x^i_l
\end{aligned}
\]
首先推導一下每層的輸入與上一層的輸入方差的關係(注意我們是在一定假設下的,獨立分佈的兩個變數積的方差等於這兩個變數方差的積。同一層的輸入各個元素的方差是相同的,權重各個元素的方差是相同的):
\[\begin{aligned}
Var(x^i_k) &= Var(f(y^{i-1}_k)) \\
&= Var(y^{i-1}_k) \\
&= Var(\pmb{W}^{i-1}_{k,.} \times \pmb{x}^{i-1}) \\
&= Var(\sum_{l=1}^{n_{i-1}} W^{i-1}_{k,l} x^{i-1}_{l}) \\
&= \sum_{l=1}^{n_{i-1}} Var(W^{i-1}_{k,l})Var(x^{i-1}_{l}) \\
&= n_{i-1}Var(W^{i-1}_{k,l})Var(x^{i-1}_{l}) \\
\end{aligned}
\]
由於數值之間都是獨立同分布,根據上式可以推匯出
\[Var(x^{i+1}) =n_iVar(W^i)Var(x^i)
\]
由之前推導的梯度公式,我們同樣可以來推導相鄰層梯度的方差(注意反向傳播就是看這層的輸出元素個數了,即 \(n_{i+1}\):
\[\begin{aligned}
Var \Big(\frac{\partial Cost}{\partial y^i_k}\Big) & = Var \Big(\frac{\partial Cost}{\partial \pmb{y}^{i+1}} (\pmb{W}^{i+1})^{\top}_{.,k}\Big)\\
&=Var \Big(\sum_{l=1}^{n_{i+1}}\frac{\partial Cost}{\partial y^{i+1}_l}(W^{i+1})^{\top}_{l,k} \Big) \\
&=\sum_{l=1}^{n_{i+1}}Var \Big(\frac{\partial Cost}{\partial y^{i+1}_l}\Big)Var\Big((W^{i+1})^{\top}_{l,k} \Big) \\
&=n_{i+1} Var\Big(\frac{\partial Cost}{\partial y^{i+1}_l}\Big)Var\Big((W^{i+1})^{\top}_{l,k} \Big) \\
\Rightarrow Var \Big(\frac{\partial Cost}{\partial y^i}\Big) & = n_{i+1} Var\Big(\frac{\partial Cost}{\partial y^{i+1}}\Big)Var\Big(W^{i+1} \Big)
\end{aligned}
\]
對於一個 d 層的網路,則有:
\[\begin{aligned}
Var(x^{i}) &=Var(x^0)\prod_{j=1}^{i-1}n_jVar(W^{j}) \\
Var \Big(\frac{\partial Cost}{\partial y^i}\Big) & = Var\Big(\frac{\partial Cost}{\partial y^{d}}\Big)\prod_{j = i}^{d}n_{i} Var\Big(W^{i+1} \Big)
\end{aligned}
\]
綜上要想滿足各層的啟用值和狀態梯度的方差有:
\[\begin{aligned}
\forall i, 1 &=n_iVar(W^{i+1}) \\
\forall i, 1 &=n_{i+1}Var(W^{i+1}) \\
\end{aligned}
\]
將上兩式相加有:
\[Var(W^{i+1}) = \frac{2}{n_i + n_{i+1}}
\]
Kaiming 初始化
首先,我們來設定一些假設,並且複習幾個公式。
假設:
\[\begin{aligned}
E[W] &= 0 \\
E[X] &= 0 \\
E[\Delta Y] &= 0
\end{aligned}
\]
幾個獨立隨機變數之和的方差等於各變數的方差之和
\[Var(X_1 + \cdots + X_n) = Var(X_1) + \cdots + Var(X_n)
\]
如果為同分布的話,結果變為 \(nVar(X)\)。方差與期望之間的關係:
\[Var(X) = E(X^2) - (EX)^2
\]
兩個獨立變數乘積的方差,且各自期望為 0,協方差為 0
\[\begin{aligned}
Var(XY) &= E(X^2Y^2) - E(XY)^2 \\
&= E(X^2)E(Y^2) - E(X)^2E(Y)^2 \\
&= (Var(X) + E(X)^2)(Var(Y) + E(Y)^2) \\
& = Var(X)Var(Y)
\end{aligned}
\]
kaiming 初始化只包含卷積和 ReLU 函式,對於卷積,可以把卷積核當作全連線層的權重,然而每做一次卷積只是更換了一次“全連線層”的輸入。
前向傳播
因此在前向傳播時,可以簡化為
\[Y_l = W_lX_l + B_l
\]
其中,\(Y_{li}\) 代表第 \(l\) 層中第 \(i\) 位置的輸出,並使用 \(Y_l\) 指第 \(l\) 層中所有位置的輸出。假設某一位置的輸入 \(X_{li}\) 的 shape 為 \(n_{in} = k \times k \times c_{in}\),輸出通道為 \(c_{out}\)。對於某一個位置而言,\(W_{li}\) 有 shape \(c_{out} \times n_{in}\)。很容易知道,對於某個位置的有 $ c_{out}$ 個輸出,因此對於某個位置的某一個輸出有:
\[y_l = \sum^{n_{in}}_{i=0} w_{li}x_{li}
\]
由於輸入各值是同分布,權重也如此,因此有:
\[Var(y) = n_{in}Var(wx)
\]
由於 x 是上一層 relu 得到,期望不再為 0,但權重的期望是為 0 的。可得:
\[\begin{aligned}
Var(w_lx_l) &= E((w_lx_l)^2) - E(w_l)^2E(x_l)^2 \\
Var(w_lx_l) &= E(w_l^2)E(x_l^2) \\
Var(w_lx_l) &= Var(w_l^2)E(x_l^2) \\
\Rightarrow Var(y_l) &= n_{in}Var(w_l)E(x_l^2)
\end{aligned}
\]
根據網路得知 \(x_l = f(y_{l-1})\),其中 \(f\) 代表 ReLU 函式,有:
\[\begin{aligned}
E(x^2_l) = E(f^2(y_{l-1})) &= \int^{+\infty}_{-\infty} p(y_{l-1})f^2(y_{l-1}) dy_{l-1} \\
\because \quad &y_{l-1} \in (-\infty, 0), f(y_{l-1}) = 0 \\
&y_{l-1} \in (0, +\infty), f(y_{l-1}) = y_{l-1} \\
& = \int^{+\infty}_{0} p(y_{l-1})(y_{l-1})^2 dy_{l-1} \\
\Rightarrow E(x^2_l) &= \frac{1}{2} \int^{+\infty}_{-\infty} p(y_{l-1})(y_{l-1})^2 dy_{l-1} \\
& = \frac{1}{2} E(y_{l-1}^2)
\end{aligned}
\]
因為權重是在 0 周圍均勻分佈的,且均值為 0,所以易得 \(E(y) = 0\)。則可以得到 \(Var(y_{l-1}) = E(y_{l-1}^2)\)。帶入則有:
\[Var(y_l) = \frac{1}{2} n_{in}Var(w_l)Var(y_{l-1})
\]
要想滿足前後的方差相等,則有:
\[Var(w_l)= \frac{2}{n_{in}}
\]
反向傳播
首先文章中的 \(\Delta\) 作者應該想表達的是梯度,而不是差分的意思,同理易得其公式為
\[\begin{aligned}
Y_l &= W_lX_l + B_l \\
\because \quad \frac{\partial Loss}{\partial X_l} &= \frac{\partial Loss}{\partial Y_l}\frac{\partial Y_l}{\partial X_l} \\
\frac{\partial Loss}{\partial X_l} &= \frac{\partial Loss}{\partial Y_l} W_l^{\top} \\
\Rightarrow \Delta X_l &= W_l^{\top} \Delta Y_l
\end{aligned}
\]
由於 \(E(\Delta Y_l) = 0\),然後權重也是期望為 0,那易得 \(\Delta X_l\) 的期望也是為 0。接下來就是推導 \(\Delta X_{l+1}\) 與 \(\Delta Y_l\) 的關係。首先有:
\[\begin{aligned}
X_{l+1} &= f(Y_l) \\
\frac{\partial Loss}{\partial Y_{l}} &= \frac{\partial Loss}{\partial X_{l+1}}\frac{\partial X_{l+1}}{\partial Y_{l}} \\
\frac{\partial Loss}{\partial Y_{l}} &= \frac{\partial Loss}{\partial X_{l+1}}\frac{\partial f(Y_l)}{\partial Y_{l}} \\
\frac{\partial Loss}{\partial Y_{l}} &= \frac{\partial Loss}{\partial X_{l+1}} f^{\prime}(Y_l) \\
\Rightarrow \Delta Y_l &= f^{\prime}(Y_l) \Delta X_{l+1}
\end{aligned}
\]
這裡考慮的 ReLU 函式的導數一半為 0,一半為 1。假設各佔一半,於是有:
\[\begin{aligned}
E(\Delta Y_l) &= \frac{1}{2} \Delta X_{l+1} = 0 \\
Var(\Delta Y_l) &= E((\Delta Y_l)^2) \\
&= E((f^{\prime}(Y_l) \Delta X_{l+1})^2) \\
&= \frac{1}{2}E((0 \times \Delta X_{l+1})^2) + \frac{1}{2}E((1 \times \Delta X_{l+1})^2) \\
&= \frac{1}{2}Var(\Delta X_{l+1})
\end{aligned}
\]
同樣一個位置的 \(\Delta x_{li}\) 依然是由 $n_{out} = k \times k \times c_{in} $ 個 \(\Delta y_{lj}, j = 1,2, \dots, n_{out}\) 與相應權重相乘相加而成的。這樣則有:
\[\begin{aligned}
Var(\Delta x_{l+1}) &= n_{out}Var(w_l)Var(\Delta y_{l}) \\
&= \frac{1}{2} n_{out}Var(w_l)Var(\Delta x_{l}) \\
\Rightarrow Var(w_l) &= \frac{2}{n_{out}}
\end{aligned}
\]