機器學習32:Batch Normalization 學習筆記(轉載)

機器學習32:Batch Normalization 學習筆記(轉載)

原文地址:http://blog.csdn.net/hjimce/article/details/50866313

作者:hjimce

1.背景意義:

            本篇博文主要講解2015年深度學習領域,非常值得學習的一篇文獻:《Batch Normalization: Accelerating Deep Network Training by  Reducing Internal Covariate Shift》,這個算法目前已經被大量的應用,最新的文獻算法很多都會引用這個算法進行網絡訓練,可見其強大之處非同一般。

            近年來隨機梯度下降成了深度學習領域訓練深度網絡的主流方法,儘管隨機梯度下降法對於訓練深度網絡簡單高效,但是它需要我們人爲選擇參數,如學習率、參數初始化、權重衰減係數、Dropout比例等。這些參數的選擇對訓練結果至關重要,以至於很多時間都浪費在調參上,那麼學習這篇文獻之後便可以不必刻意地慢慢調整參數。

            BN算法(Batch Normalization)的強大之處如下:

            (1) 可以選擇比較大的初始學習率,使訓練速度加快:

                  之前的算法需要緩慢地調整學習率,甚至在網絡訓練過半時還需要計算學習率進一步調小的合適比例,現在可以採用較大的初始學習率,並且學習率的衰減速度也很快,因爲算法收斂速度很快;

                  使用BN算法即使選擇了較小的學習率,依然收斂速度快於之前,因爲它具有快速訓練收斂的特性;

            (2)不需要人爲選擇擬閤中Dropout及L2正則項的參數:

                  採用BN算法後可以移除這兩項參數,或者可以選擇更小的L2正則約束參數了,因爲BN具有提高網絡泛化能力的特性;

            (3)不需要使用使用局部響應歸一化層:

                 局部響應歸一化是Alexnet網絡中使用的方法,因爲BN本身就是一個歸一化網絡層所以不需要繼續使用局部響應歸一化;

            (4)可以把訓練數據徹底打亂。

 

2,BN算法解決的問題:

            神經網絡學習過程本質就是爲了學習數據分佈,一旦訓練數據與測試數據的分佈不同,那麼網絡的泛化能力也大大降低;另外一方面,一旦每批訓練數據的分佈各不相同(batch 梯度下降),那麼網絡就要在每次迭代都去學習適應不同的分佈,這樣將會大大降低網絡的訓練速度,這也正是爲什麼我們需要對數據都要做一個歸一化預處理的原因。

            對於深度網絡的訓練是一個複雜的過程,只要網絡的前面幾層發生微小的改變,那麼後面幾層就會被累積放大下去。一旦網絡某一層的輸入數據的分佈發生改變,那麼這一層網絡就需要去適應學習這個新的數據分佈,所以如果訓練過程中,訓練數據的分佈一直在發生變化,那麼將會影響網絡的訓練速度。

            網絡訓練過程中更新參數,除了已執行人爲歸一化的輸入層數據外,後面網絡每一層的輸入數據分佈是一直在發生變化,因爲在訓練過程中,前面層訓練參數的更新將導致後面層輸入數據分佈的變化。以網絡第二層爲例:網絡的第二層輸入,是由輸入數據和第一層的參數共同計算得到的,而第一層的參數在整個訓練過程中一直在變化,因此必然會引起後面每一層輸入數據分佈的改變。

            網絡中間層在訓練過程中數據分佈的改變稱爲:“Internal  Covariate Shift”,論文中所提出的算法,就是要解決在訓練過程中中間層數據分佈發生改變的情況,於是就有了Batch  Normalization算法的誕生。

 

3.初識BN算法(Batch  Normalization):

            (1)BN算法概述:

                    與激活函數層、卷積層、全連接層、池化層相同,BN(Batch Normalization)也屬於網絡結構中的一層。

                    前面提到“Internal Covariate Shift”問題,即網絡除了輸出層外,其它層因爲低層網絡在訓練的時候更新參數而引起了後面層輸入數據分佈的變化。此時如果在每一層輸入時加入預處理操作,如網絡第三層輸入數據X3(X3表示網絡第三層的輸入數據)歸一化至:均值0、方差爲1,然後再輸入第三層計算,這樣就可以解決問題了。

                    而事實上,論文的算法本質原理就是這樣:在網絡的每一層輸入時插入一個歸一化層,也就是先做一個歸一化處理,然後再進入網絡的下一層。不過論文中的歸一化層更復雜,是一個可學習、有參數的網絡層。

            (2)預處理操作——白化:

                    神經網絡輸入數據預處理操作中最好的算法莫過於白化預處理,然而白化算法計算量很大,並且不是處處可微的,所以在深度學習中其實很少用到白化。經過白化預處理後,數據滿足條件:

                    a.特徵之間的相關性降低:相當於pca;

                    b.數據均值、標準差歸一化:使得每一維特徵均值爲0,標準差爲1。

                    當數據特徵維數比較大時需要進行PCA(實現白化的第一個要求),PCA操作需要計算特徵向量因此計算量非常大,於是爲了簡化計算作者忽略了第一個要求,僅僅使用了下面的公式進行預處理,也就是近似的白化預處理,後面也將用這個公式對某一個層網絡的輸入數據做歸一化處理:

                    需要注意的是,訓練過程中採用batch 隨機梯度下降,分子中的E(xk)指的是每一批訓練數據神經元xk的平均值,分母是每一批數據神經元xk激活得到的一個標準差。

