【深度學習】深入理解Batch Normalization批歸一化

【深度學習】深入理解Batch Normalization批歸一化

轉自:https://www.cnblogs.com/guoyaohua/p/8724433.html

這幾天面試經常被問到BN層的原理,雖然回答上來了,但還是感覺答得不是很好,今天仔細研究了一下Batch Normalization的原理,以下為參考網上幾篇文章總結得出。

Batch Normalization作為最近一年來DL的重要成果,已經廣泛被證明其有效性和重要性。雖然有些細節處理還解釋不清其理論原因,但是實踐證明好用才是真的好,別忘了DL從Hinton對深層網絡做Pre-Train開始就是一個經驗領先于理論分析的偏經驗的一門學問。本文是對論文《Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift》的導讀。

機器學習領域有個很重要的假設:IID獨立同分布假設,就是假設訓練數據和測試數據是滿足相同分布的,這是通過訓練數據獲得的模型能夠在測試集獲得好的效果的一個基本保障。那BatchNorm的作用是什么呢?BatchNorm就是在深度神經網絡訓練過程中使得每一層神經網絡的輸入保持相同分布的。

接下來一步一步的理解什么是BN。

為什么深度神經網絡隨著網絡深度加深,訓練起來越困難,收斂越來越慢?這是個在DL領域很接近本質的好問題。很多論文都是解決這個問題的,比如ReLU激活函數,再比如Residual Network,BN本質上也是解釋并從某個不同的角度來解決這個問題的。

一、Internal Covariate Shift 問題

從論文名字可以看出,BN是用來解決“Internal Covariate Shift“問題的,那么首先得理解什么是“Internal Covariate Shift”?

論文首先說明Mini-Batch SGD相對于One Example SGD的兩個優勢:梯度更新方向更準確;并行計算速度快;(為什么要說這些?因為BatchNorm是基于Mini-Batch SGD的,所以先夸下Mini-Batch SGD,當然也是大實話);然后吐槽下SGD訓練的缺點:超參數調起來很麻煩。(作者隱含意思是用BN就能解決很多SGD的缺點)

接著引入covariate shift的概念:如果ML系統實例集合<X,Y>中的輸入值X的分布老是變,這不符合IID假設,網絡模型很難穩定的學規律,這不得引入遷移學習才能搞定嗎,我們的ML系統還得去學習怎么迎合這種分布變化啊。對于深度學習這種包含很多隱層的網絡結構,在訓練過程中,因為各層參數不停在變化,所以每個隱層都會面臨covariate shift的問題,也就是在訓練過程中,隱層的輸入分布老是變來變去,這就是所謂的“Internal Covariate Shift”,Internal指的是深層網絡的隱層,是發生在網絡內部的事情,而不是covariate shift問題只發生在輸入層。

然后提出了BatchNorm的基本思想:能不能讓每個隱層節點的激活輸入分布固定下來呢?這樣就避免了“Internal Covariate Shift”問題了。

BN不是憑空拍腦袋拍出來的好點子,它是有啟發來源的:之前的研究表明如果在圖像處理中對輸入圖像進行白化(Whiten)操作的話——所謂白化,就是對輸入數據分布變換到0均值,單位方差的正態分布——那么神經網絡會較快收斂,那么BN作者就開始推論了:圖像是深度神經網絡的輸入層,做白化能加快收斂,那么其實對于深度網絡來說,其中某個隱層的神經元是下一層的輸入,意思是其實深度神經網絡的每一個隱層都是輸入層,不過是相對下一層來說而已,那么能不能對每個隱層都做白化呢?這就是啟發BN產生的原初想法,而BN也確實就是這么做的,可以理解為對深層神經網絡每個隱層神經元的激活值做簡化版本的白化操作。

二、BatchNorm的本質思想

