[深度學習]BatchNormalization、LayerNormalization、InstanceNorm、GroupNorm、SwitchableNorm個人總結
個人總結
1. 概述
歸一化層,目前主要有這幾個方法,Batch Normalization(2015年)、Layer Normalization(2016年)、Instance Normalization(2017年)、Group Normalization(2018年)、Switchable Normalization(2018年);
將輸入的影像shape記為[N, C, H, W],這幾個方法主要的區別就是在,
- batchNorm是在batch上,對NHW做歸一化,對小batchsize效果不好;
- layerNorm在通道方向上,對CHW歸一化,主要對RNN作用明顯;
- instanceNorm在影像畫素上,對HW做歸一化,用在風格化遷移;
- GroupNorm將channel分組,然後再做歸一化;
- SwitchableNorm是將BN、LN、IN結合,賦予權重,讓網路自己去學習歸一化層應該使用什麼方法。
2. Batch Normalization
首先,在進行訓練之前,一般要對資料做歸一化,使其分佈一致,但是在深度神經網路訓練過程中,通常以送入網路的每一個batch訓練,這樣每個batch具有不同的分佈;此外,為了解決internal covarivate shift問題,這個問題定義是隨著batch normalizaiton這篇論文提出的,在訓練過程中,資料分佈會發生變化,對下一層網路的學習帶來困難。
所以batch normalization就是強行將資料拉回到均值為0,方差為1的正太分佈上,這樣不僅資料分佈一致,而且避免發生梯度消失。
此外,internal corvariate shift和covariate shift是兩回事,前者是網路內部,後者是針對輸入資料,比如我們在訓練資料前做歸一化等預處理操作。
演算法過程:
- 沿著通道計算每個batch的均值u
- 沿著通道計算每個batch的方差σ^2
- 對x做歸一化,x’=(x-u)/開根號(σ^2+ε)
- 加入縮放和平移變數γ和β ,歸一化後的值,y=γx’+β
加入縮放平移變數的原因是:保證每一次資料經過歸一化後還保留原有學習來的特徵,同時又能完成歸一化操作,加速訓練。 這兩個引數是用來學習的引數。
import numpy as np
def Batchnorm(x, gamma, beta, bn_param):
# x_shape:[B, C, H, W]
running_mean = bn_param['running_mean']
running_var = bn_param['running_var']
results = 0.
eps = 1e-5
x_mean = np.mean(x, axis=(0, 2, 3), keepdims=True)
x_var = np.var(x, axis=(0, 2, 3), keepdims=True0)
x_normalized = (x - x_mean) / np.sqrt(x_var + eps)
results = gamma * x_normalized + beta
# 因為在測試時是單個圖片測試,這裡保留訓練時的均值和方差,用在後面測試時用
running_mean = momentum * running_mean + (1 - momentum) * x_mean
running_var = momentum * running_var + (1 - momentum) * x_var
bn_param['running_mean'] = running_mean
bn_param['running_var'] = running_var
return results, bn_param
3.Layer Normalizaiton
batch normalization存在以下缺點:
- 對batchsize的大小比較敏感,由於每次計算均值和方差是在一個batch上,所以如果batchsize太小,則計算的均值、方差不足以代表整個資料分佈;
- BN實際使用時需要計算並且儲存某一層神經網路batch的均值和方差等統計資訊,對於對一個固定深度的前向神經網路(DNN,CNN)使用BN,很方便;但對於RNN來說,sequence的長度是不一致的,換句話說RNN的深度不是固定的,不同的time-step需要儲存不同的statics特徵,可能存在一個特殊sequence比其他sequence長很多,這樣training時,計算很麻煩。(參考於https://blog.csdn.net/lqfarmer/article/details/71439314)
與BN不同,LN是針對深度網路的某一層的所有神經元的輸入按以下公式進行normalize操作
BN與LN的區別在於:
- LN中同層神經元輸入擁有相同的均值和方差,不同的輸入樣本有不同的均值和方差;
BN中則針對不同神經元輸入計算均值和方差,同一個batch中的輸入擁有相同的均值和方差。 - 所以,LN不依賴於batch的大小和輸入sequence的深度,因此可以用於batchsize為1和RNN中對邊長的輸入sequence的normalize操作。
LN用於RNN效果比較明顯,但是在CNN上,不如BN。
def Layernorm(x, gamma, beta):
# x_shape:[B, C, H, W]
results = 0.
eps = 1e-5
x_mean = np.mean(x, axis=(1, 2, 3), keepdims=True)
x_var = np.var(x, axis=(1, 2, 3), keepdims=True0)
x_normalized = (x - x_mean) / np.sqrt(x_var + eps)
results = gamma * x_normalized + beta
return results
4. Instance Normalization
BN注重對每個batch進行歸一化,保證資料分佈一致,因為判別模型中結果取決於資料整體分佈。
但是影像風格化中,生成結果主要依賴於某個影像例項,所以對整個batch歸一化不適合影像風格化中,因而對HW做歸一化。可以加速模型收斂,並且保持每個影像例項之間的獨立。
公式:
def Instancenorm(x, gamma, beta):
# x_shape:[B, C, H, W]
results = 0.
eps = 1e-5
x_mean = np.mean(x, axis=(2, 3), keepdims=True)
x_var = np.var(x, axis=(2, 3), keepdims=True0)
x_normalized = (x - x_mean) / np.sqrt(x_var + eps)
results = gamma * x_normalized + beta
return results
5. Group Normalization
主要是針對Batch Normalization對小batchsize效果差,GN將channel方向分group,然後每個group內做歸一化,算(C//G)HW的均值,這樣與batchsize無關,不受其約束。
公式:
虛擬碼:
def GroupNorm(x, gamma, beta, G=16):
# x_shape:[B, C, H, W]
results = 0.
eps = 1e-5
x = np.reshape(x, (x.shape[0], G, x.shape[1]/16, x.shape[2], x.shape[3]))
x_mean = np.mean(x, axis=(2, 3, 4), keepdims=True)
x_var = np.var(x, axis=(2, 3, 4), keepdims=True0)
x_normalized = (x - x_mean) / np.sqrt(x_var + eps)
results = gamma * x_normalized + beta
return results
6. Switchable Normalization
本篇論文作者認為,
- 第一,歸一化雖然提高模型泛化能力,然而歸一化層的操作是人工設計的。在實際應用中,解決不同的問題原則上需要設計不同的歸一化操作,並沒有一個通用的歸一化方法能夠解決所有應用問題;
- 第二,一個深度神經網路往往包含幾十個歸一化層,通常這些歸一化層都使用同樣的歸一化操作,因為手工為每一個歸一化層設計操作需要進行大量的實驗。
因此作者提出自適配歸一化方法——Switchable Normalization(SN)來解決上述問題。與強化學習不同,SN使用可微分學習,為一個深度網路中的每一個歸一化層確定合適的歸一化操作
def SwitchableNorm(x, gamma, beta, w_mean, w_var):
# x_shape:[B, C, H, W]
results = 0.
eps = 1e-5
mean_in = np.mean(x, axis=(2, 3), keepdims=True)
var_in = np.var(x, axis=(2, 3), keepdims=True)
mean_ln = np.mean(x, axis=(1, 2, 3), keepdims=True)
var_ln = np.var(x, axis=(1, 2, 3), keepdims=True)
mean_bn = np.mean(x, axis=(0, 2, 3), keepdims=True)
var_bn = np.var(x, axis=(0, 2, 3), keepdims=True)
mean = w_mean[0] * mean_in + w_mean[1] * mean_ln + w_mean[2] * mean_bn
var = w_var[0] * var_in + w_var[1] * var_ln + w_var[2] * var_bn
x_normalized = (x - mean) / np.sqrt(var + eps)
results = gamma * x_normalized + beta
return results
結果比較:
7. 相關論文連線
1、Batch Normalization
https://arxiv.org/pdf/1502.03167.pdf
2、Layer Normalizaiton
https://arxiv.org/pdf/1607.06450v1.pdf
3、Instance Normalization
https://arxiv.org/pdf/1607.08022.pdf
https://github.com/DmitryUlyanov/texture_nets
4、Group Normalization
https://arxiv.org/pdf/1803.08494.pdf
5、Switchable Normalization
https://arxiv.org/pdf/1806.10779.pdf
https://github.com/switchablenorms/Switchable-Normalization
參考資料
[1] https://blog.csdn.net/liuxiao214/article/details/81037416
[2] https://mlexplained.com/2018/11/30/an-overview-of-normalization-methods-in-deep-learning/
相關文章
- 機器學習、深度學習資源總結機器學習深度學習
- 深度學習調參tricks總結!深度學習
- 深度學習調參tricks總結深度學習
- 深度學習模型調參總結深度學習模型
- 深度學習優化演算法總結深度學習優化演算法
- 【深度學習】深度學習md筆記總結第1篇:深度學習課程,要求【附程式碼文件】深度學習筆記
- UFLDL:史丹佛大學深度學習課程總結深度學習
- 個人總結
- 神經網路與深度學習 課程複習總結神經網路深度學習
- Python常見面試題總結——個人Python學習經驗Python面試題
- (資料結構程式碼,總結,自我思考)=> { return 個人學習筆記; } 【To be continued~】資料結構筆記
- gulp個人總結
- ES6個人初學總結-XY
- 小學期第一週個人總結
- 學習總結
- 演算法金 | 深度學習影像增強方法總結演算法深度學習
- 萬字總結Keras深度學習中文文字分類Keras深度學習文字分類
- 機器學習及深度學習的知識點及面試題總結機器學習深度學習面試題
- 2018年個人總結
- SpringBoot的個人總結Spring Boot
- activeMQ個人理解總結MQ
- 2023年個人總結
- 【個人總結】常用技巧
- 爬蟲個人總結爬蟲
- 一個IT人的自卷之路 —— GBase 8s培訓學習總結
- 個人學習
- ConstraintLayout 學習總結AI
- BOM學習總結
- tkinter學習總結
- vue學習總結Vue
- HSF學習總結
- ElasticSearch 學習總結Elasticsearch
- Storm學習總結ORM
- vue 學習總結Vue
- lua 學習總結
- Angularjs 學習總結AngularJS
- WebRTC學習總結Web
- GCD 學習總結GC