背景
BN依賴于Batch做歸一化,在小批量上會出現(xiàn)性能退化恢恼;GN雖然通過將特征在Channel上分組來擺脫Batch的 依賴,但是在大批量上性能不如BN。
BN 到GN
<span style='color: red'>機器學(xué)習(xí)最重要的任務(wù)</span>
根據(jù)一些以觀察到的證據(jù)來對感興趣的位置變量進行估計和推測蕉拢。
概率模型提高了一種描述框架,將學(xué)習(xí)任務(wù)歸結(jié)于計算變量。
歸一化處理有助于模型的優(yōu)化晕换。
BN
BN?通過計算batch中所有樣本的每個channel上的均值和方差來進行歸一化午乓。
計算方式偽代碼:
- 計算在(B, H, W)維度上的均值
和方差
![]()
- 在各個通道上進行標(biāo)準(zhǔn)歸一化
- 對歸一化的特征進行放縮
和平移
,其中兩個參數(shù)是可學(xué)習(xí)的
問題
-
訓(xùn)練時batch較大闸准,預(yù)測時batch通常為1益愈,造成訓(xùn)練和預(yù)測時均值
和方差
的計算分布不一致。
BN的解決方案是 在訓(xùn)練時估計一個均值和方差量來作為測試時的歸一化參數(shù)夷家,
一般對每次mini-batch的均值和方差進行指數(shù)加權(quán)平均來得到
蒸其。 BN對batch的大小敏感,如果batch太小库快,模型性能會明顯惡化摸袁,且受限于顯存大小,當(dāng)前很多模型的batch難以很大义屏。
解決BN問題
1. 避免在batch維度歸一化
由上述靠汁,我們知道如果避免在batch維度上進行歸一化可以避免batch帶來的問題。BN的兩個主要問題 <span style='color: blue'>訓(xùn)練和與測試均值和方差計算分布不一致
</span> 和 <span style='color: blue'>batch太小模型性能惡化
</span> 都是batch維度帶來的湿蛔,顯然不在batch上進行歸一化膀曾,上述問題就迎刃而解了。
基于這一觀點阳啥,衍生出一系列方法:
Layer Normalization
添谊,Instance Normalization
,Group Normalization
BN | LN | IN | GN | |
---|---|---|---|---|
處理維度 | (B, H, W) | (H, W, C) | (H, W) | (H, W, G) |
GN在歸一化時需要對C分組扎瓶,即特征從 [B, H, W, C] 轉(zhuǎn)換成 [B, H, W, G, C/G]
LN所踊,IN,GN都沒有在batch維度上進行歸一化概荷,所以不會有BN的問題秕岛。相比之下,GN更為常用误证。
2. 降低訓(xùn)練和測試之間的不一致性
Batch Renomalization
限制訓(xùn)練過程中batch統(tǒng)計量的值范圍
3. 多卡BN方法訓(xùn)練
相當(dāng)于增大batch size继薛。
FRN
FRN層包括 FRN歸一化層FRN (Filter Response Normalization)
和 激活層TLU (Threshold Linear Unit)
。
FRN不僅消除了訓(xùn)練時對batch的依賴愈捅,而且當(dāng)batch size較大時性能由于BN遏考。
原理? FRN的操作是在 (H, W) 維度上的,即對每個樣本的每個channel單獨進行歸一化蓝谨,這里就是一個N維度
的向量灌具,所以沒有對batch依賴的問題青团。FRN沒有采樣高斯分布進行歸一化,而是除以
的二次范數(shù)的平均值咖楣。這種歸一化方式類似BN可以消除中間操作(卷積和非線性激活)帶來的尺度問題督笆,有助于模型訓(xùn)練。
? 防止除0的小正常量截歉。FRN 是在 H胖腾,W 兩個維度歸一化,一般情況下網(wǎng)絡(luò)的特征圖大小
較大瘪松,但有時候會出現(xiàn)
的情況咸作。
對于特征圖為 的情況,
就比較關(guān)鍵宵睦,不同的
正則化效果區(qū)別很大记罚。當(dāng)
值較小時,歸一化相當(dāng)于符號函數(shù)壳嚎,這時候梯度幾乎為0桐智,嚴(yán)重影響模型訓(xùn)練;當(dāng)
值較大時烟馅,曲線變得更圓滑说庭,此時梯度有助于學(xué)習(xí)。對于這種情況郑趁,論文建議采用一個可學(xué)習(xí)的
刊驴。
IN 也是在 H, W維度上進行歸一化,但是會減去均值寡润,對于 的情況歸一化結(jié)果是 0捆憎,但FRN可以避免這個問題。
歸一化之后同樣需要進行縮放和平移變換梭纹,這里 和
也是可學(xué)習(xí)的參數(shù):
FRN缺少減均值的操作躲惰,可能使得歸一化的結(jié)果任意地偏移0,如果FRN之后是ReLU激活層变抽,可能產(chǎn)生很多0值础拨,這對于模型訓(xùn)練和性能是不利地。
為了解決這個問題绍载,F(xiàn)RN之后采用閾值化的ReLU太伊,即TLU:
其中 是可學(xué)習(xí)參數(shù)。
實驗結(jié)果
代碼實現(xiàn)
class FilterResponseNormNd(nn.Module):
def __init__(self, ndim, num_features, eps=1e-6, learnable_eps=False):
assert ndim in [3,4,5], \
'FilterResponseNorm only support 3d, 4d or 5d inputs'
super(FilterResponseNormNd, self).__init__()
shape = (1, num_features) + (1, ) * (ndim - 2)
self.eps = nn.Parameter(torch.ones(*shape) * eps)
if not learnable_eps:
self.eps.required_grad_(False)
self.gamma = nn.Parameter(torch.Tensor(*shape))
self.beta = nn.Parameter(torch.Tensor(*shape))
self.tau = nn.Parameter(torch.Tensor(*shape))
self.reset_parameters()
def forward(self, x):
avg_dims = tuple(range(2, x.dim()))
nu2 = torch.pow(x, 2).mean(dim=avg_dims, keepdim=True)
x = x * torch.rsqrt(nu2 + torch.abs(self.eps))
return torch.max(self.gamma * x + self.bata, self.tau)
def reset_parameters(self):
nn.init.ones_(self.gamma)
nn.init.zeros_(self.beta)
nn.init.zeros_(self.tau)