BN的基本思想其實相當直觀:因為深層神經網絡在做非線性變換前的激活輸入值(就是那個x=WU+B,U是輸入)隨著網絡深度加深或者在訓練過程中,其分布逐漸發生偏移或者變動,之所以訓練收斂慢,一般是整體分布逐漸往非線性函數的取值區間的上下限兩端靠近(對于Sigmoid函數來說,意味著激活輸入值WU+B是大的負值或正值),所以這導致反向傳播時低層神經網絡的梯度消失,這是訓練深層神經網絡收斂越來越慢的本質原因而BN就是通過一定的規范化手段,把每層神經網絡任意神經元這個輸入值的分布強行拉回到均值為0方差為1的標準正態分布,其實就是把越來越偏的分布強制拉回比較標準的分布,這樣使得激活輸入值落在非線性函數對輸入比較敏感的區域,這樣輸入的小變化就會導致損失函數較大的變化,意思是這樣讓梯度變大,避免梯度消失問題產生,而且梯度變大意味著學習收斂速度快,能大大加快訓練速度。

THAT’S IT。其實一句話就是: 對于每個隱層神經元,把逐漸向非線性函數映射后向取值區間極限飽和區靠攏的輸入分布強制拉回到均值為0方差為1的比較標準的正態分布,使得非線性變換函數的輸入值落入對輸入比較敏感的區域,以此避免梯度消失問題。因為梯度一直都能保持比較大的狀態,所以很明顯對神經網絡的參數調整效率比較高,就是變動大,就是說向損失函數最優值邁動的步子大,也就是說收斂地快。BN說到底就是這么個機制,方法很簡單,道理很深刻。

上面說得還是顯得抽象,下面更形象地表達下這種調整到底代表什么含義。

在這里插入圖片描述

圖1 幾個正態分布

? 假設某個隱層神經元原先的激活輸入x取值符合正態分布,正態分布均值是-2,方差是0.5,對應上圖中最左端的淺藍色曲線,通過BN后轉換為均值為0,方差是1的正態分布(對應上圖中的深藍色圖形),意味著什么,意味著輸入x的取值正態分布整體右移2(均值的變化),圖形曲線更平緩了(方差增大的變化)。這個圖的意思是,BN其實就是把每個隱層神經元的激活輸入分布從偏離均值為0方差為1的正態分布通過平移均值壓縮或者擴大曲線尖銳程度,調整為均值為0方差為1的正態分布。

那么把激活輸入x調整到這個正態分布有什么用?首先我們看下均值為0,方差為1的標準正態分布代表什么含義:

在這里插入圖片描述

圖2 均值為0方差為1的標準正態分布圖

這意味著在一個標準差范圍內,也就是說64%的概率x其值落在[-1,1]的范圍內,在兩個標準差范圍內,也就是說95%的概率x其值落在了[-2,2]的范圍內。那么這又意味著什么?我們知道,激活值x=WU+B,U是真正的輸入,x是某個神經元的激活值,假設非線性函數是sigmoid,那么看下sigmoid(x)其圖形:

在這里插入圖片描述

圖3 Sigmoid(x)

及sigmoid(x)的導數為:G’=f(x)*(1-f(x)),因為f(x)=sigmoid(x)在0到1之間,所以G’在0到0.25之間,其對應的圖如下:

在這里插入圖片描述

圖4 Sigmoid(x)導數圖

假設沒有經過BN調整前x的原先正態分布均值是-6,方差是1,那么意味著95%的值落在了[-8,-4]之間,那么對應的Sigmoid(x)函數的值明顯接近于0,這是典型的梯度飽和區,在這個區域里梯度變化很慢,為什么是梯度飽和區?請看下sigmoid(x)如果取值接近0或者接近于1的時候對應導數函數取值,接近于0,意味著梯度變化很小甚至消失。而假設經過BN后,均值是0,方差是1,那么意味著95%的x值落在了[-2,2]區間內,很明顯這一段是sigmoid(x)函數接近于線性變換的區域,意味著x的小變化會導致非線性函數值較大的變化,也即是梯度變化較大,對應導數函數圖中明顯大于0的區域,就是梯度非飽和區。

