本文轉載自:知乎專欄 -- 深度學習前言筆記 作者:張俊林
Batch Normalization(簡稱BN)自從提出之後,因爲效果特別好,很快被作爲深度學習的標準工具應用在了各種場合。BN大法雖然好,但是也存在一些侷限和問題,諸如當BatchSize太小時效果不佳、對RNN等動態網絡無法有效應用BN等。針對BN的問題,最近兩年又陸續有基於BN思想的很多改進Normalization模型被提出。BN是深度學習進展中里程碑式的工作之一,無論是希望深入瞭解深度學習,還是在實踐中解決實際問題,BN及一系列改進Normalization工作都是繞不開的重要環節。
一、從Mini-Batch SGD說起
我們先從Mini-Batch SGD的優化過程講起,因爲這是下一步理解Batch Normalization中Batch所代表具體含義的知識基礎。
我們知道,SGD是無論學術圈寫文章做實驗還是工業界調參跑模型最常用的模型優化算法,但是有時候容易被忽略的一點是:一般提到的SGD是指的Mini-batch SGD,而非原教旨意義下的單實例SGD。
圖1. Mini-Batch SGD 訓練過程(假設Batch Size=2)
所謂“Mini-Batch”,是指的從訓練數據全集T中隨機選擇的一個訓練數據子集合。假設訓練數據集合T包含N個樣本,而每個Mini-Batch的Batch Size爲b,於是整個訓練數據可被分成N/b個Mini-Batch。在模型通過SGD進行訓練時,一般跑完一個Mini-Batch的實例,叫做完成訓練的一步(step),跑完N/b步則整個訓練數據完成一輪訓練,則稱爲完成一個Epoch。完成一個Epoch訓練過程後,對訓練數據做隨機Shuffle打亂訓練數據順序,重複上述步驟,然後開始下一個Epoch的訓練,對模型完整充分的訓練由多輪Epoch構成(參考圖1)。
在拿到一個Mini-Batch進行參數更新時,首先根據當前Mini-Batch內的b個訓練實例以及參數對應的損失函數的偏導數來進行計算,以獲得參數更新的梯度方向,然後根據SGD算法進行參數更新,以此來達到本步(Step)更新模型參數並逐步尋優的過程。
圖2. Mini-Batch SGD優化過程
具體而言,如果我們假設機器學習任務的損失函數是平方損失函數:
那麼,由Mini-Batch內訓練實例可得出SGD優化所需的梯度方向爲:
根據梯度方向即可利用標準SGD來更新模型參數:
其中,
是學習率。
由上述過程(參考圖2)可以看出,對於Mini-Batch SGD訓練方法來說,爲了能夠參數更新必須得先求出梯度方向,而爲了能夠求出梯度方向,需要對每個實例得出當前參數下映射函數的預測值,這意味着如果是用神經網絡來學習映射h(x)的話,Mini-Batch內的每個實例需要走一遍當前的網絡,產生當前參數下神經網絡的預測值,這點請注意,這是理解後續Batch Normalization的基礎。
至於Batch Size的影響,目前可以實驗證實的是:batch size 設置得較小訓練出來的模型相對大batch size訓練出的模型泛化能力更強,在測試集上的表現更好,而太大的batch size往往不太Work,而且泛化能力較差。但是背後是什麼原因造成的,目前還未有定論,持不同看法者各持己見。因爲這不是文本的重點,所以先略過不表。
二、Normalization到底是在做什麼
Normalization的中文翻譯一般叫做“規範化”,是一種對數值的特殊函數變換方法,也就是說假設原始的某個數值是x,套上一個起到規範化作用的函數,對規範化之前的數值x進行轉換,形成一個規範化後的數值,即:
所謂規範化,是希望轉換後
足一定的特性,至於對數值具體如何變換,跟規範化目標有關,也就是說f()函數的具體形式,不同的規範化目標導致具體方法中函數所採用的形式不同。
其實我們生活中也有很多類似的規範化操作,知乎裏面有個熱帖,主題是:“爲什麼人大附中的學生那麼愛穿校服?”,裏面有人打趣地問:“請問人大附中的學生洗澡的時候脫不脫校服?”。這個問題我回答不了,要我猜大概率夏天洗澡的時候是會脫的,要不然洗澡的時候天太熱人受不了,冬天則未必,穿着洗可能更保暖。跑題了,其實我想說的是:學校要求學生穿校服就是一種典型的規範化操作,學校的規範化目標是要求學生着裝整齊劃一,顯得幹練有風貌,所以定義了一個規範化函數:
就是說不論哪個學生,不論你平常的着裝變量x=”香奈兒”還是x=“麻袋片”,經過這個規範化函數操作,統一都換成校服。這樣就達到了學校的規範化目的。
圖3. 神經元
在介紹深度學習Normalization前,我們先普及下神經元的活動過程。深度學習是由神經網絡來體現對輸入數據的函數變換的,而神經網絡的基礎單元就是網絡神經元,一個典型的神經元對數據進行處理時包含兩個步驟的操作(參考圖3):
步驟一:對輸入數據進行線性變換,產生淨激活值
其中,x是輸入,w是權重參數,b是偏置,w和b是需要進過訓練學習的網絡參數。
步驟二:套上非線性激活函數,神經網絡的非線性能力來自於此,目前深度學習最常用的激活函數是Relu函
如此一個神經元就完成了對輸入數據的非線性函數變換。這裏需要強調下,步驟一的輸出一般稱爲淨激活(Net Activation),第二步驟經過激活函數後得到的值爲激活值。爲了描述簡潔,本文後續文字中使用激活的地方,其實指的是未經激活函數的淨激活值,而非一般意義上的激活,這點還請注意。
至於深度學習中的Normalization,因爲神經網絡裏主要有兩類實體:神經元或者連接神經元的邊,所以按照規範化操作涉及對象的不同可以分爲兩大類,一類是對第L層每個神經元的激活值或者說對於第L+1層網絡神經元的輸入值進行Normalization操作,比如BatchNorm/LayerNorm/InstanceNorm/GroupNorm等方法都屬於這一類;另外一類是對神經網絡中連接相鄰隱層神經元之間的邊上的權重進行規範化操作,比如Weight Norm就屬於這一類。廣義上講,一般機器學習裏看到的損失函數裏面加入的對參數的的L1/L2等正則項,本質上也屬於這第二類規範化操作。L1正則的規範化目標是造成參數的稀疏化,就是爭取達到讓大量參數值取得0值的效果,而L2正則的規範化目標是有效減小原始參數值的大小。有了這些規範目標,通過具體的規範化手段來改變參數值,以達到避免模型過擬合的目的。
本文主要介紹第一類針對神經元的規範化操作方法,這是目前DNN做Normalization最主流的做法。
圖4. Normalization加入的位置
那麼對於第一類的Normalization操作,其在什麼位置發揮作用呢?目前有兩種在神經元中插入Normalization操作的地方(參考圖4),第一種是原始BN論文提出的,放在激活函數之前;另外一種是後續研究提出的,放在激活函數之後,不少研究表明將BN放在激活函數之後效果更好。本文在講解時仍然遵循BN原始論文,後續講解都可以看成是將Normalization操作放在激活函數之前進行。
對於神經元的激活值來說,不論哪種Normalization方法,其規範化目標都是一樣的,就是將其激活值規整爲均值爲0,方差爲1的正態分佈。即規範化函數統一都是如下形式:
寫成兩步的模式是爲了方便講解,如果寫成一體的形式,則是如下形式:
其中,
爲某個神經元原始激活值,
爲經過規範化操作後的規範後值。整個規範化過程可以分解爲兩步,第一步參考公式(1),是對激活值規整到均值爲0,方差爲1的正態分佈範圍內。其中,
是通過神經元集合S(至於S如何選取讀者可以先不用關注,後文有述)中包含的m個神經元各自的激活值求出的均值,即:
爲根據均值和集合S中神經元各自激活值求出的激活值標準差:
其中,
是爲了增加訓練穩定性而加入的小的常量數據。
第二步參考公式(2),主要目標是讓每個神經元在訓練過程中學習到對應的兩個調節因子,對規範到0均值,1方差的值進行微調。因爲經過第一步操作後,Normalization有可能降低神經網絡的非線性表達能力,所以會以此方式來補償Normalization操作後神經網絡的表達能力。
目前神經網絡中常見的第一類Normalization方法包括Batch Normalization/Layer Normalization/Instance Normalization和Group Normalization,BN最早由Google研究人員於2015年提出,後面幾個算法算是BN的改進版本。不論是哪個方法,其基本計算步驟都如上所述,大同小異,最主要的區別在於神經元集合S的範圍怎麼定,不同的方法採用了不同的神經元集合定義方法。
爲什麼這些Normalization需要確定一個神經元集合S呢?原因很簡單,前面講過,這類深度學習的規範化目標是將神經元的激活值
限定在均值爲0方差爲1的正態分佈中。而爲了能夠對網絡中某個神經元的激活值 規範到均值爲0方差爲1的範圍,必須有一定的手段求出均值和方差,而均值和方差是個統計指標,要計算這兩個指標一定是在一個集合範圍內纔可行,所以這就要求必須指定一個神經元組成的集合,利用這個集合裏每個神經元的激活來統計出所需的均值和方差,這樣才能達到預定的規範化目標。
圖5. Normalization具體例子
圖5給出了這類Normalization的一個計算過程的具體例子,例子中假設網絡結構是前向反饋網絡,對於隱層的三個節點來說,其原初的激活值爲[0.4,-0.6,0.7],爲了可以計算均值爲0方差爲1的正態分佈,劃定集合S中包含了這個網絡中的6個神經元,至於如何劃定集合S讀者可以先不用關心,此時其對應的激活值如圖中所示,根據這6個激活值,可以算出對應的均值和方差。有了均值和方差,可以利用公式3對原初激活值進行變換,如果r和b被設定爲1,那麼可以得到轉換後的激活值[0.21,-0.75,0.50],對於新的激活值經過非線性變換函數比如RELU,則形成這個隱層的輸出值[0.21,0,0.50]。這個例子中隱層的三個神經元在某刻進行Normalization計算的時候共用了同一個集合S,在實際的計算中,隱層中的神經元可能共用同一個集合,也可能每個神經元採用不同的神經元集合S,並非一成不變,這點還請留心與注意。
針對神經元的所有Normalization方法都遵循上述計算過程,唯一的不同在於如何劃定計算統計量所需的神經元集合S上。讀者可以自己思考下,如果你是BN或者其它改進模型的設計者,那麼你會如何選取集合S?
三、Batch Normalization 如何做
我們知道,目前最常用的深度學習基礎模型包括前向神經網絡(MLP),CNN和RNN。目前BN在這些基礎網絡結構都有嘗試,總體而言,BN在MLP和CNN是非常成功的,在RNN上效果不明顯。下面我們分述前向神經網絡以及CNN中如何應用BN,然後談談BN面臨的一些困境。正是這些困境引發了後續的一系列改進模型的提出。
3.1 前向神經網絡中的BN
圖6. 前向神經網絡中的BatchNorm
對於前向神經網絡來說,BatchNorm在計算隱層某個神經元k激活的規範值的時候,對應的神經元集合S範圍是如何劃定呢?圖6給出了示意。因爲對於Mini-Batch訓練方法來說,根據Loss更新梯度使用Batch中所有實例來做,所以對於神經元k來說,假設某個Batch包含n個訓練實例,那麼每個訓練實例在神經元k都會產生一個激活值,也就是說Batch中n個訓練實例分別通過同一個神經元k的時候產生了n個激活值,BatchNorm的集合S選擇入圍的神經元就是這n個同一個神經元被Batch不同訓練實例激發的激活值。劃定集合S的範圍後,Normalization的具體計算過程與前文所述計算過程一樣,採用公式3即可完成規範化操作。
3.2 CNN網絡中的BN
瞭解了前向神經網絡中的BatchNorm ,接下來介紹CNN中的BatchNorm,讀者可以先自行思考下如果由你來主導設計,在CNN中究竟應該如何確定神經元集合S的勢力範圍。
我們知道,常規的CNN一般由卷積層、下采樣層及全連接層構成。全連接層形式上與前向神經網絡是一樣的,所以可以採取前向神經網絡中的BatchNorm方式,而下采樣層本身不帶參數所以可以忽略,所以CNN中主要關注卷積層如何計算BatchNorm。
圖7. CNN中的卷積核
CNN中的某個卷積層由m個卷積核構成,每個卷積覈對三維的輸入(通道數*長*寬)進行計算,激活及輸出值是個二維平面(長*寬),對應一個輸出通道(參考圖7),由於存在m個卷積核,所以輸出仍然是三維的,由m個通道及每個通道的二維平面構成。
圖8. CNN中的BatchNorm過程
那麼在卷積層中,如果要對通道激活二維平面中某個激活值進行Normalization操作,怎麼確定集合S的範圍呢?圖8給出了示意圖。類似於前向神經網絡中的BatchNorm計算過程,對於Mini-Batch訓練方法來說,反向傳播更新梯度使用Batch中所有實例的梯度方向來進行,所以對於CNN某個卷積層對應的輸出通道k來說,假設某個Batch包含n個訓練實例,那麼每個訓練實例在這個通道k都會產生一個二維激活平面,也就是說Batch中n個訓練實例分別通過同一個卷積核的輸出通道k的時候產生了n個激活平面。假設激活平面長爲5,寬爲4,則激活平面包含20個激活值,n個不同實例的激活平面共包含20*n個激活值。那麼BatchNorm的集合S的範圍就是由這20*n個同一個通道被Batch不同訓練實例激發的激活平面中包含的所有激活值構成(對應圖8中所有標爲藍色的激活值)。劃定集合S的範圍後,激活平面中任意一個激活值都需進行Normalization操作,其Normalization的具體計算過程與前文所述計算過程一樣,採用公式3即可完成規範化操作。這樣即完成CNN卷積層的BatchNorm轉換過程。
圖9. CNN中Batch Norm的另外一種角度的理解
描述起來似乎有些複雜,但是從概念上,其實可以把CNN中的卷積層想象成前向神經網絡中的一個隱層,然後把對應的某個卷積核想象成MLP隱層中的一個神經元節點,無非其輸出是個二維激活平面而不像MLP的神經元輸出是一個激活值,另外一個不同是這個神經元覆蓋的輸入部分不同,CNN的卷積核是局部覆蓋輸入,通過滑動窗口來實現輸入的全覆蓋,而MLP的神經元則是一步到位全局覆蓋輸入而已(參考圖9示意)。如果從這個角度思考CNN和MLP中的BatchNorm的話,其實兩者的做法是一致的。
從理論上講,類似的BatchNorm操作也可以應用在RNN上,事實上也有不少研究做了嘗試,但是各種實驗證明其實這麼做沒什麼用,所以本文就不展開講RNN中的BN了。
BatchNorm目前基本已經成爲各種網絡(RNN除外)的標配,主要是因爲效果好,比如可以加快模型收斂速度,不再依賴精細的參數初始化過程,可以調大學習率等各種方便,同時引入的隨機噪聲能夠起到對模型參數進行正則化的作用,有利於增強模型泛化能力。
但是,BatchNorm這麼好用的大殺器,仍然存在很多問題。
3.3 Batch Norm的四大罪狀
侷限1:如果Batch Size太小,則BN效果明顯下降。
BN是嚴重依賴Mini-Batch中的訓練實例的,如果Batch Size比較小則任務效果有明顯的下降。那麼多小算是太小呢?圖10給出了在ImageNet數據集下做分類任務時,使用ResNet的時候模型性能隨着BatchSize變化時的性能變化情況,可以看出當BatchSize小於8的時候開始對分類效果有明顯負面影響。之所以會這樣,是因爲在小的BatchSize意味着數據樣本少,因而得不到有效統計量,也就是說噪音太大。這個很好理解,這就類似於我們國家統計局在做年均收入調查的時候,正好把你和馬雲放到一個Batch裏算平均收入,那麼當你爲下個月房租發愁之際,突然聽到你所在組平均年薪1億美金時,你是什麼心情,那小Mini-Batch裏其它訓練實例就是啥心情。
圖10. BN的Batch Size大小對ImageNet分類任務效果的影響(From GN論文)
BN的Batch Size大小設置是由調參師自己定的,調參師只要把Batch Size大小設置大些就可以避免上述問題。但是有些任務比較特殊,要求batch size必須不能太大,在這種情形下,普通的BN就無能爲力了。比如BN無法應用在Online Learning中,因爲在線模型是單實例更新模型參數的,難以組織起Mini-Batch結構。
侷限2:對於有些像素級圖片生成任務來說,BN效果不佳;
對於圖片分類等任務,只要能夠找出關鍵特徵,就能正確分類,這算是一種粗粒度的任務,在這種情形下通常BN是有積極效果的。但是對於有些輸入輸出都是圖片的像素級別圖片生成任務,比如圖片風格轉換等應用場景,使用BN會帶來負面效果,這很可能是因爲在Mini-Batch內多張無關的圖片之間計算統計量,弱化了單張圖片本身特有的一些細節信息。
侷限3:RNN等動態網絡使用BN效果不佳且使用起來不方便
對於RNN來說,儘管其結構看上去是個靜態網絡,但在實際運行展開時是個動態網絡結構,因爲輸入的Sequence序列是不定長的,這源自同一個Mini-Batch中的訓練實例有長有短。對於類似RNN這種動態網絡結構,BN使用起來不方便,因爲要應用BN,那麼RNN的每個時間步需要維護各自的統計量,而Mini-Batch中的訓練實例長短不一,這意味着RNN不同時間步的隱層會看到不同數量的輸入數據,而這會給BN的正確使用帶來問題。假設Mini-Batch中只有個別特別長的例子,那麼對較深時間步深度的RNN網絡隱層來說,其統計量不方便統計而且其統計有效性也非常值得懷疑。另外,如果在推理階段遇到長度特別長的例子,也許根本在訓練階段都無法獲得深層網絡的統計量。綜上,在RNN這種動態網絡中使用BN很不方便,而且很多改進版本的BN應用在RNN效果也一般。
侷限4:訓練時和推理時統計量不一致
對於BN來說,採用Mini-Batch內實例來計算統計量,這在訓練時沒有問題,但是在模型訓練好之後,在線推理的時候會有麻煩。因爲在線推理或預測的時候,是單實例的,不存在Mini-Batch,所以就無法獲得BN計算所需的均值和方差,一般解決方法是採用訓練時刻記錄的各個Mini-Batch的統計量的數學期望,以此來推算全局的均值和方差,在線推理時採用這樣推導出的統計量。雖說實際使用並沒大問題,但是確實存在訓練和推理時刻統計量計算方法不一致的問題。
上面所列BN的四大罪狀,表面看是四個問題,其實深入思考,都指向了幕後同一個黑手,這個隱藏在暗處的黑手是誰呢?就是BN要求計算統計量的時候必須在同一個Mini-Batch內的實例之間進行統計,因此形成了Batch內實例之間的相互依賴和影響的關係。如何從根本上解決這些問題?一個自然的想法是:把對Batch的依賴去掉,轉換統計集合範圍。在統計均值方差的時候,不依賴Batch內數據,只用當前處理的單個訓練數據來獲得均值方差的統計量,這樣因爲不再依賴Batch內其它訓練數據,那麼就不存在因爲Batch約束導致的問題。在BN後的幾乎所有改進模型都是在這個指導思想下進行的。
但是這個指導思路儘管會解決BN帶來的問題,又會引發新的問題,新的問題是:我們目前已經沒有Batch內實例能夠用來求統計量了,此時統計範圍必須侷限在一個訓練實例內,一個訓練實例看上去孤零零的無依無靠沒有組織,怎麼看也無法求統計量,所以核心問題是對於單個訓練實例,統計範圍怎麼算?
四、Layer Normalization、Instance Normalization 及 Group Normalization
4.1 Layer Normalization
爲了能夠在只有當前一個訓練實例的情形下,也能找到一個合理的統計範圍,一個最直接的想法是:MLP的同一隱層自己包含了若干神經元;同理,CNN中同一個卷積層包含k個輸出通道,每個通道包含m*n個神經元,整個通道包含了k*m*n個神經元;類似的,RNN的每個時間步的隱層也包含了若干神經元。那麼我們完全可以直接用同層隱層神經元的響應值作爲集合S的範圍來求均值和方差。這就是Layer Normalization的基本思想。圖11、圖12和圖13分示了MLP、CNN和RNN的Layer Normalization的集合S計算範圍,因爲很直觀,所以這裏不展開詳述。
圖11. MLP中的LayerNorm
圖12. CNN中的LayerNorm
圖13. RNN中的LayerNorm
前文有述,BN在RNN中用起來很不方便,而Layer Normalization這種在同隱層內計算統計量的模式就比較符合RNN這種動態網絡,目前在RNN中貌似也只有LayerNorm相對有效,但Layer Normalization目前看好像也只適合應用在RNN場景下,在CNN等環境下效果是不如BatchNorm或者GroupNorm等模型的。從目前現狀看,動態網絡中的Normalization機制是非常值得深入研究的一個領域。
4.2 Instance Normalization
從上述內容可以看出,Layer Normalization在拋開對Mini-Batch的依賴目標下,爲了能夠統計均值方差,很自然地把同層內所有神經元的響應值作爲統計範圍,那麼我們能否進一步將統計範圍縮小?對於CNN明顯是可以的,因爲同一個卷積層內每個卷積核會產生一個輸出通道,而每個輸出通道是一個二維平面,也包含多個激活神經元,自然可以進一步把統計範圍縮小到單個卷積覈對應的輸出通道內部。圖14展示了CNN中的Instance Normalization,對於圖中某個卷積層來說,每個輸出通道內的神經元會作爲集合S來統計均值方差。對於RNN或者MLP,如果在同一個隱層類似CNN這樣縮小範圍,那麼就只剩下單獨一個神經元,輸出也是單值而非CNN的二維平面,這意味着沒有形成集合S,所以RNN和MLP是無法進行Instance Normalization操作的,這個很好理解。
圖14 CNN中的Instance Normalization
我們回想下圖8代表的CNN中的Batch Normalization,可以設想一下:如果把BN中的Batch Size大小設定爲1,此時和Instance Norm的圖14比較一下,是否兩者是等價的?也就是說,看上去Instance Normalization像是Batch Normalization的一種Batch Size=1的特例情況。但是仔細思考,你會發現兩者還是有區別的,至於區別是什麼讀者可自行思考。
Instance Normalization對於一些圖片生成類的任務比如圖片風格轉換來說效果是明顯優於BN的,但在很多其它圖像類任務比如分類等場景效果不如BN。
4.3 Group Normalization
從上面的Layer Normalization和Instance Normalization可以看出,這是兩種極端情況,Layer Normalization是將同層所有神經元作爲統計範圍,而Instance Normalization則是CNN中將同一卷積層中每個卷積覈對應的輸出通道單獨作爲自己的統計範圍。那麼,有沒有介於兩者之間的統計範圍呢?通道分組是CNN常用的模型優化技巧,所以自然而然會想到對CNN中某一層卷積層的輸出或者輸入通道進行分組,在分組範圍內進行統計。這就是Group Normalization的核心思想,是Facebook何凱明研究組2017年提出的改進模型。
圖15展示了CNN中的Group Normalization。理論上MLP和RNN也可以引入這種模式,但是還沒有看到相關研究,不過從道理上考慮,MLP和RNN這麼做的話,分組內包含神經元太少,估計缺乏統計有效性,猜測效果不會太好。
圖15. CNN中的Group Normalization
Group Normalization在要求Batch Size比較小的場景下或者物體檢測/視頻分類等應用場景下效果是優於BN的。
4.4 用一個故事來總結
爲了能夠更直觀地理解四種Normalization的異同,大家可以體會下面的故事以做類比:
很久很久以前,在遙遠的L國內有一個神奇的理髮館,理髮館裏面有很多勤勞的理髮師,來這裏理髮的顧客也很奇特,他們所有人都會要求理髮師(神經元)理出和其他人差不多長的頭髮(求均值)。那麼和其他人差不多長究竟是多長呢?這可難不倒我們可愛又聰明的理髮師,於是理髮師把自己最近24個小時服務過的顧客(Mini-Batch)進入理髮店時的頭髮長度求個平均值,這個均值就是“和其他人差不多長”的長度。來這裏的每個顧客都很滿意,時間久了,人們尊稱這些理髮師爲:BatchNorm理髮師。
不幸總是突然的,有一天,理髮館裏發生了一件怪事,所有理髮師的記憶只能維持1分鐘,他們再也記不住過去24小時中發生的事情了,自然也記不住過去服務客人的頭髮長度。但是每個顧客仍然要求剪出和其他人差不多長的頭髮長度,這可怎麼辦?聰明的理髮師們又想出了一個辦法:他們相互大聲報出同一時刻在理髮館裏自己手上客人的頭髮長度,每個理髮師就可以用這些人的頭髮長度均值作爲滿足自己手上客人條件的長度。儘管這是一羣得了失憶綜合證的理髮師,但是顧客對他們的服務仍然非常滿意,於是人們改稱他們爲:LayerNorm理髮師。
不幸總是突然的,有一天,理髮館裏又發生了一件怪事,理髮師們不僅得了失憶症,這次都突然失聰,再也聽不到其它理髮師的口頭通知,而固執的客人仍然堅持要理出“和其他人差不多長”的頭髮。對了,忘了介紹了,理髮館是有隔間的,每個隔間有K個理髮師同時給顧客理髮,雖然我們可愛又聰明的理髮師現在失憶又失聰,但是再大的困難也難不倒也叫不醒這羣裝睡的人,他們醒來後羣策羣力又發明了一個新方法:同一個隔間的理髮師通過相互打手勢來通知其它理髮師自己手上顧客的頭髮長度。於是同一個隔間的理髮師又可以剪出顧客滿意的頭髮了。人們稱這些身殘志堅的理髮師爲:GroupNorm理髮師。
不幸總是突然的,有一天,理髮館裏又發生了一件怪事,不過這次不是天災是人禍,理髮館老闆出於好心,給每位理髮師單獨開個辦公室給顧客理髮,但是好心辦了壞事,這樣一來,失憶失聰又無法相互打手勢的理髮師們怎麼應對頑固的顧客呢?怎樣才能繼續理出“和其他人差不多長”的頭髮呢?想必一般人這個時候基本無路可走了,但是我們可愛又聰明,同時失聰又失憶的理髮師仍然想出瞭解決辦法:他們看了看客人頭上的頭髮,發現不同地方有長有短,於是就把同一個客人所有頭髮的平均長度作爲難題的答案(CNN的InstanceNorm)。聽起來這個解決方案匪夷所思,但是出人意料的是,有些客人居然仍然非常滿意。人們管這些傳說中的神奇理髮師爲:InstanceNorm理髮師。
五、Normalization 操作的 Re-Scaling 不變性
我們知道,當神經網絡深度加深時,訓練有較大困難,往往其原因在於隨着網絡加深,在反向傳播訓練模型時,存在梯度爆炸或者梯度消失問題,Loss信息不能有效傳導到低層神經網絡參數,所以導致參數無法更新,模型無法收斂或者收斂速度慢。而很多環節可能導致梯度爆炸或者梯度消失問題,比如非線性函數及其導數是什麼形式以及網絡參數是否過大過小等,以非線性函數來說,比如RELU是能極大緩解這個問題的(因爲它的導數是個常數),這也是爲何目前RELU大行其道的根本原因。從神經網絡參數角度看,如果神經網絡中的參數具備Re-Scaling 不變性,意味着參數值過大或者過小對神經元輸出沒什麼影響,無疑這對緩解梯度爆炸或者梯度消失也有極大幫助作用,而Normalization確實具備幾個不同角度的Re-Scaling不變性,這也許是Normalization爲何應用在深度學習有效的原因之一,雖然可能並非本質原因。本節即講述Normalization爲何具備Re-Scaling 不變性這種優良特性。
我們考慮神經網絡中的三種Re-Scaling情形:權重向量(Weight Vector)Re-Scaling,數據Re-Scaling和權重矩陣(Weight Matrix)Re-Scaling。
圖16. 權重向量Re-Scaling
對於網絡中某個神經元i來說,其對應的邊權重向量假設爲
,所謂權重向量(Weight Vector)Re-Scaling,就是將
乘上一個縮放因子
,如果神經元i在進行權重向量 Re-Scaling之前和之後兩種不同情況下做Normalization操作,若Normalization之後神經元i對應的激活值沒發生變化,我們就說這種Normalization具備權重向量Re-Scaling不變性(參考圖16)。
圖17. 數據Re-Scaling
所謂數據Re-Scaling,指的是把輸入X乘上一個縮放因子
,同樣的,如果對輸入做縮放前後兩種情況下進行Normalization操作,若Normalization之後所有隱層神經元對應的激活值沒發生變化,我們說這種Normalization具備數據Re-Scaling不變性(參考圖17)。
圖18. 權重矩陣 Re-Scaling
而權重矩陣 Re-Scaling指的是:對於某兩個隱層(L層vs L+1層)之間的所有邊的權重參數
同時乘上相同的縮放因子
,如果在權重矩陣 Re-Scaling之前和之後兩種情形下對(L+1)層隱層神經元做Normalization操作,若兩種情況下隱層所有神經元激活值沒有變化,我們說這種Normalization具備權重矩陣 Re-Scaling不變性(參考圖18)。
在瞭解了三種Re-Scaling的含義及Normalization對應的三種不變性特性後,我們先歸納各種Normalization操作所對應的三種Re-Scaling的不變性特性如下表所示(Layer Normalization原始論文分析了LayerNorm及BatchNorm的Re-Scaling不變性,本文作者補充了InstanceNorm及GroupNorm的情況以及細化了推導過程):
由表中可見,這四種不同的Normalization操作都同時具備權重矩陣Re-Scaling不變性和數據Re-Scaling不變性,但是不同的操作在權重向量Re-Scaling不變性這方面有差異,Batch Norm和Instance Norm具備權重向量Re-Scaling不變性,而另外兩種Normalization不具備這個特性。
我們以Batch Normalization爲例來說明爲何BN具備權重向量Re-Scaling不變性。
對於某個神經元i的激活a來說,其值爲:
(對於MLP和CNN來說,是一樣的,都是這個公式,區別在於CNN是局部連接,MLP是全局連接,也就是說只有
的數量規模不同而已。)
其中,
是與神經元i相連的邊權重向量(Weight Vector),X是輸入數據或是多層網絡中前一層的輸出向量,
是偏置。我們可以把偏置看作輸入數據值爲1的特殊邊的權重,所以可以併入前項,簡寫上述公式爲:
現在假設我們開始re-scale邊權重向量
,使得這些邊的權重縮放因子爲
,其對應的新的激活得到相同的縮放比例:
而邊的權重縮放後對應的均值變爲:
也就是說均值也被同比例縮放,這裏的關鍵是因爲BN的統計量取值範圍是來自於同一個Mini-Batch的實例,所以經過的是用一個神經元,於是對應了相同的邊權重向量,那麼縮放因子相同,就可以提到求和公式之外。
類似的,如果我們忽略噪音因子,邊權重縮放後對應的方差變爲:
可見方差也被同比例縮放,因爲
這是爲何說BN具備權重向量Re-Scaling不變性的原因。
類似的,BN也具備數據Re-Scaling不變性,其推導過程與上述推導過程基本一樣。因爲如果將原始輸入X乘以縮放因子,等價於某個神經元i的激活變爲
其餘推導類似上述的權重向量ReScaling的後續推導過程,其對應的均值和方差也會同比例縮放,於是得到了BN的數據Re-Scaling不變性。
同樣的,很容易推出BN也具備權重矩陣Re-Scaling不變性,因爲權重矩陣中所有邊權重會使用相同的縮放因子
,意味着某個隱層所有神經元對應的權重向量都使用相同的縮放因子,而在進行BN操作時,同隱層內的神經元相互獨立沒什麼關係,因爲上面推導了對於某個神經元i來說,其具備權重向量Re-Scaling不變性,所以對於所有隱層神經元來說,整個權重矩陣縮放後,任意神經元的激活與未縮放時相同,所以BN具備權重矩陣Re-Scaling不變性。
對於其它三類Normalization,也就是Layer Norm/Instance Norm/Group Norm來說,都同時具備權重矩陣 Re-Scaling不變性及數據Re-Scaling不變性,推導過程也與上述推導過程類似,此處不贅述。
那麼爲何Layer Norm不具備權重向量Re-Scaling不變性呢?因爲Layer Norm是在同隱層的神經元之間求統計量,我們考慮一種比較極端的情況,假設MLP的隱層只包含兩個神經元:神經元i和神經元j,而神經元i對應的邊權重向量
縮放因子是
,神經元j對應的邊權重向量
縮放因子是
。於是得出各自經過縮放後的激活值爲:
對應的縮放後的均值爲:
均值是無法提出公共縮放因子的,類似的方差也提不出公共縮放因子,所以不具備權重向量Re-Scaling不變性。那這又是爲什麼呢?根本原因是要進行求統計量計算的範圍不是同一個神經元,而是不同的神經元,而每個神經元對應權重向量縮放因子不同,所以難以抽出公共縮放因子並相互抵消。除非同一隱層所有隱層神經元共享相同的縮放因子,這個情形其實就是權重矩陣 Re-Scaling能夠滿足的條件,所以可以看出Layer Norm具備權重矩陣 Re-Scaling不變性而不具備權重向量Re-Scaling不變性。Group Norm也是類似情況。
六、Batch Normalization 爲何有效
正如上文所述,BN在提出後獲得了巨大的成功,目前在各種深度學習場景下廣泛應用,因爲它能加快神經網絡收斂速度,不再依賴精細的參數初始化過程,可以使用較大的學習率等很多好處,但是我們應該意識到,所講的這些好處僅僅是引用BN帶來的結果,那麼更深層次的問題是:爲什麼BN能夠給深度學習帶來如此多的優點呢?它背後起作用的深層原因是什麼呢?上文儘管從Normalization操作的Re-Scaling不變性角度有所說明,但其實還有更深層或更本質的原因。
原始的BN論文給出的解釋是BN可以解決神經網絡訓練過程中的ICS(Internal Covariate Shift)問題,所謂ICS問題,指的是由於深度網絡由很多隱層構成,在訓練過程中由於底層網絡參數不斷變化,導致上層隱層神經元激活值的分佈逐漸發生很大的變化和偏移,而這非常不利於有效穩定地訓練神經網絡。
圖19. BN和ICS問題的關係
但是能夠解決ICS問題其實並不是BN爲何有效背後真正的原因,最近有一些研究對此作了探討。那麼ICS問題真實存在嗎?ICS問題在較深的網絡中確實是普遍存在的,但是這並非導致深層網絡難以訓練的根本原因。另外,BN解決了ICS問題了嗎?其實也沒有。實驗一方面證明:即使是應用了BN,網絡隱層中的輸出仍然存在嚴重的ICS問題;另一方面也證明了:在BN層輸出後人工加入噪音模擬ICS現象,並不妨礙BN的優秀表現(參考圖19)。這兩方面的證據互相佐證來看的話,其實側面說明了BN和ICS問題並沒什麼關係。
圖20. 損失曲面
那麼BN有效的真正原因到底是什麼呢?這還要從深度網絡的損失曲面(Loss Surface)說起,在深度網絡疊加大量非線性函數方式來解決非凸複雜問題時,損失曲面形態異常複雜,大量空間坑坑窪窪相當不平整(參考圖20),也有很多空間是由平坦的大量充滿鞍點的曲面構成,訓練過程就是利用SGD在這個複雜平面上一步一步遊走,期望找到全局最小值,也就是曲面裏最深的那個坑。所以在SGD尋優時,在如此複雜曲面上尋找全局最小值而不是落入局部最小值或者被困在鞍點動彈不得,可想而知難度有多高。
有了損失曲面的基本概念,我們回頭來看爲何BN是有效的。研究表明,BN真正的用處在於:通過上文所述的Normalization操作,使得網絡參數重整(Reparametrize),它對於非線性非凸問題複雜的損失曲面有很好的平滑作用,參數重整後的損失曲面比未重整前的參數損失曲面平滑許多。我們可以用L-Lipschitz函數來評估損失曲面的平滑程度,L-Lipschitz函數定義如下:
含義也很直觀,對於定義區間內的任意取值
和
,用它們的距離去和經過函數映射後的值(就是深度網絡表達的損失函數)的距離進行比較,如果存在值L滿足上述公式條件,也就是說函數映射後的距離一定在任意兩個x差值的L倍以內,那麼這個函數稱爲L-Lipschitz函數。而L的大小代表了函數曲面的平滑程度,很明顯,L越小曲面越平滑,L越大,則曲面越凹凸不平,時而高峯時而波谷不斷顛倒跳躍。舉個例子,假設你一出門邁出一步才1米
,就突然掉到一個100米深的深溝
,那麼要滿足公式條件,L最小得是100;而假設你一出門邁出一步(
)踏上了一個0.3米的小臺階
,那麼L最小等於0.3即可。
圖21. 帶BN與不帶BN操作的L-Lipschitz情況
圖21展示了用L-Lipschitz函數來衡量採用和不採用BN進行神經網絡訓練時兩者的區別,可以看出未採用BN的訓練過程中,L值波動幅度很大,而採用了BN後的訓練過程L值相對比較穩定且值也比較小,尤其是在訓練的初期,這個差別更明顯。這證明了BN通過參數重整確實起到了平滑損失曲面及梯度的作用。
前文提到了Normalization對參數的Re-Scaling不變性,這也是參數重整達到的效果之一,所以也許其Re-Scaling特性和Loss曲面平滑作用是Normalization的一體兩面,共同發揮作用或者其實本身是一回事。事實的真相很可能是:Normalization通過對激活值進行正態分佈化的參數重整,產生參數Re-Scaling不變的效果,因此緩解梯度消失或梯度爆炸問題,與其對應的重整後的損失曲面及梯度也因此變得更平滑,更有利於SGD尋優找到問題好的解決方案。當然這只是本文作者根據幾方面研究現狀做出的推測,目前並沒有相關實證研究,還請讀者謹慎對待此觀點。
七、結束語
本文歸納了目前深度學習技術中針對神經元進行Normalization操作的若干種模型,可以看出,所有模型都採取了類似的步驟和過程,將神經元的激活值重整爲均值爲0方差爲1的新數值,最大的不同在於計算統計量的神經元集合S的劃分方法上。BN採用了同一個神經元,但是來自於Mini-Batch中不同訓練實例導致的不同激活作爲統計範圍。而爲了克服Mini-Batch帶來的弊端,後續改進方法拋棄了Mini-Batch的思路,只用當前訓練實例引發的激活來劃分集合S的統計範圍,概括而言,LayerNorm採用同隱層的所有神經元;InstanceNorm採用CNN中卷積層的單個通道作爲統計範圍,而GroupNorm則折衷兩者,採用卷積層的通道分組,在劃分爲同一個分組的通道內來作爲通道範圍。
至於各種Normalization的適用場景,可以簡潔歸納如下:對於RNN的神經網絡結構來說,目前只有LayerNorm是相對有效的;如果是GAN等圖片生成或圖片內容改寫類型的任務,可以優先嚐試InstanceNorm;如果使用場景約束BatchSize必須設置很小,無疑此時考慮使用GroupNorm;而其它任務情形應該優先考慮使用BatchNorm。
看上去其實Normalization的各種改進模型思路都很直觀,問題是:還有其它劃分集合S的方法嗎?很明顯還有很多種其它方法,建議讀者可以仔細思考下這個問題,如果你能找到一種新的集合劃分方法且證明其有效,那麼恭喜你,這意味着你找到了一種新的Normalization模型。還等什麼,趕緊去發現它們吧。
參考文獻:
- Sergey Ioffe etc. Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift. 2015.
- Jimmy Lei Ba etc. Layer Normalization. 2016.
- Dmitry Ulyanov etc. Instance Normalization: The Missing Ingredient for Fast Stylization. 2016.
- Yuxin Wu etc. Group Normalization.2018.
- Tim Salimans etc. Weight Normalization: A Simple Reparameterization to Accelerate Training of Deep Neural Networks.2016.
- Shibani Santurkar etc. How Does Batch Normalization Help Optimization? 2018.
- Johan Bjorck etc. Understanding Batch Normalization. 2018