AI視覺網奇 2021-09-18 18:17:19 阅读数:553
torch 有兩個地方用Momentum動量,沖量,
一,優化器中的Momentum
主要是在訓練網絡時,最開始會對網絡進行權值初始化,但是這個初始化不可能是最合適的;因此可能就會出現損失函數在訓練的過程中出現局部最小值的情况,而沒有達到全局最優的狀態。
momentum的出現可以在一定程度上解决這個問題。動量來源於物理學,當momentum越大時,轉換為勢能的能量就越大,就越有可能擺脫局部凹區域,從而進入全局凹區域。momentum主要是用於權值優化。
2.bn層中的Momentum
Switchable Normalization 代碼地址:
https://github.com/switchablenorms/Switchable-Normalization
參考:https://blog.csdn.net/liuxiao214/article/details/81037416
歸一化層,目前主要有這幾個方法,Batch Normalization(2015年)、Layer Normalization(2016年)、Instance Normalization(2017年)、Group Normalization(2018年)、Switchable Normalization(2019年);
將輸入的圖像shape記為[N, C, H, W],這幾個方法主要的區別就是在,
1.BN
batchNorm是在batch上,對NHW做歸一化;即是將同一個batch中的所有樣本的同一層特征圖抽出來一起求mean和variance
加快收斂速度,允許網絡使用更高的學習率。可作為一個正則化器,减少對dropout的需求
但是當batch size較小時(小於16時),效果會變差,這時使用group norm可能得到的效果會更好
對小批量(mini-batch)3d數據組成的4d輸入進行批標准化(Batch Normalization)操作
進行了兩步操作:可見Batch Normalization的解釋
在每一個小批量(mini-batch)數據中,計算輸入各個維度的均值和標准差。γ與β是可學習的大小為C的參數向量(C為輸入大小)。默認γ取值為U(0,1),β設置為0
同樣,默認情况下,在訓練期間,該層將運行其計算的平均值和方差的估計值,然後在驗證期間使用這些估計值(即訓練求得的均值/方差)進行標准化。運行估計(running statistics)時保持默認momentum為0.1。
如果track_running_stats被設置為False,那麼這個層就不會繼續運行驗證,並且在驗證期間也會使用批處理統計信息。
️這個momentum參數不同於優化器optimizer類中使用的momentum參數和momentum的傳統概念。從數學上講,這裏運行統計數據的更新規則是 :
xnew = (1-momentum) * x + momentum * xt
因為批處理規範化是在C維(channel通道維度)上完成的,計算(N,H,W)片上的統計信息,所以通常將其稱為空間批處理規範化。
參數:
Shape:
輸入:(N, C,H, W)
輸出:(N, C, H, W)(輸入輸出相同)
舉例:
當affine=True時
import torch from torch import nn m = nn.BatchNorm2d(2,affine=True) print(m.weight) print(m.bias) input = torch.randn(1,2,3,4) print(input) output = m(input) print(output) print(output.size())
返回:
Parameter containing: tensor([0.5247, 0.4397], requires_grad=True) Parameter containing: tensor([0., 0.], requires_grad=True) tensor([[[[ 0.8316, -1.6250, 0.9072, 0.2746], [ 0.4579, -0.2228, 0.4685, 1.2020], [ 0.8648, -1.2116, 1.0224, 0.7295]], [[ 0.4387, -0.8889, -0.8999, -0.2775], [ 2.4837, -0.4111, -0.6032, -2.3912], [ 0.5622, -0.0770, -0.0107, -0.6245]]]]) tensor([[[[ 0.3205, -1.1840, 0.3668, -0.0206], [ 0.0916, -0.3252, 0.0982, 0.5474], [ 0.3409, -0.9308, 0.4373, 0.2580]], [[ 0.2664, -0.2666, -0.2710, -0.0211], [ 1.0874, -0.0747, -0.1518, -0.8697], [ 0.3160, 0.0594, 0.0860, -0.1604]]]], grad_fn=<NativeBatchNormBackward>) torch.Size([1, 2, 3, 4])
當affine=False時
import torch from torch import nn m = nn.BatchNorm2d(2,affine=False) print(m.weight) print(m.bias) input = torch.randn(1,2,3,4) print(input) output = m(input) print(output) print(output.size())
返回:
None None tensor([[[[-1.5365, 0.2642, 1.0482, 2.0938], [-0.0906, 1.8446, 0.7762, 1.2987], [-2.4138, -0.5368, -1.2173, 0.2574]], [[ 0.2518, -1.9633, -0.0487, -0.0317], [-0.9511, 0.2488, 0.3887, 1.4182], [-0.1422, 0.4096, 1.4740, 0.5241]]]]) tensor([[[[-1.2739, 0.0870, 0.6795, 1.4698], [-0.1811, 1.2814, 0.4740, 0.8689], [-1.9368, -0.5183, -1.0326, 0.0819]], [[ 0.1353, -2.3571, -0.2028, -0.1837], [-1.2182, 0.1320, 0.2894, 1.4478], [-0.3080, 0.3129, 1.5106, 0.4417]]]]) torch.Size([1, 2, 3, 4])
2.InstanceNorm2d(當mini-batch時使用)
instanceNorm在圖像像素上,對HW做歸一化;即是對batch中的單個樣本的每一層特征圖抽出來一層層求mean和variance,與batch size無關。若特征層為1,即C=1,准則instance norm的值為輸入本身
CLASS torch.nn.InstanceNorm2d(num_features, eps=1e-05, momentum=0.1, affine=False, track_running_stats=False)
在4D輸入上應用instance Normalization(帶有額外channel維度的mini-batch 2D輸入),即shape為[N,C,H,W]
在mini-batch中的對象的均值和標准差是每個維度分開計算的。如果affine=True,則γ和β這兩個可學習的參數向量,大小為C,C為輸入大小。
這一層使用從訓練和評估模式的輸入數據計算得到的instace數據。
如果track_running_stats被設置為True,那麼在訓練期間,該層將繼續運行計算均值和方差的估計,得到的均值和方差將使用到評估(eval)時的normalization中。運行估計時保持默認momentum為0.1。
️這個momentum參數不同於優化器optimizer類中使用的momentum參數和momentum的傳統概念。從數學上講,這裏運行統計數據的更新規則是 :
xnew = (1-momentum) * x + momentum * xt
️
InstanceNorm2d和LayerNorm非常相似,但是有一些細微的差別。InstanceNorm2d應用於RGB圖像等信道數據的每個信道,而LayerNorm通常應用於整個樣本,並且通常用於NLP任務。此外,LayerNorm應用元素仿射變換,而InstanceNorm2d通常不應用仿射變換。
參數:
Shape:
輸入:(N, C,H, W)
輸出:(N, C, H, W)(輸入輸出相同)
舉例:
import torch input = torch.randn(2,3,2,2) input
返回:
View Code
import torch.nn as nn #聲明仿射變換要寫成 #m = nn.InstanceNorm2d(3, affine=True) m = nn.InstanceNorm2d(3)#feature數量,即channel number = 3 output = m(input) output
返回:
View Code
layerNorm在通道方向上,對CHW歸一化;即是將batch中的單個樣本的每一層特征圖抽出來一起求一個mean和variance,與batch size無關,不同通道有著相同的均值和方差
CLASS torch.nn.LayerNorm(normalized_shape, eps=1e-05, elementwise_affine=True)
平均值和標准偏差分別計算在最後幾個維數上,這些維數必須是normalized_shape指定的形狀。如果elementwise_affine=True,則γ和β為兩個可學習的仿射變換參數向量,大小為normalized_shape
️與batch normalization和instance normalization不同,batch normalization使用affine選項為每個通道/平面應用標量尺度γ和偏差β,而layer normalization使用elementwise_affine參數為每個元素應用尺度和偏差。
這一層使用從訓練和評估模式的輸入數據計算得到的統計數據。
參數:
如果使用單個整數,則將其視為一個單例列錶,並且此模塊將在最後一個維度上進行規範化,而最後一個維度應該具有特定的大小。
Shape:
輸入:(N, *)
輸出:(N, *)(輸入輸出相同)
舉例:
import torch input = torch.randn(2,3,2,2) input
返回:
View Code
import torch.nn as nn #取消仿射變換要寫成 #m = nn.LayerNorm(input.size()[1:], elementwise_affine=False) m1 = nn.LayerNorm(input.size()[1:])#input.size()[1:]為torch.Size([3, 2, 2]) output1 = m1(input) output1
返回:
View Code
#只normalize後兩個維度 m2 = nn.LayerNorm([2,2]) output2 = m2(input) output2
返回:
View Code
#只normalize最後一個維度 m3 = nn.LayerNorm(2) output3 = m3(input) output3
返回:
View Code
GroupNorm將channel分組;即是將batch中的單個樣本的G層特征圖抽出來一起求mean和variance,與batch size無關
當batch size較小時(小於16時),使用該normalization方法效果更好
CLASS torch.nn.GroupNorm(num_groups, num_channels, eps=1e-05, affine=True)
輸入通道被分成num_groups組,每個組包含num_channels / num_groups個通道。每組的均值和標准差分開計算。如果affine=True,則γ和β這兩個可學習的通道仿射變換參數向量的大小為num_channels。
這一層使用從訓練和評估模式的輸入數據計算得到的統計數據。
參數:
Shape:
輸入:(N, C,*) ,C = num_channels
輸出:(N, C, *)(輸入輸出相同)
舉例:
import torch input = torch.randn(2,4,3,3) input
返回:
View Code
import torch.nn as nn #將4個通道分為2組 m1 = nn.GroupNorm(2,4) output1 = m1(input) output1
返回:
View Code
#將4個通道分為4組,等價於Instance Norm m2 = nn.GroupNorm(4,4) output2 = m2(input) output2
返回:
View Code
#將4個通道分為4組,等價於layer Norm m3 = nn.GroupNorm(4,4) output3 = m3(input) output3
返回:
View Code
pix2pix代碼中該部分的使用:
class Identity(nn.Module): def forward(self, x): return x def get_norm_layer(norm_type='instance'): """返回標准化層 Parameters: norm_type (str) -- 標准化層的名字,有: batch | instance | none 對於BatchNorm,我們使用可學習的仿射參數並追踪運行數據(mean/stddev) 對於InstanceNorm,我們不使用可學習的仿射參數也不追踪運行數據 """ if norm_type == 'batch': norm_layer = functools.partial(nn.BatchNorm2d, affine=True, track_running_stats=True) elif norm_type == 'instance': norm_layer = functools.partial(nn.InstanceNorm2d, affine=False, track_running_stats=False) elif norm_type == 'none': norm_layer = lambda x: Identity() else: raise NotImplementedError('normalization layer [%s] is not found' % norm_type) return norm_layer
版权声明:本文为[AI視覺網奇]所创,转载请带上原文链接,感谢。 https://gsmany.com/2021/09/20210918181718834i.html