從上面幾個圖應該看出來BN在干什么了吧?其實就是把隱層神經元激活輸入x=WU+B從變化不拘一格的正態分布通過BN操作拉回到了均值為0,方差為1的正態分布,即原始正態分布中心左移或者右移到以0為均值,拉伸或者縮減形態形成以1為方差的圖形。什么意思?就是說經過BN后,目前大部分Activation的值落入非線性函數的線性區內,其對應的導數遠離導數飽和區,這樣來加速訓練收斂過程。

但是很明顯,看到這里,稍微了解神經網絡的讀者一般會提出一個疑問:如果都通過BN,那么不就跟把非線性函數替換成線性函數效果相同了?這意味著什么?我們知道,如果是多層的線性函數變換其實這個深層是沒有意義的,因為多層線性網絡跟一層線性網絡是等價的。這意味著網絡的表達能力下降了,這也意味著深度的意義就沒有了。所以BN為了保證非線性的獲得,對變換后的滿足均值為0方差為1的x又進行了scale加上shift操作(y=scale*x+shift),每個神經元增加了兩個參數scale和shift參數,這兩個參數是通過訓練學習到的,意思是通過scale和shift把這個值從標準正態分布左移或者右移一點并長胖一點或者變瘦一點,每個實例挪動的程度不一樣,這樣等價于非線性函數的值從正中心周圍的線性區往非線性區動了動。核心思想應該是想找到一個線性和非線性的較好平衡點,既能享受非線性的較強表達能力的好處,又避免太靠非線性區兩頭使得網絡收斂速度太慢。當然,這是我的理解,論文作者并未明確這樣說。但是很明顯這里的scale和shift操作是會有爭議的,因為按照論文作者論文里寫的理想狀態,就會又通過scale和shift操作把變換后的x調整回未變換的狀態,那不是饒了一圈又繞回去原始的“Internal Covariate Shift”問題里去了嗎,感覺論文作者并未能夠清楚地解釋scale和shift操作的理論原因。

三、訓練階段如何做BatchNorm

上面是對BN的抽象分析和解釋,具體在Mini-Batch SGD下做BN怎么做?其實論文里面這塊寫得很清楚也容易理解。為了保證這篇文章完整性,這里簡單說明下。

假設對于一個深層神經網絡來說,其中兩層結構如下:

在這里插入圖片描述

圖5 DNN其中兩層

要對每個隱層神經元的激活值做BN,可以想象成每個隱層又加上了一層BN操作層,它位于X=WU+B激活值獲得之后,非線性函數變換之前,其圖示如下:

在這里插入圖片描述

圖6 BN操作

對于Mini-Batch SGD來說,一次訓練過程里面包含m個訓練實例,其具體BN操作就是對于隱層內每個神經元的激活值來說,進行如下變換:

在這里插入圖片描述

要注意,==這里t層某個神經元的x(k)不是指原始輸入,就是說不是t-1層每個神經元的輸出,而是t層這個神經元的線性激活x=WU+B,這里的U才是t-1層神經元的輸出。==變換的意思是:某個神經元對應的原始的激活x通過減去mini-Batch內m個實例獲得的m個激活x求得的均值E(x)并除以求得的方差Var(x)來進行轉換。

上文說過經過這個變換后某個神經元的激活x形成了均值為0,方差為1的正態分布,目的是把值往后續要進行的非線性變換的線性區拉動,增大導數值,增強反向傳播信息流動性,加快訓練收斂速度。 但是這樣會導致網絡表達能力下降,為了防止這一點,每個神經元增加兩個調節參數(scale和shift),這兩個參數是通過訓練來學習到的,用來對變換后的激活反變換,使得網絡表達能力增強,即對變換后的激活進行如下的scale和shift操作,這其實是變換的反操作:

