點擊上方「小白學視覺」,選擇加"星標"或「置頂」
重磅乾貨,第一時間送達
編輯:CVDaily 轉載自:計算機視覺Daily
https://www.zhihu.com/question/283715823
本文僅作為學術分享,如果侵權,會刪文處理
BN 放在ReLU的前面還是後面?這個問題是AI面試的高頻題
Batch-normalized 應該放在非線性激活層的前面還是後面?我看網上的中文資料基本都是說,將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的黑體是我加的,為了突出重點)
但是,Franç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.「應該」放在前面還是後面?這個「應該」其實有兩種解釋:
放在前面還是後面比較好?
為什麼要放在前面還是後面?
對於第一問,目前在實踐上,傾向於把BN放在ReLU後面。也有評測表明BN放ReLU後面效果更好。
對於第二問,實際上,我們目前對BN的機制仍然不是特別清楚,這裡只能嘗試做些(玄學)解釋,不一定正確。
BN,也就是Batch-Normalization,這名字就能讓我們想到普通的normalization(歸一化),也就是將輸入傳給神經網絡之前對輸入做的normalization。這個normalization是對輸入操作的,是在輸入層之前進行的。那麼,從這個角度上來說,Batch-Normalization可以視作對傳給隱藏層的輸入的normalization。想像一下,如果我們把網絡中的某一個隱藏層前面的網絡層全部砍掉,那麼這個隱藏層就變成了輸入層,傳給它的輸入需要normalization,就在這一層之間,這個位置,就是原本的BN層的位置。從這方面來說,BN層放非線性激活之後,是很自然的。
然後,我們再來考慮一些具體的激活函數。我們看到,無論是tanh
還是sigmoid
函數圖像的兩端,相對於x的變化,y的變化都很小(這其實很正常,畢竟tanh就是拉伸過的sigmoid)。也就是說,容易出現梯度衰減的問題。那麼,如果在tanh或sigmoid之前,進行一些normalization處理,就可以緩解梯度衰減的問題。我想這可能也是最初的BN論文選擇把BN層放在非線性激活之前的原因。
但是ReLU的畫風和它們完全不一樣啊。
實際上,最初的BN論文雖然也在使用ReLU的Inception上進行了試驗,但首先研究的是sigmoid激活。因此,試驗ReLU的,我猜想作者可能就順便延續了之前把BN放前面的配置,而沒有單獨針對ReLU進行處理。
總結一下,BN層的作用機制也許是通過平滑隱藏層輸入的分布,幫助隨機梯度下降的進行,緩解隨機梯度下降權重更新對後續層的負面影響。因此,實際上,無論是放非線性激活之前,還是之後,也許都能發揮這個作用。只不過,取決於具體激活函數的不同,效果也許有一點差別(比如,對sigmoid和tanh而言,放非線性激活之前,也許順便還能緩解sigmoid/tanh的梯度衰減問題,而對ReLU而言,這個平滑作用經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與常用的數據歸一化最大的區別就是有α和β兩個參數,這兩個參數主要作用是在加速收斂和表徵破壞之間做的trade off。在初期數據歸一化比較明顯,所以網絡可以迅速收斂。至於為什麼數據歸一化可以加速收斂,這篇博客解釋的不錯,可以參考下,Batch Normalization詳解。隨著訓練來到中後期這兩個參數學習到差不多的時候,主要是用來恢復上一層輸入分布。
所以這麼去理解,上面的兩個結構的斜線加粗部分。1和2中都相當於作conv2的輸入做了歸一化,從conv2的看來,其輸入都是ReLU1之後的數據,但區別在於1中ReLU1截斷了部分bn1歸一化以後的數據,所以很有可能歸一化的數據已經不再完全滿足0均值和單位方差,而2中ReLU1之後的數據做了歸一化,歸一化後仍滿足0均值和單位方差。所以放後邊更有效也是可以理解的。
以上純屬個人理解,其實可以做這麼個實驗,在1結構的中在加一個BN,conv1-bn1-ReLU1-bn-conv2-bn2-ReLU2,把截斷後的數據在做個歸一化,這樣和原始的1比較下看看是否更有效。如果有的話,說明conv2更喜歡0均值和單位方差的分布~,不過我也沒試過。不知道會不會被打臉( ̄ε(# ̄)☆╰╮( ̄▽ ̄///)
作者:王藝程
https://www.zhihu.com/question/283715823/answer/443733242
在我所見過的所有包含BN的網絡結構中,BN都是在ReLU之前的。下面給出一種解釋
為了方便大家理解,先介紹一下我們在CVPR2018發表的論文《Person Re-identification with Cascaded Pairwise Convolutions》中提出的一種簡單的層:Channel Scaling (CS, 通道放縮層)。CS層將每一輸入通道乘以一恆正因子後作為輸出。在CS層存在於卷積層後,ReLU層前時,我們認為CS層可以在網絡訓練過程中引導卷積權值取正,進而緩解零梯度問題。具體的解釋除了看論文,還可以看下圖。
BN也可以解決零梯度問題,有兩條途徑,下面直觀地定性講講:
當對於絕大部分輸入特徵圖,filter絕大部分響應值為負時,會產生零梯度問題,在卷積層後加入BN層後,BN層中該filter對應通道的均值為負,BN中的減均值處理會使得相當一部分響應值變為正,進而解決了零梯度問題。(這段討論忽略了BN中的bias項和scaling項)
BN中的scaling項初始化為1,在訓練過程中一般取值為正,因此可通過類似CS的途徑來緩解零梯度問題;其實,如果scaling項一直取值為負,也可通過類似CS的途徑來緩解零梯度問題。(這段討論中忽略了BN中的normalization計算)
前述兩條途徑均存在缺陷,使得帶BN的網絡的訓練不穩定(至少在我們的實驗中是這樣):
BN中的均值和方差不是通過隨機梯度下降法訓練的,而是逐Batch統計並滑動平均,受不同Batch中樣本情況差異的影響大,在訓練過程中可能出現較大波動或改變,進而影響網絡功能。
訓練過程中,BN層中scaling項的取值有可能由正變負或者由負變正,這種情況翻轉了對應通道的含義,可能對網絡功能造成損害;此外,如果scaling項時而取正時而取負,無法實現類似CS的功能。
---
【補充】上面提到的我們的那篇論文存在靠不合理評測方式提升分數的問題,並且第三個貢獻——Sample Rate Leaning策略的優勢在調整網絡結構後難以體現。至少根據現有實驗,我覺得CS的效果比較明顯,並且有很合理的理論解釋。
作者:star all
https://www.zhihu.com/question/283715823/answer/700870267
和一位答友類似,我見過的很多網絡也是都把bn放到激活前面。我做一下解釋:
現在我們假設所有的激活都是relu,也就是使得負半區的卷積值被抑制,正半區的卷積值被保留。而bn的作用是使得輸入值的均值為0,方差為1,也就是說假如relu之前是bn的話,會有接近一半的輸入值被抑制,一半的輸入值被保留。
所以bn放到relu之前的好處可以這樣理解:bn可以防止某一層的激活值全部都被抑制,從而防止從這一層往前傳的梯度全都變成0,也就是防止梯度消失。(當然也可以防止梯度爆炸)
還有一個好處,把bn放到激活前面是有可以把卷積的weight和bn的參數進行合併的,所以它有利於網絡在做前向inference時候進行加速。
作者:郭嘉
https://www.zhihu.com/question/283715823/answer/553603362
前面答案說了一大堆bn放在relu後面的好處和理論依據。
而我用resnet18訓練手部檢測,只改變bn和relu的順序,和有些答主一樣,bn放在relu前面效果稍微好一點。
深度學習的理論真的有那麼肯定的話,就不需要做那麼多實驗來調整網絡了,根據自己的使用場景,自己實驗才是正確的答案。
下載1:OpenCV-Contrib擴展模塊中文版教程在「小白學視覺」公眾號後臺回覆:擴展模塊中文教程,即可下載全網第一份OpenCV擴展模塊教程中文版,涵蓋擴展模塊安裝、SFM算法、立體視覺、目標跟蹤、生物視覺、超解析度處理等二十多章內容。在「小白學視覺」公眾號後臺回覆:Python視覺實戰項目31講,即可下載包括圖像分割、口罩檢測、車道線檢測、車輛計數、添加眼線、車牌識別、字符識別、情緒檢測、文本內容提取、面部識別等31個視覺實戰項目,助力快速學校計算機視覺。在「小白學視覺」公眾號後臺回覆:OpenCV實戰項目20講,即可下載含有20個基於OpenCV實現20個實戰項目,實現OpenCV學習進階。在「小白學視覺」公眾號後臺回覆:leetcode,即可下載。每題都 runtime beats 100% 的開源好書,你值得擁有!交流群
歡迎加入公眾號讀者群一起和同行交流,目前有SLAM、三維視覺、傳感器、自動駕駛、計算攝影、檢測、分割、識別、醫學影像、GAN、算法競賽等微信群(以後會逐漸細分),請掃描下面微信號加群,備註:」暱稱+學校/公司+研究方向「,例如:」張三 + 上海交大 + 視覺SLAM「。請按照格式備註,否則不予通過。添加成功後會根據研究方向邀請進入相關微信群。請勿在群內發送廣告,否則會請出群,謝謝理解~