Batch Normalization的通俗解釋
開始解釋Batch Normalization前先了解一個概念, Feature Scaling
Feature Scaling
如果特徵大小差的比較遠的話,loss function會很扁平,數值更大的feature的引數會對結果的影響更大,這樣在訓練過程中,不同的方向需要設定不同的學習率,這樣子會不太方便,這不是我們想看到的,所以我們通常會去做feature scaling。
圖片來自李宏毅老師BN教學影片
具體的操作很簡單,對每一維特徵,我們對每一個數據減去這維特徵的均值,再除以這位特徵的標準差,得到縮放後的新的特徵值,此時它的均值為0,方差為1。一般經過feature scaling之後,收斂速度會變快。
那麼在神經網路中又是什麼情況呢?
我們可以看到,其實在深度網路中,後一層的輸入其實是前一層的輸出。那麼我們在做feature scaling的時候,應該對每一層的輸入都去做一個feature scaling, 但是又不像傳統的機器學習,由於神經網路每一層的引數都在不斷變化,直接使用前面的feature scaling是不太合適的。所以我們需要一個新的技術,就是Batch Normalization了
Batch Normalization
GPU在訓練的時候,其實是拿了一打資料去訓練,它們之間是並行的,我們稱之為一個batch。
對於邏輯迴歸,我們只對輸入進行了歸一化(也就是feature scaling技術),而在DNN中,我們在
每一層的啟用函式前做batch normalization
。怎麼做呢,我們先算一個均值
和一個 標準差
,有
,
, 同時這裡的m不可以太小,然後我們對要透過經過啟用函式前的z值做一個batch normalization, 令
這就是BN的內容。這裡的分母本來應該是
,但為了防止它為0,我們加上一個一個
。通常對每一層我們都會做BN
在這個基礎上,可以對
繼續做一些變換,也就是
是神經網路的引數,是網路自己學習的。調整
,可以讓神經網路擁有不同的
。比如說當我設定
,那麼
。透過構造
,可以構造含其他均值和方差的z值。
訓練完神經網路,到了測試的時候,會出現一個問題,我們說
是透過一個batch的
算出來的,但是測試的時候是沒有batch的,那麼這兩個引數怎麼來呢?一種做法是把過去訓練時每個batch算出來的
都儲存下來,然後對這些
做加權平均,給最後幾次訓練的
更大的權重,因為此時的引數更接近於完成的模型。
Batch Normalization的好處
最後總結一下batch Normalization的好處,這些是在實踐中逐漸被證明了的:
減少了訓練時間,而且可以進行深層網路的訓練,同時可以使用更大的學習率
會減少梯度爆炸和梯度消失的問題,特別是對sigmoid, tanh這種啟用函式
BN使得學習過程更少收到初始化的影響
有對抗過擬合的作用,可以減少正則化的需求
為什麼BN這麼強
關於Batch Normalization為什麼可以幫助訓練,眾說紛紜。一種說法是它能減少“internal covariate shift (ICS)。“,不過在NIPS2018收錄論文How Does Batch Normalization Help Optimization? 反駁了這個觀點並提供了另一種解釋,本文取NIPS的這篇論文的觀點來說明。論文中提到並沒有發現BN跟internal covariate shift有半毛錢關係,實驗方法是加入了一個“noise batch normalization”的對照實驗,在batch normalization中加入噪聲,使得z發生協變數偏移,但是這樣的noise batch normalization的效果也遠優於未經BN的網路,由此反駁了ICS的觀點。
同時這篇論文計算了一下每次跟新引數後的梯度變化,結果發現加上BN的實驗組,ICS沒有變得更低,反而更高了,見下圖。總之就是啪啪打臉前人觀點,嗯。
論文中認為BN使得最佳化問題更加平滑,由此梯度的預測性更強,所以可以允許使用更大學習率,並且加快網路收斂。在使用BN後loss和gradient的Lipschitzness都提升了(也就是更平滑了)。