深度學習中的歸一化方法總結(BN、LN、IN、GN)

  一般在神經網絡中會用到數據的歸一化,比如在卷積層後進行歸一化然後再下采樣然後再激活等。目前比較受歡迎的數據歸一化層有:BN(BatchNormalization),LN(LayerNormalization),IN(InstanceNormalization),GN(GroupNormalization)這4種。本篇文章主要是對比一下它們各自是怎麼計算的。
  先看對數據的歸一化是這麼操作的。其實就是先計算均值和方差然後再標準化即可。具體的對一個標量數據(xiRx_i∈R)在給定的數據集X=x1,x2,...,xmX=x_1,x_2,...,x_m中進行標準化是按如下進行計算的:
先計算給定數據集的均值和方差:μ=1mi=1mxi\mu=\frac1m\sum_{i=1}^{m}x_iσ2=1mi=1m(xiμ)2\sigma^2=\frac1m\sum_{i=1}^{m}(x_i-\mu)^2 然後對這個數據集中的每個數進行標準化(歸一化):x^=xiμσ2+ϵ\hat{x}=\frac{x_i-\mu}{\sqrt{\sigma^2+\epsilon}}
  BN、LN、IN、GN這4種歸一化方法的區別就是用於計算均值和方差的數據集不同。後面我以卷積層後跟歸一化來舉例,我叫需要進行標準化的值爲一個像素點,那麼數據集叫像素集。我們來看一下這4種方法它們計算均值和方差的像素集有啥區別。(藍色區域即爲該方法對應的計算一次均值和方差的像素集,當然最終是要將整個方塊按區域劃分分別進行一次歸一化)
在這裏插入圖片描述
  假如現在圖像先進行了卷積運算得到如上圖所示的激活狀態(N,C,H,W),其中N是樣本數,C爲通道數即特徵圖數。現在我對以上的激活狀態進行歸一化操作。
  對於BN,一個要計算均值和方差的像素集爲:所有樣本(一個batch的所有樣本)中有相同索引的特徵圖像素點集合爲一個計算均值和方差的像素集。如圖所示藍色區域爲一個像素集,在每一個像素集中先計算方差和均值然後對每一個像素進行歸一化即可完成這個像素集的歸一化。那麼要將整個輸入都BN完則需要對C個像素集分別進行歸一化。BN有點像在多個樣本的某一特徵上進行歸一化這樣的好處是減少了數據值間的差距,而LN有點像在某一個樣本的所有特徵上進行歸一化,由於不同的特徵可能量綱不同所以LN這種方式相比於BN不僅縮小了數值差異而且還避免了量綱的影響。由於BN它不僅是可進行前向歸一化還可以反向恢復爲近似原始輸入,在反向恢復中有兩個參數需要訓練γ\gammaβ\betayi=γxi^+βy_i=\gamma\hat{x_i}+\beta=>xix_i。看一下BN中有多少個參數。由於每個進行歸一化的像素集是不同的那麼各像素集的恢復參數也不會相同,故BN層會有2*C個參數。我們用Keras來看一下:

from keras.models import Sequential
from keras.layers import BatchNormalization
model = Sequential()
model.add(BatchNormalization(input_shape=(55,55,96)))
model.summary()
'''
結果:
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
batch_normalization_1 (Batch (None, 55, 55, 96)        384       
=================================================================
Total params: 384
Trainable params: 192
Non-trainable params: 192
_________________________________________________________________
'''

  可以看到參數爲384個,不等於2*96,爲啥?翻一下keras實現BN的代碼可以發現對於每一個像素集它有兩個可訓練參數gamma和beta,還有另外兩個參數moving_mean,moving_variance這兩個參數被設計爲不可訓練。所以384個參數是指這個BN層中所有的參數包括192個可訓練參數和192個不可訓練參數,從結果後面的彙總信息也可以看出Total params: 384 Trainable params: 192 Non-trainable params: 192。那麼爲啥Keras的BN層要設計另外兩個參數moving_mean,moving_variance?因爲:訓練時使用一個minibatch的訓練數據計算均值和方差然後標準化數據,在test的時候我們也希望作相同的處理,比較直接的方法是在訓練集上重新計算一遍統計量,但是,如果有1000w數據,這種計算就比較花費時間,而test的速度越快越好,所以在訓練的時候,順便就把均值和方差計算出來了,當然不是精確值,是近似值,這就是moving_mean和moving_variance,它們兩個是用來記錄訓練時均值和方差的偏移的,以便在測試時直接使用,故而他們倆不需要學習。
  對於LN,它的一個像素集爲一個樣本的所有特徵圖的像素集合。那麼對於整個batch的輸入歸一化它需要分別在N個像素集上進行歸一化操作才能完成。
  對於IN,它的一個像素集爲一個特徵圖像素點集合,那麼對於輸入需要進行N×C次的歸一化。對於GN,它的一個像素集爲一個樣本的一部分連續特徵圖的像素點集合。
GN實現:

def GroupNorm(x, gamma, beta, G, eps=1e − 5):
    # x: input features with shape [N,C,H,W]
    # gamma, beta: scale and offset, with shape [1,C,1,1]
    # G: number of groups for GN
    N, C, H, W = x.shape
    x = tf.reshape(x, [N, G, C // G, H, W])
    mean, var = tf.nn.moments(x, [2, 3, 4], keep dims=True)
    x = (x − mean) / tf.sqrt(var + eps)
    x = tf.reshape(x, [N, C, H, W])
    return x ∗ gamma + beta

  所以對給定的激活狀態作爲輸入(包括N,針對一個batch的輸入不是針對一個樣本)要對它進行歸一化,並不是在整個輸入像素集上進行一次歸一化,而是按區域分別歸一化。(對於一個batch的輸入BN需要C次,LN需要N次,IN需要N×C次,GN需要N×Cg\frac Cg次的歸一化)

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