在這里插入圖片描述

BN其具體操作流程,如論文中描述的一樣:

在這里插入圖片描述

過程非常清楚,就是上述公式的流程化描述,這里不解釋了,直接應該能看懂。

四、BatchNorm的推理(Inference)過程

BN在訓練的時候可以根據Mini-Batch里的若干訓練實例進行激活數值調整,但是在推理(inference)的過程中,很明顯輸入就只有一個實例,看不到Mini-Batch其它實例,那么這時候怎么對輸入做BN呢?因為很明顯一個實例是沒法算實例集合求出的均值和方差的。這可如何是好?

既然沒有從Mini-Batch數據里可以得到的統計量,那就想其它辦法來獲得這個統計量,就是均值和方差。可以用從所有訓練實例中獲得的統計量來代替Mini-Batch里面m個訓練實例獲得的均值和方差統計量,因為本來就打算用全局的統計量,只是因為計算量等太大所以才會用Mini-Batch這種簡化方式的,那么在推理的時候直接用全局統計量即可。

決定了獲得統計量的數據范圍,那么接下來的問題是如何獲得均值和方差的問題。很簡單,因為每次做Mini-Batch訓練時,都會有那個Mini-Batch里m個訓練實例獲得的均值和方差,現在要全局統計量,只要把每個Mini-Batch的均值和方差統計量記住,然后對這些均值和方差求其對應的數學期望即可得出全局統計量,即:

在這里插入圖片描述

有了均值和方差,每個隱層神經元也已經有對應訓練好的Scaling參數和Shift參數,就可以在推導的時候對每個神經元的激活數據計算NB進行變換了,在推理過程中進行BN采取如下方式:

在這里插入圖片描述

這個公式其實和訓練時

在這里插入圖片描述

是等價的,通過簡單的合并計算推導就可以得出這個結論。那么為啥要寫成這個變換形式呢?我猜作者這么寫的意思是:在實際運行的時候,按照這種變體形式可以減少計算量,為啥呢?因為對于每個隱層節點來說:

在這里插入圖片描述

都是固定值,這樣這兩個值可以事先算好存起來,在推理的時候直接用就行了,這樣比原始的公式每一步驟都現算少了除法的運算過程,乍一看也沒少多少計算量,但是如果隱層節點個數多的話節省的計算量就比較多了。

五、BatchNorm的好處

BatchNorm為什么NB呢,關鍵還是效果好。 ①不僅僅極大提升了訓練速度,收斂過程大大加快;②還能增加分類效果,一種解釋是這是類似于Dropout的一種防止過擬合的正則化表達方式,所以不用Dropout也能達到相當的效果;③另外調參過程也簡單多了,對于初始化要求沒那么高,而且可以使用大的學習率等。 總而言之,經過這么簡單的變換,帶來的好處多得很,這也是為何現在BN這么快流行起來的原因。

作者:郭耀華
出處:http://www.guoyaohua.com
微信:guoyaohua167
郵箱:guo.yaohua@foxmail.com
本文版權歸作者和博客園所有,歡迎轉載,轉載請標明出處。
【如果你覺得本文還不錯,對你的學習帶來了些許幫助,請幫忙點擊右下角的推薦】

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/532626.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/532626.shtml
英文地址,請注明出處:http://en.pswp.cn/news/532626.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

ThinkPHP V5 漏洞利用

ThinkPHP 5漏洞簡介 ThinkPHP官方2018年12月9日發布重要的安全更新&#xff0c;修復了一個嚴重的遠程代碼執行漏洞。該更新主要涉及一個安全更新&#xff0c;由于框架對控制器名沒有進行足夠的檢測會導致在沒有開啟強制路由的情況下可能的getshell漏洞&#xff0c;受影響的版本…

Vim 重復操作的宏錄制