3.BN算法實現:

            (1)BN算法概述:

                    經過前面介紹,BN算法好像只是對網絡中間層數據簡單做一個歸一化處理,然而其實實現起來並不是那麼簡單。

                    如果僅僅使用上面的歸一化公式對網絡某一層A的輸出數據做歸一化,然後送入網絡下一層,這樣會影響到本層網絡A所學習到的特徵。比如網絡中間某一層學習到特徵數據本身就分佈在S型激活函數的兩側,如果強制把它歸一化處理,標準差也限制在了1,把數據變換成分佈於s函數的中間部分,這樣就相當於這一層網絡所學習到的特徵分佈被破壞了。於是論文中提出變換重構的思路,引入了可學習參數γ、β,這就是算法關鍵之處:

                    每一個神經元xk都會有一對這樣的參數γ、β,這樣可以恢復出原始的某一層所學到的特徵:

                    因此引入了這個可學習重構參數γ、β使網絡可以學習恢復出原始網絡所要學習的特徵分佈,於是最終Batch Normalization網絡層的前向傳導過程公式就是(公式中m指的是mini-batch size):

                   

            (2)源碼實現:


            m = K.mean(X, axis=-1, keepdims=True)#計算均值
            std = K.std(X, axis=-1, keepdims=True)#計算標準差
            X_normed = (X - m) / (std + self.epsilon)#歸一化
            out = self.gamma * X_normed + self.beta#重構變換


            (3)實戰使用:

                    上面的算法解釋了網絡的訓練過程,網絡訓練結束min-batch概念就失去了意義。測試階段一般只輸入一個測試樣本獲取測試結果。因此測試樣本,前向傳導的時候均值u、標準差σ 從何而來?

                    其實網絡一旦訓練完畢參數都是固定的,此時每批訓練樣本進入網絡BN層計算的均值u、和標準差都是固定不變的,可以採用這些數值作爲測試樣本所需要的均值、標準差,於是測試階段的u和σ 計算公式如下:

                    上面公式的簡單理解就是:對於均值來說直接計算所有batch u值的平均值;然後對於標準偏差採用每個batch σB的無偏估計。測試階段BN的使用公式就是:

                    根據論文,BN算法可以應用於一個神經網絡的任何神經元上,文中主要將BN變換置於網絡激活函數層的前面。在沒有采用BN的時候,激活函數層是這樣的:

                                                                            z=g(Wu+b)

                    也就是我們需要一個激活函數使函數輸入的自變量x是經過BN處理後的結果。因此前向傳導的計算公式是:

                                                                            z=g(BN(Wu+b))

                    由於偏置參數b經過BN層後其實是沒有用的,因此也會被均值歸一化,當然BN層後面還有個β參數作爲偏置項,所以b這個參數就不需要了。最後BN層+激活函數層轉換爲:

                                                                            z=g(BN(Wu))

4.Batch Normalization在CNN中的使用:

            通過前面的學習瞭解到BN層是對單個神經元執行歸一化操作的運算,那麼在卷積神經網絡中假如某一層卷積層有6個特徵圖,每個特徵圖的大小是100*100,也就是這一層網絡有6*100*100個神經元,如果採用BN算法就會產生6*100*100個參數γ、β。

            因此卷積層上的BN算法的實際應用採取了類似權值共享的策略,將一整張特徵圖當做一個神經元進行處理。

            卷積神經網絡經過卷積後得到的是一系列的特徵圖,如果min-batch sizes爲m,那麼網絡某一層輸入數據可以表示爲四維矩陣(m,f,p,q),f爲特徵圖個數,p、q分別爲特徵圖的寬高。在卷積神經網絡中可以把每個特徵圖看成是一個特徵處理(一個神經元),因此在使用BN算法時mini-batch size 的大小就是:m*p*q,於是對於每個特徵圖都只有一對可學習參數:γ、β。

           這也就相當於求取所有樣本所對應的一個特徵圖的所有神經元的平均值、方差,然後對這個特徵圖神經元做歸一化。下面是來自於keras卷積層的BN實現一小段主要源碼:

           input_shape = self.input_shape
            reduction_axes = list(range(len(input_shape)))
            del reduction_axes[self.axis]
            broadcast_shape = [1] * len(input_shape)
            broadcast_shape[self.axis] = input_shape[self.axis]
            if train:
                m = K.mean(X, axis=reduction_axes)
                brodcast_m = K.reshape(m, broadcast_shape)
                std = K.mean(K.square(X - brodcast_m) + self.epsilon, axis=reduction_axes)
                std = K.sqrt(std)
                brodcast_std = K.reshape(std, broadcast_shape)
                mean_update = self.momentum * self.running_mean + (1-self.momentum) * m
                std_update = self.momentum * self.running_std + (1-self.momentum) * std
                self.updates = [(self.running_mean, mean_update),
                                (self.running_std, std_update)]
                X_normed = (X - brodcast_m) / (brodcast_std + self.epsilon)
            else:
                brodcast_m = K.reshape(self.running_mean, broadcast_shape)
                brodcast_std = K.reshape(self.running_std, broadcast_shape)
                X_normed = ((X - brodcast_m) /
                            (brodcast_std + self.epsilon))
            out = K.reshape(self.gamma, broadcast_shape) * X_normed + K.reshape(self.beta, broadcast_shape)


5.參考文獻:

            (1)《Batch Normalization: Accelerating Deep Network Training by  Reducing Internal Covariate Shift》

            (2)  Spatial Transformer Networks》

            (3)  https://github.com/fchollet/keras
————————————————
版權聲明:本文爲CSDN博主「hjimce」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/hjimce/article/details/50866313

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