Batch Normalization應(yīng)該放在ReLU非線性激活層的前面還是后面?
點擊上方“小白學(xué)視覺”,選擇加"星標(biāo)"或“置頂”
重磅干貨,第一時間送達(dá)

編輯:CVDaily ?轉(zhuǎn)載自:計算機(jī)視覺Daily
https://www.zhihu.com/question/283715823
本文僅作為學(xué)術(shù)分享,如果侵權(quán),會刪文處理
BN 放在ReLU的前面還是后面?這個問題是AI面試的高頻題
Batch-normalized 應(yīng)該放在非線性激活層的前面還是后面?
我看網(wǎng)上的中文資料基本都是說,將BN 層放在非線性激活層的前面,但是
在 Deep Learning for Computer Vision with Python 中,有以下討論,

作者:論智
https://www.zhihu.com/question/283715823/answer/438882036
在BN的原始論文中,BN是放在非線性激活層前面的(arXiv:1502.03167v3,第5頁)
We add the BN transform immediately before the nonlinearity
(注意:before的黑體是我加的,為了突出重點)
但是,F(xiàn)ran?ois Chollet爆料說BN論文的作者之一Christian把BN放在ReLU后面(你的問題里引用的文字也提到了這一段)。
I can guarantee that recent code written by Christian applies relu before BN.
另外,Jeremy Howard直接主張把BN放在非線性激活后面
You want the batchnorm after the non-linearity, and before the dropout.
“應(yīng)該”放在前面還是后面?這個“應(yīng)該”其實有兩種解釋:
放在前面還是后面比較好?
為什么要放在前面還是后面?
對于第一問,目前在實踐上,傾向于把BN放在ReLU后面。也有評測表明BN放ReLU后面效果更好。
對于第二問,實際上,我們目前對BN的機(jī)制仍然不是特別清楚,這里只能嘗試做些(玄學(xué))解釋,不一定正確。
BN,也就是Batch-Normalization,這名字就能讓我們想到普通的normalization(歸一化),也就是將輸入傳給神經(jīng)網(wǎng)絡(luò)之前對輸入做的normalization。這個normalization是對輸入操作的,是在輸入層之前進(jìn)行的。那么,從這個角度上來說,Batch-Normalization可以視作對傳給隱藏層的輸入的normalization。想象一下,如果我們把網(wǎng)絡(luò)中的某一個隱藏層前面的網(wǎng)絡(luò)層全部砍掉,那么這個隱藏層就變成了輸入層,傳給它的輸入需要normalization,就在這一層之間,這個位置,就是原本的BN層的位置。從這方面來說,BN層放非線性激活之后,是很自然的。
然后,我們再來考慮一些具體的激活函數(shù)。我們看到,無論是tanh

還是sigmoid

函數(shù)圖像的兩端,相對于x的變化,y的變化都很?。ㄟ@其實很正常,畢竟tanh就是拉伸過的sigmoid)。也就是說,容易出現(xiàn)梯度衰減的問題。那么,如果在tanh或sigmoid之前,進(jìn)行一些normalization處理,就可以緩解梯度衰減的問題。我想這可能也是最初的BN論文選擇把BN層放在非線性激活之前的原因。
但是ReLU的畫風(fēng)和它們完全不一樣啊。