Vim 重復操作的宏錄制 轉自&#xff1a;https://www.cnblogs.com/ini_always/archive/2011/09/21/2184446.html 在編輯某個文件的時候&#xff0c;可能會出現需要對某種特定的操作進行許多次的情況&#xff0c;以編輯下面的文件為例&#xff1a; ; ;This is a sample config…

Vim 進階1

Vim 進階1 所有你覺得簡單重復&#xff0c;可以自動化實現的操作&#xff0c;都是可以自動化實現的。 Vim光標移動拾遺 w&#xff1a;下一個單詞的開頭&#xff0c;e&#xff1a;下一個單詞的結尾&#xff0c;b&#xff1a;上一個單詞的開頭&#xff0c; 0&#xff1a;行首…

攻防世界web題ics-06(爆破id值)

打開界面&#xff1a;嚯&#xff01;這花里胡哨 點來點去只有報表中心有回顯&#xff1a; 發現url中id等于1&#xff0c;sql注入嘗試無果&#xff0c; burp工具爆破id 對id的值進行爆破 burp報ERROR的話這是個bug&#xff0c;先點擊Hex后點decimal手動刷新就可以使用 強行總…

crontab用法與實例

crontab用法與實例 本文基于 ubuntu 18.04 在Linux系統的實際使用中&#xff0c;可能會經常碰到讓系統在某個特定時間執行某些任務的情況&#xff0c;比如定時采集服務器的狀態信息、負載狀況&#xff1b;定時執行某些任務/腳本來對遠端進行數據采集等。這里將介紹下crontab的配…

手工sql注入常規總結

1.發現注入點 2.報數據庫 先用單引號&#xff08;也嘗試雙引號&#xff09;閉合前面的語句&#xff0c;使注入的語句能夠執行&#xff0c; 數字 0 :匹配字段&#xff0c;還有 11 12 等等都可以使用&#xff0c;有些網站會有過濾處理&#xff0c;建議采用 1%2b12 1%2b1>1 繞…

Systemd入門教程:命令篇

Systemd入門教程&#xff1a;命令篇 轉自&#xff1a;http://www.ruanyifeng.com/blog/2016/03/systemd-tutorial-commands.html 作者&#xff1a; 阮一峰 日期&#xff1a; 2016年3月 7日 Systemd 是 Linux 系統工具&#xff0c;用來啟動守護進程&#xff0c;已成為大多數…

【CVE-2018-12613】phpmyadmin 4.8.1 遠程文件包含漏洞復現

**環境&#xff1a;**http://62.234.56.138:8080/server_databases.php 官網下載phpmyadmin 4.8.1 源碼&#xff1a;index.php文件中 函數含義&#xff1a; targer非空targer是否位字符串不能以index為開頭&#xff0c;即過濾了index值不能出現在blacklist內&#xff0c;即…

Systemd 入門教程:實戰篇

Systemd 入門教程&#xff1a;實戰篇 轉自&#xff1a;https://www.ruanyifeng.com/blog/2016/03/systemd-tutorial-part-two.html 作者&#xff1a; 阮一峰 日期&#xff1a; 2016年3月 8日 上一篇文章&#xff0c;我介紹了 Systemd 的主要命令&#xff0c;今天介紹如何使…

關于ubuntu自定義service服務時找不到/usr/lib/systemd/system目錄的問題

關于ubuntu自定義service服務時找不到/usr/lib/systemd/system目錄的問題 問題 我們知道在 systemd 取代了 init 而成為廣大 Linux 系統中 PID 為1的守護進程之后&#xff0c;Linux 中的服務&#xff08;service&#xff09;主要有 systemd 命令組來實現。在大多數發行版 Lin…

攻防世界web2(逆向加密算法)

打開網頁有如下代碼&#xff1a; <?php $miwen"a1zLbgQsCESEIqRLwuQAyMwLyq2L5VwBxqGA3RQAyumZ0tmMvSGM2ZwB4tws";function encode($str){$_ostrrev($str);// echo $_o;for($_00;$_0<strlen($_o);$_0){$_csubstr($_o,$_0,1);$__ord($_c)1;$_cchr($__);$_$_.$…

