天天看點

Batch Normalization應該在激活函數之前使用還是激活函數之後使用

作者:資料學習DataLearner

Batch Normalization(BN)是深度學習領域最重要的技巧之一,最早由Google的研究人員提出。這個技術可以大大提高深度學習網絡的收斂速度。簡單來說,BN就是将每一層網絡進行歸一化,就可以提高整個網絡的訓練速度,并打亂訓練資料,提升精度。但是,BN的使用可以在很多地方,很多人最大的困惑是放在激活函數之前還是激活函數之後使用,著名機器學習領域的部落客Santiago總結了這部分需要注意的内容。

結論可以直接看第三部分:

  • 一、BN簡介
  • 二、BN的使用方式
  • 三、BN層是在激活函數之前還是之後使用?

一、BN簡介

首先是對BN的簡短介紹:Batch Normalization在每一次疊代訓練的時候,針對每一個mini-batch的資料,對每一層的輸入進行normalize。

二、BN的使用方式

以Keras為例,BN使用如下:

model = Sequential([
    Dense(128, input_shape=(4,), activation="relu"),
    BatchNormalization(),
    Dense(10, activation="softmax")
])           

這裡我們是在輸入層之前,激活函數之後加了一個BN的層。注意,也有人的寫法如下:

model = Sequential([
    Dense(128, input_shape=(4,)),
    BatchNormalization(),
    Activation(activations.relu),
    Dense(10, activation="softmax")
])           

這種寫法和上面最大的差別是BN層的位置從激活函數之後變成了在激活函數之前計算。這二者雖然看起來簡單,但是差別很大。

三、BN層是在激活函數之前還是之後使用?

如果我們在激活函數之前增加BN層,那麼我們可以完整地利用激活函數的輸出。例如,Sigmoid可以将BN的輸出限制在0-1的範圍内。這種方式也有原作者的解釋(也是原作者推薦的方式):

Batch Normalization應該在激活函數之前使用還是激活函數之後使用

意思是在激活函數之前使用BN可以輸出更加穩定的分布結果,讓激活函數更好地發揮作用。但是,如果在激活函數之後使用BN可以使得下一層網絡的輸入是一個normalized的輸入,可以讓所有的值都在相同的尺度範圍内。這是Paperspace blog裡面提到的(參考連結:Intro to Optimization in Deep Learning: Busting the Myth About Batch Normalization):

Batch Normalization應該在激活函數之前使用還是激活函數之後使用

作者認為,放在激活函數之後在實際訓練中有更好的效果。

這沒有标準的答案,著名深度學習學者Sebastian Raschka在推特上釋出的調查,讓大家選擇BN的使用方式,結果顯示,45%的人在激活函數之前使用,但也有30%的人在激活函數之後使用,剩下的人不适用或者treat pre/post as hparam。

Batch Normalization應該在激活函數之前使用還是激活函數之後使用

那麼實際情況中,應該是需要測試一下最好,不同的場景也許有不同的結論。

原文詳情:Batch Normalization應該在激活函數之前使用還是激活函數之後使用? | 資料學習者官方網站(Datalearner)

繼續閱讀