Batch Normalization閱讀筆記
這篇paper可以說是入門deep learning最基礎的一篇paper了,得好好吃透,下面就來寫寫自己在閱讀這篇paper時候的收穫和總結。
主要內容參考的是台大李宏毅的PPT和教程。
再講BN前,我們要先引入一個概念:feature scaling (可以翻譯成為,特徵縮放)
Feature Scaling:
- 什麼是特徵縮放? 答:特徵縮放其實就是標準化數據特徵的範圍。
- 為什麼要進行特徵縮放? 答:特徵縮放可以使得ML方法工作的更好,比如在k-nn的演算法中,分類器主要是計算兩點之間的歐幾里得距離,如果一個feature比其他另外一個feature大超過一個數量級的情況下,那麼兩者之間的距離就會更大的偏向於這個feature。因此,我們必須對每個feature都進行歸一化,將其規範到[0,1]的範圍內,這樣就可以加速model收斂的速度。
- 特徵縮放的一些方法。
- 調節比例( rescaling)
- 這種方法是將我們的數據都規範到[0,1]或者[-1,1]之間,至於縮放到什麼範圍,完全由數據的性質來決定。計算公式如下:
- ,其中 是最初的特徵值, 是縮放後的特徵值
- 標準化( normalization)
- 特徵標準化使每個特徵的值有零均值(zero-mean)和單位方差(unit-variance),計算公式如下:
接下來,通過圖來表達下上面的意思。
假如說我們現在有一個nn的網路結構,
- input的 是1,2,,,數量級的
- input的 是100,200,,,數量級的
- 那麼,此時為了讓output的a維持一定的標準態, 的取值就應該是一個很大的數, 的取值就應該是一個很小的數,這樣乘起來的結果再相加才能作為一個比較合理的數。不然,如果 還是一個很小的數,那麼乘出來的結果會慢慢吞噬 的作用。
那麼,如果我們不做feature scaling,會帶來什麼問題呢?
- 通過左邊的這個圖,我們發現,其是一個橢圓形的loss曲線。原因就是loss在 方向上的梯度變化緩慢,而在 方向上的梯度變化劇烈,使得整個曲線的形狀像一個橢圓形。
- 如果在訓練的過程中,我們為了避免這種情況發生,可以在 方向上使用較大learning_rate,而在 方向上使用較小的learning_rate。
做完feature scaling後,我們的loss曲線就是一個圓形的曲線了,這個時候,不管在哪個方向上的梯度都是一樣的,在train的過程中,model很快就能收斂了。
有關feature scaling的內容就講完了。
How about hidden layer?
那麼,接下來,我們就把問題轉到Deep Learning中來,在Deep Learning中,我們要train的往往都是一個deep的神經網路,網路中自然而然就會具有很多的hidden layer,層級結構如下所示:
那麼,當我們的input是x的時候,通過layer1後,得到 , 然後,再將這個 作為輸入送進layer2,得到 ,以此往下不斷的輸入,直到達到網路的output layer為止。
這裡,通過一個示例介紹一個新的概念:Internal Covariate Shift
這個圖表示的是,
- 有一群人想要互相之間傳遞消息,傳遞消息的方式是,必須一個人左右兩邊的話筒處於同一個位置。
- 拿上圖中從左往右數第二個人為例,要想讓message成功的從左邊傳遞到右邊,那麼就應該讓這個人左手邊的話筒向下降低,讓這個人右手邊的話筒向上提高。
- 仔細分析這個過程,是一個左右兩邊同時變化的過程。如果兩邊變化的幅度沒有控制好,那麼最終會導致下面這個圖的發生
- 左邊的話筒下的太過
- 右邊的話筒上的太高
- 此時,並沒有達成我們最終傳遞message的目的
其實,再回到我們問題的本身來看,deep neural network中,每一個hidden layer的input和output其實也是這種類似打電話的小人。
- 因為,我們train神經網路的過程,就是對於其中每一層layer中的weights的學習的過程,而通過正向傳播和反向傳播的相互作用,每一層的layer會不斷的變化,這也就導致了其input和output在不斷的變化。
- 但是,當我們固定下來一個方向的數值後,再去調整另外一個方向的數值,使得其與前面的方向匹配,那麼,我們就得到了最終想要的目的。
- 對於不加bn其實也可以解決我們的問題,就是通過非常小的learning_rate來彌補這種雙向變化的空缺,但是訓練的過程將會非常慢
在講解Batch Normalization之前,我們再來回顧下batch的原理,以及GPU是如何對batch進行加速計算的。
上面這張圖是說,一個batch裡面現在有 這三個數據,然後通過同一組parameters,我們得到了 ,然後在經過activation function,得到了 ,依次不斷input下去。
而當我們把 都同時放進一個matrix裡面的時候,將 放到這個matrix的前面,我們就能得到兩個matrix的乘法操作,最終得到 。
比起分別計算三次矩陣乘法得到 和放到一個矩陣中,平行化計算一次來說。
第二種方法明顯加快了運算的速度,這也就是GPU加速batch進行訓練的原理了。
Batch normalization是怎麼來操作的呢?
這張圖就說明了,BN的操作過程。
- 首先,我們將 放入一個batch裡面
- 然後經過一個layer的parameter,得到
- 通過 計算得到相應的
- 要記住: 的值是來自 的, 的值是來自 和 的
- 注意這裡的紅色標註:BN是不能夠應用到小數據batch上的,因為我們知道,在計算均值和方差的時候,非常小的batch是沒辦法來衡量整個training set的均值和方差的。而如果我們要去計算整個training set的均值和方差,就會太浪費時間。其實我們真正想要的 和 的值就是整個training set上得到的。
那麼,接下來,我們就通過對 減去均值除以標準差的方式得到了做完BN後的
問題來了,在training的過程中,我們該怎麼做bp呢?
這裡有兩種想法:
- 第一種:認為 和 是常量,所以說,前面的這些操作對於其bp的過程並不會有任何影響。
- 第二種:因為在每次做bp的過程中,由於會牽連到parameters的改變,那麼下一次輸出的 肯定會發生變化,那麼 和 的數值自然而然也會發生變化。所以bp的過程會和以前不同。
那麼,我們就需要多引入一組獨立的參數 ,這組parameter和輸入的batch數據無關。是神經網路能夠通過學習自己學到的。而 卻是和輸入的batch數據有關的。
現在來分析這兩組參數之間的關係:
- 當 與 對應相等的時候,那麼BN就相當於沒有做
- 當 與 不等的時候,就是BN起作用的時候了
在Training階段,BN是如何表現的?
前面都已經分析過了,這裡就不分析了。
在testing階段,BN是如何表現的?
這時候就會發現一個問題,就是說,我們test的時候輸入的是一個data,並不是像train那樣,輸入的是一個batch的data,那麼關於參數 的信息,我們沒辦法得到。
- 一個理想的解決方案:通過整個training set上的 來代表在test時候的信息,這個方法的不足很明顯。需要計算整個訓練集,太浪費時間。
- 另外一種比較實際的方法:就是在我們training的過程中,把每個batch所得到的 都保存下來,然後用平均的 來代替我們最終test時候的 。
上圖就展示了這個過程,當然,我們也可以不用均值,而是通過給準確度越高的 賦更大的權重,準確度越低的 賦更小的權重,最後得到一個加權的 當做最終test時候的parameter。同理對於 也這樣操作。
BN- Benefit:
- 能夠減少Interal Covariate Shift的問題,從而減少train的時間,使得對於deep網路的訓練更加可行。
- 消除梯度消失和梯度爆炸的問題,特別是對sigmoid和tanh函數
- 對於參數的初始化影響更小
即使對於某組parameter同時乘以k倍後,最終的結果還是會keep不變的
- 能夠減少overfitting問題的發生
推薦閱讀:
※譯文:如何使用TensorFlow實現神經網路(上)
※受限玻爾茲曼機(RBM)學習筆記
※先睹為快:神經網路頂會ICLR 2018論文接受結果速覽
※CS224N Lecture1 筆記
※ML領域的生物進化論,進化策略圖文詳解
TAG:深度學習DeepLearning | 神經網路 | 機器學習 |