ctags 基本使用方法

ctags 基本使用方法 簡介 ctags&#xff08;Generate tag files for source code&#xff09;是vim下方便代碼閱讀的工具。盡管ctags也可以支持其它編輯器&#xff0c;但是它正式支持的只有 Vim。并且 Vim 中已經默認安裝了 ctags&#xff0c;它可以幫助程序員很容易地瀏覽源…

vimrc配置文件

vimrc配置文件 轉自&#xff1a;https://www.ruanyifeng.com/blog/2018/09/vimrc.html Vim 是最重要的編輯器之一&#xff0c;主要有下面幾個優點。 可以不使用鼠標&#xff0c;完全用鍵盤操作。系統資源占用小&#xff0c;打開大文件毫無壓力。鍵盤命令變成肌肉記憶以后&am…

CTFHUB 《請求方式》 http請求,curl命令總結

打開網頁&#xff1a; 思路一&#xff1a; 根據題目&#xff0c;應該是向網頁發送get方式請求&#xff0c;但并沒有具體規定要發送什么&#xff0c;嘗試get發送參數后&#xff0c;都沒有返回網頁&#xff0c;emmm’…好像不是我想的那種套路 思路二&#xff1a; 網上找到思路…

Vim進階2 map映射

Vim進階2 map映射 簡介 map是一個 vim 中的一些列映射命令&#xff0c;將常用的很長的命令映射到一個新的功能鍵上。map是Vim強大的一個重要原因&#xff0c;可以自定義各種快捷鍵&#xff0c;用起來自然得心應手。 map系列命令格式 格式 以 map 命令為例&#xff0c;它的…

CTFHUB 《基礎認證》:burp使用,basic請求了解

題目簡介&#xff1a;在HTTP中&#xff0c;基本認證&#xff08;英語&#xff1a;Basic access authentication&#xff09;是允許http用戶代理&#xff08;如&#xff1a;網頁瀏覽器&#xff09;在請求時&#xff0c;提供 用戶名 和 密碼 的一種方式。詳情請查看 https://zh.w…

信息量、熵、交叉熵、KL散度、JS散度雜談及代碼實現

信息量、熵、交叉熵、KL散度、JS散度雜談及代碼實現 信息量 任何事件都會承載著一定的信息量&#xff0c;包括已經發生的事件和未發生的事件&#xff0c;只是它們承載的信息量會有所不同。如昨天下雨這個已知事件&#xff0c;因為已經發生&#xff0c;既定事實&#xff0c;那…

CTFHUB《Web-信息泄露-備份文件下載》網站源碼,

1.網站源碼 三種方法&#xff1a; 方法一&#xff1a;dirsearch掃描git泄露 有文件下載 拿到flag 方法二&#xff1a;御劍&#xff08;超時10s&#xff09; 御劍其實也可以掃出來&#xff0c;但是一般我們掃域名超時時間都是三秒&#xff0c;本環境中需要超時10秒才能得到…

Linux下C/C++程序編譯鏈接加載過程中的常見問題及解決方法

Linux下C/C程序編譯鏈接加載過程中的常見問題及解決方法 1 頭文件包含的問題 報錯信息 該錯誤通常發生在編譯時&#xff0c;常見報錯信息如下&#xff1a; run.cpp:2:10: fatal error: dlpack/dlpack.h: No such file or directory#include <dlpack/dlpack.h>^~~~~~~…

DVWA Command Injection 練習總結

low: 首先查看源碼沒有對字符進行任何過濾 target參數為將要ping的ip地址&#xff0c;比如在輸入框輸入127.0.0.1后&#xff0c;對于windows系統&#xff0c;會發出ping 127.0.0.1操作。 這里可以引入命令行的幾種操作方式&#xff1a; A && B&#xff1a; 先執行A…