實際上,最初的BN論文雖然也在使用ReLU的Inception上進(jìn)行了試驗,但首先研究的是sigmoid激活。因此,試驗ReLU的,我猜想作者可能就順便延續(xù)了之前把BN放前面的配置,而沒有單獨(dú)針對ReLU進(jìn)行處理。
總結(jié)一下,BN層的作用機(jī)制也許是通過平滑隱藏層輸入的分布,幫助隨機(jī)梯度下降的進(jìn)行,緩解隨機(jī)梯度下降權(quán)重更新對后續(xù)層的負(fù)面影響。因此,實際上,無論是放非線性激活之前,還是之后,也許都能發(fā)揮這個作用。只不過,取決于具體激活函數(shù)的不同,效果也許有一點差別(比如,對sigmoid和tanh而言,放非線性激活之前,也許順便還能緩解sigmoid/tanh的梯度衰減問題,而對ReLU而言,這個平滑作用經(jīng)ReLU“扭曲”之后也許有所衰弱)。
作者:王超鋒
https://www.zhihu.com/question/283715823/answer/444230597
個人理解上和@論智差不多一致
實驗上,放后面更有效。為什么放后面有效,談一下我自己的理解。例如,這里兩層卷積:
1、before, conv1-bn1-ReLU1-conv2-bn2-ReLU2
2、after,conv1-ReLU1-bn1-conv2-ReLU2-bn2
BN與常用的數(shù)據(jù)歸一化最大的區(qū)別就是有α和β兩個參數(shù),這兩個參數(shù)主要作用是在加速收斂和表征破壞之間做的trade off。在初期數(shù)據(jù)歸一化比較明顯,所以網(wǎng)絡(luò)可以迅速收斂。至于為什么數(shù)據(jù)歸一化可以加速收斂,這篇博客解釋的不錯,可以參考下,Batch Normalization詳解。隨著訓(xùn)練來到中后期這兩個參數(shù)學(xué)習(xí)到差不多的時候,主要是用來恢復(fù)上一層輸入分布。
所以這么去理解,上面的兩個結(jié)構(gòu)的斜線加粗部分。1和2中都相當(dāng)于作conv2的輸入做了歸一化,從conv2的看來,其輸入都是ReLU1之后的數(shù)據(jù),但區(qū)別在于1中ReLU1截斷了部分bn1歸一化以后的數(shù)據(jù),所以很有可能歸一化的數(shù)據(jù)已經(jīng)不再完全滿足0均值和單位方差,而2中ReLU1之后的數(shù)據(jù)做了歸一化,歸一化后仍滿足0均值和單位方差。所以放后邊更有效也是可以理解的。
以上純屬個人理解,其實可以做這么個實驗,在1結(jié)構(gòu)的中在加一個BN,conv1-bn1-ReLU1-bn-conv2-bn2-ReLU2,把截斷后的數(shù)據(jù)在做個歸一化,這樣和原始的1比較下看看是否更有效。如果有的話,說明conv2更喜歡0均值和單位方差的分布~,不過我也沒試過。不知道會不會被打臉( ̄ε(# ̄)☆╰╮( ̄▽ ̄///)
作者:王藝程
https://www.zhihu.com/question/283715823/answer/443733242
在我所見過的所有包含BN的網(wǎng)絡(luò)結(jié)構(gòu)中,BN都是在ReLU之前的。下面給出一種解釋
為了方便大家理解,先介紹一下我們在CVPR2018發(fā)表的論文《Person Re-identification with Cascaded Pairwise Convolutions》中提出的一種簡單的層:Channel Scaling (CS, 通道放縮層)。CS層將每一輸入通道乘以一恒正因子后作為輸出。在CS層存在于卷積層后,ReLU層前時,我們認(rèn)為CS層可以在網(wǎng)絡(luò)訓(xùn)練過程中引導(dǎo)卷積權(quán)值取正,進(jìn)而緩解零梯度問題。具體的解釋除了看論文,還可以看下圖。

BN也可以解決零梯度問題,有兩條途徑,下面直觀地定性講講:
當(dāng)對于絕大部分輸入特征圖,filter絕大部分響應(yīng)值為負(fù)時,會產(chǎn)生零梯度問題,在卷積層后加入BN層后,BN層中該filter對應(yīng)通道的均值為負(fù),BN中的減均值處理會使得相當(dāng)一部分響應(yīng)值變?yōu)檎?,進(jìn)而解決了零梯度問題。(這段討論忽略了BN中的bias項和scaling項)
BN中的scaling項初始化為1,在訓(xùn)練過程中一般取值為正,因此可通過類似CS的途徑來緩解零梯度問題;其實,如果scaling項一直取值為負(fù),也可通過類似CS的途徑來緩解零梯度問題。(這段討論中忽略了BN中的normalization計算)
前述兩條途徑均存在缺陷,使得帶BN的網(wǎng)絡(luò)的訓(xùn)練不穩(wěn)定(至少在我們的實驗中是這樣):
BN中的均值和方差不是通過隨機(jī)梯度下降法訓(xùn)練的,而是逐B(yǎng)atch統(tǒng)計并滑動平均,受不同Batch中樣本情況差異的影響大,在訓(xùn)練過程中可能出現(xiàn)較大波動或改變,進(jìn)而影響網(wǎng)絡(luò)功能。
訓(xùn)練過程中,BN層中scaling項的取值有可能由正變負(fù)或者由負(fù)變正,這種情況翻轉(zhuǎn)了對應(yīng)通道的含義,可能對網(wǎng)絡(luò)功能造成損害;此外,如果scaling項時而取正時而取負(fù),無法實現(xiàn)類似CS的功能。
-------------
【補(bǔ)充】上面提到的我們的那篇論文存在靠不合理評測方式提升分?jǐn)?shù)的問題,并且第三個貢獻(xiàn)——Sample Rate Leaning策略的優(yōu)勢在調(diào)整網(wǎng)絡(luò)結(jié)構(gòu)后難以體現(xiàn)。至少根據(jù)現(xiàn)有實驗,我覺得CS的效果比較明顯,并且有很合理的理論解釋。
作者:star all
https://www.zhihu.com/question/283715823/answer/700870267
和一位答友類似,我見過的很多網(wǎng)絡(luò)也是都把bn放到激活前面。我做一下解釋:
現(xiàn)在我們假設(shè)所有的激活都是relu,也就是使得負(fù)半?yún)^(qū)的卷積值被抑制,正半?yún)^(qū)的卷積值被保留。而bn的作用是使得輸入值的均值為0,方差為1,也就是說假如relu之前是bn的話,會有接近一半的輸入值被抑制,一半的輸入值被保留。
所以bn放到relu之前的好處可以這樣理解:bn可以防止某一層的激活值全部都被抑制,從而防止從這一層往前傳的梯度全都變成0,也就是防止梯度消失。(當(dāng)然也可以防止梯度爆炸)
還有一個好處,把bn放到激活前面是有可以把卷積的weight和bn的參數(shù)進(jìn)行合并的,所以它有利于網(wǎng)絡(luò)在做前向inference時候進(jìn)行加速。
作者:郭嘉
https://www.zhihu.com/question/283715823/answer/553603362
前面答案說了一大堆bn放在relu后面的好處和理論依據(jù)。
而我用resnet18訓(xùn)練手部檢測,只改變bn和relu的順序,和有些答主一樣,bn放在relu前面效果稍微好一點。
深度學(xué)習(xí)的理論真的有那么肯定的話,就不需要做那么多實驗來調(diào)整網(wǎng)絡(luò)了,根據(jù)自己的使用場景,自己實驗才是正確的答案。
交流群
歡迎加入公眾號讀者群一起和同行交流,目前有SLAM、三維視覺、傳感器、自動駕駛、計算攝影、檢測、分割、識別、醫(yī)學(xué)影像、GAN、算法競賽等微信群(以后會逐漸細(xì)分),請掃描下面微信號加群,備注:”昵稱+學(xué)校/公司+研究方向“,例如:”張三?+?上海交大?+?視覺SLAM“。請按照格式備注,否則不予通過。添加成功后會根據(jù)研究方向邀請進(jìn)入相關(guān)微信群。請勿在群內(nèi)發(fā)送廣告,否則會請出群,謝謝理解~

