『教程』Batch Normalization 層介紹html
知乎:詳解深度學習中的Normalization,BN/LN/WNpython
獨立同分布的數據能夠簡化常規機器學習模型的訓練、提高機器學習模型的預測能力網絡
去除特徵之間的相關性 —> 獨立;框架
使得全部特徵具備相同的均值和方差 —> 同分布。dom
深度神經網絡涉及到不少層的疊加,而每一層的參數更新會致使上層的輸入數據分佈發生變化,經過層層疊加,高層(抽象程度高)的輸入分佈變化會很是劇烈,這就使得高層須要不斷去從新適應底層的數據更新機器學習
Google 將這一現象總結爲 Internal Covariate Shif:ide
統計機器學習中的一個經典假設是「源空間(source domain)和目標空間(target domain)的數據分佈(distribution)是一致的」。若是不一致,那麼就出現了新的機器學習問題,如 transfer learning / domain adaptation 等。函數
而 covariate shift 就是分佈不一致假設之下的一個分支問題,它是指源空間和目標空間的條件機率是一致的,可是其邊緣機率不一樣,即:對全部,post
可是學習
你們細想便會發現,的確,對於神經網絡的各層輸出,因爲它們通過了層內操做做用,各層的輸入信號的分佈顯然不一樣,並且差別會隨着網絡深度增大而增大,但是它們所能「指示」的樣本標記(label)仍然是不變的,這便符合了covariate shift的定義。因爲是對層間信號的分析,也便是「internal」的來由。
問題描述簡而言之,每一個神經元的輸入數據再也不是「獨立同分布」。
其一,上層參數須要不斷適應新的輸入數據分佈,下降學習速度。
其二,下層輸入的變化可能趨向於變大或者變小,致使上層落入飽和區,使得學習過早中止。
其三,每層的更新都會影響到其它層,所以每層的參數更新策略須要儘量的謹慎。
咱們以神經網絡中的一個普通神經元爲例。神經元接收一組輸入向量
經過某種運算後,輸出一個標量值:
因爲 ICS 問題的存在, 對於某一特定層,不一樣批次的輸入 的分佈可能相差很大。
要解決獨立同分布的問題,「理論正確」的方法就是對每一層的數據都進行白化操做。然而標準的白化操做代價高昂,特別是咱們還但願白化操做是可微的,保證白化操做能夠經過反向傳播來更新梯度。
在將 送給神經元以前,先對其作平移和伸縮變換, 將 的分佈規範化成在固定區間範圍的標準分佈。
通用變換框架就以下所示:
(1) 是平移參數(shift parameter), 是縮放參數(scale parameter)。經過這兩個參數進行 shift 和 scale 變換:
獲得的數據符合均值爲 0、方差爲 1 的標準分佈。
(2) 是再平移參數(re-shift parameter), 是再縮放參數(re-scale parameter)。將 上一步獲得的 進一步變換爲:
最終獲得的數據符合均值爲 、方差爲 的分佈。
第一次變換獲得均值爲 0、方差爲 1 的標準分佈,表達能力有限,下層神經元可能很努力地在學習,但不論其如何變化,其輸出的結果在交給上層神經元進行處理以前,將被粗暴地從新調整到這一固定範圍。爲了更好的應用底層神經網絡的學習結果,咱們將規範化後的數據進行再平移和再縮放,使得每一個神經元對應的輸入範圍是針對該神經元量身定製的一個肯定範圍(均值爲 、方差爲 )。rescale 和 reshift 的參數都是可學習的,這就使得 Normalization 層能夠學習如何去適應底層的學習結果。
除了充分利用底層學習的能力,另外一方面的重要意義在於保證得到非線性的表達能力。
Sigmoid 等激活函數在神經網絡中有着重要做用,經過區分飽和區和非飽和區,使得神經網絡的數據變換具備了非線性計算能力。而第一步的規範化會將幾乎全部數據映射到激活函數的非飽和區(線性區),僅利用到了線性變化能力,從而下降了神經網絡的表達能力。而進行再變換,則能夠將數據從線性區變換到非線性區,恢復模型的表達能力。
不添加正則化, 的均值取決於下層神經網絡的複雜關聯;添加本層後,取值 僅由 來肯定,去除了與下層計算的密切耦合。新參數很容易經過梯度降低來學習,簡化了神經網絡的訓練。
a)BN的實際做用
標準白化操做的目的是「獨立同分布」。獨立就不說了,暫不考慮。變換爲均值爲 、方差爲 的分佈,也並非嚴格的同分布,只是映射到了一個肯定的區間範圍而已(因此,這個問題仍然有研究空間)。
另外有人提出:BN其優點並不是解決了獨立同分布的問題(實際上它也沒解決),其最大意義在於解決了梯度彌散問題,見論文:How Does Batch Normalization Help Optimization?(知乎上的一篇閱讀筆記:爲何Batch Normalization那麼有用?)。文章結論以下:
其做用爲防止梯度爆炸或彌散、能夠提升訓練時模型對於不一樣超參(學習率、初始化)的魯棒性、可讓大部分的激活函數可以遠離其飽和區域。
b) BN對小批次訓練效果很差
當單個小批次(minibatch)的數據不能表明整個數據的分佈時,BN的表現就會不盡如人意,這意味着忘記將輸入隨機打亂順序的狀況下使用批歸一化是很危險的,實際上batch太小的時候就不太適合開放BN的可訓練性。具體討論見論文:Batch Normalization: Accelerating Deep Network Training by Reducing。
使用 BN 的目的就是爲了保證每批數據的分佈穩定,使用全局統計量反而違背了這個初衷;
BN 的做者認爲在訓練時採用移動平都可能會與梯度優化存在衝突
BatchNorm:batch方向作歸一化,算N*H*W的均值
LayerNorm:channel方向作歸一化,算C*H*W的均值
InstanceNorm:一個channel內作歸一化,算H*W的均值
GroupNorm:將channel方向分group,而後每一個group內作歸一化,算(C//G)*H*W的均值
https://zhuanlan.zhihu.com/p/69659844
於2015年由 Google 提出,BN 獨立地規範化每個層不一樣批次的 ,但規範化的參數是一個 mini-batch 的一階統計量和二階統計量。這就要求 每個 mini-batch 的統計量是總體統計量的近似估計,或者說每個 mini-batch 彼此之間,以及和總體數據,都應該是近似同分布的。分佈差距較小的 mini-batch 能夠看作是爲規範化操做和模型訓練引入了噪聲,能夠增長模型的魯棒性;但若是每一個 mini-batch的原始分佈差異很大,那麼不一樣 mini-batch 的數據將會進行不同的數據變換,這就增長了模型訓練的難度。訓練時,網絡會記錄每個batch滑動平均的均值和方差,訓練結束的時候這四個參數就固定了供測試時直接加載使用。
BN 比較適用的場景是:每一個 mini-batch 比較大,數據分佈比較接近。在進行訓練以前,要作好充分的 shuffle,不然效果會差不少。
另外,因爲 BN 須要在運行過程當中統計每一個 mini-batch 的一階統計量和二階統計量,所以不適用於 動態的網絡結構 和 RNN 網絡。不過,也有研究者專門提出了適用於 RNN 的 BN 使用方法,這裏先不展開了。
LN 針對單個訓練樣本進行,不依賴於其餘數據,所以能夠避免 BN 中受 mini-batch 數據分佈影響的問題,能夠用於 小 mini-batch 場景、動態網絡場景和 RNN,特別是天然語言處理領域。此外,LN 不須要保存 mini-batch 的均值和方差,節省了額外的存儲空間。
可是,BN 的轉換是針對單個神經元可訓練的——不一樣神經元的輸入通過再平移和再縮放後分布在不一樣的區間,而 LN 對於一整層的神經元訓練獲得同一個轉換——全部的輸入都在同一個區間範圍內。若是不一樣輸入特徵不屬於類似的類別(好比顏色和大小),那麼 LN 的處理可能會下降模型的表達能力。
在GAN和style transfer的任務中,目前的IN norm要好於BN,IN主要用於對單張圖像的數據作處理,而BN主要是對Bacth的數據作處理。因爲BN在訓練時每一個batch的均值和方差會因爲shuffle都會改變,因此能夠理解爲一種數據加強,而IN能夠理解爲對數據作一個歸一化的操做。
換句話說,BN的計算是要受其餘樣本影響的,因爲每一個batch的均值和標準差不穩定,對於單個數據而言,相對因而引入了噪聲,但在分類這種問題上,結果和數據的總體分佈有關係,所以須要經過BN得到數據的總體分佈。而instance norm的信息都是來自於自身的圖片,至關於對全局信息作了一次整合和調整,在圖像轉換這種問題上,BN得到的總體信息不會帶來任何收益,帶來的噪聲反而會弱化實例之間的獨立性:這類生成式方法,每張圖片本身的風格比較獨立不該該與batch中其餘的樣本產生太大聯繫。
group normalization是2018年3月份何愷明大神的又一力做,優化了BN在比較小的mini-batch狀況下表現不太好的劣勢。批量維度進行歸一化會帶來一些問題——批量統計估算不許確致使批量變小時,BN 的偏差會迅速增長。在訓練大型網絡和將特徵轉移到計算機視覺任務中(包括檢測、分割和視頻),內存消耗限制了只能使用小批量的BN。事實上,GN的極端狀況就是LN和IN,分別對應G等於C和G等於1。
tf實現並不複雜,以下
def GroupNorm(x,G=16,eps=1e-5): N,H,W,C=x.shape x=tf.reshape(x,[tf.cast(N,tf.int32), tf.cast(H,tf.int32), tf.cast(W,tf.int32), tf.cast(G,tf.int32), tf.cast(C//G,tf.int32)]) mean,var=tf.nn.moments(x,[1,2,4],keep_dims=True) x=(x-mean)/tf.sqrt(var+eps) x=tf.reshape(x,[tf.cast(N,tf.int32), tf.cast(H,tf.int32), tf.cast(W,tf.int32), tf.cast(C,tf.int32)]) gamma = tf.Variable(tf.ones(shape=[1,1,1,tf.cast(C,tf.int32)]), name="gamma") beta = tf.Variable(tf.zeros(shape=[1,1,1,tf.cast(C,tf.int32)]), name="beta") return x*gamma+beta
在深度學習沒有火起來以前,提取特徵一般是使用SIFT,HOG和GIST特徵,這些特徵有一個共性,都具備按group表示的特性,每個group由相同種類直方圖的構建而成,這些特徵一般是對在每一個直方圖(histogram)或每一個方向(orientation)上進行組歸一化(group-wise norm)而獲得。
從深度學習上來說,徹底能夠認爲卷積提取的特徵是一種非結構化的特徵或者向量,拿網絡的第一層卷積爲例,卷積層中的的卷積核filter1和此卷積核的其餘通過transform過的版本filter2(transform能夠是horizontal flipping等),在同一張圖像上學習到的特徵應該是具備相同的分佈,那麼,具備相同的特徵能夠被分到同一個group中,按照我的理解,每一層有不少的卷積核,這些核學習到的特徵並不徹底是獨立的,某些特徵具備相同的分佈,所以能夠被group。