40_pytorch Batch Norm
1.37.Batch Normalization,批規范化
1.37.1.Batch Norm介紹
1.37.2.Intuitive explanation
1.37.3.Intuitive explanation
1.37.4.Feature scaling
1.37.5.BatchNorm1d、BatchNorm2d、BatchNorm3d
1.37.5.1.nn.BatchNorm1d(num_features)
1.37.5.2.nn.BatchNorm2d(num_features)
1.37.5.3.nn.BatchNorm3d(num_features)
1.37.6.Batch Norm
1.37.7.Pipeline
1.37.8.參考博文
1.37.Batch Normalization,批規范化
1.37.1.Batch Norm介紹
Batch Normalization(簡稱為BN)[2],中文翻譯成批規范化,是在深度學習中普遍使用的一種技術,通常用于解決多層神經網絡中間層的協方差偏移(Internal Covariate Shift)問題,類似于網絡輸入進行零均值化和方差歸一化的操作,不過是在中間層的輸入中操作而已。
1.37.2.Intuitive explanation
1.37.3.Intuitive explanation
使用sigmoid會出現梯度消失的情況,在實際訓練中,引入了BatchNorm操作,可以將輸入值限定在(γ = 1 , β)之間
如下圖,如果不進行Batch Norm,如果輸入weight差別過大,在兩個方向進行梯度下降,會出現梯度下降不平衡,在訓練過程中不能穩定的收斂,在實際應用過程中也不能穩定的輸出label結果,因此Normalization是很重要的
1.37.4.Feature scaling
Image Normalization
normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])Batch Normalization
1.37.5.BatchNorm1d、BatchNorm2d、BatchNorm3d
1.37.5.1.nn.BatchNorm1d(num_features)
1.對小批量(mini-batch)的2d或3d輸入進行批標準化(Batch Normalization)操作 2.num_features:來自期望輸入的特征數,該期望輸入的大小為'batch_size x num_features [x width]'意思即輸入大小的形狀可以是'batch_size x num_features' 和 'batch_size x num_features x width' 都可以。(輸入輸出相同)輸入Shape:(N, C)或者(N, C, L)輸出Shape:(N, C)或者(N,C,L)eps:為保證數值穩定性(分母不能趨近或取0),給分母加上的值。默認為1e-5。momentum:動態均值和動態方差所使用的動量。默認為0.1。affine:一個布爾值,當設為true,給該層添加可學習的仿射變換參數。 3.在每一個小批量(mini-batch)數據中,計算輸入各個維度的均值和標準差。gamma與beta是可學習的大小為C的參數向量(C為輸入大小)在訓練時,該層計算每次輸入的均值與方差,并進行移動平均。移動平均默認的動量值為0.1。在驗證時,訓練求得的均值/方差將用于標準化驗證數據。 4.例子 >>> # With Learnable Parameters >>> m = nn.BatchNorm1d(100) #num_features指的是randn(20, 100)中(N, C)的第二維C >>> # Without Learnable Parameters >>> m = nn.BatchNorm1d(100, affine=False) >>> input = autograd.Variable(torch.randn(20, 100)) #輸入Shape:(N, C) >>> output = m(input) #輸出Shape:(N, C)1.37.5.2.nn.BatchNorm2d(num_features)
1.對小批量(mini-batch)3d數據組成的4d輸入進行批標準化(Batch Normalization)操作 2.num_features: 來自期望輸入的特征數,該期望輸入的大小為'batch_size x num_features x height x width'(輸入輸出相同)輸入Shape:(N, C,H, W)輸出Shape:(N, C, H, W)eps: 為保證數值穩定性(分母不能趨近或取0),給分母加上的值。默認為1e-5。momentum: 動態均值和動態方差所使用的動量。默認為0.1。affine: 一個布爾值,當設為true,給該層添加可學習的仿射變換參數。 3.在每一個小批量(mini-batch)數據中,計算輸入各個維度的均值和標準差。gamma與beta是可學習的大小為C的參數向量(C為輸入大小)在訓練時,該層計算每次輸入的均值與方差,并進行移動平均。移動平均默認的動量值為0.1。在驗證時,訓練求得的均值/方差將用于標準化驗證數據。 4.例子 >>> # With Learnable Parameters >>> m = nn.BatchNorm2d(100) #num_features指的是randn(20, 100, 35, 45)中(N, C,H, W)的第二維C >>> # Without Learnable Parameters >>> m = nn.BatchNorm2d(100, affine=False) >>> input = autograd.Variable(torch.randn(20, 100, 35, 45)) #輸入Shape:(N, C,H, W) >>> output = m(input)1.37.5.3.nn.BatchNorm3d(num_features)
1.對小批量(mini-batch)4d數據組成的5d輸入進行批標準化(Batch Normalization)操作 2.num_features: 來自期望輸入的特征數,該期望輸入的大小為'batch_size x num_features depth x height x width' (輸入輸出相同)輸入Shape:(N, C,D, H, W)輸出Shape:(N, C, D, H, W)eps: 為保證數值穩定性(分母不能趨近或取0),給分母加上的值。默認為1e-5。momentum: 動態均值和動態方差所使用的動量。默認為0.1。affine: 一個布爾值,當設為true,給該層添加可學習的仿射變換參數。3.在每一個小批量(mini-batch)數據中,計算輸入各個維度的均值和標準差。gamma與beta是可學習的大小為C的參數向量(C為輸入大小)在訓練時,該層計算每次輸入的均值與方差,并進行移動平均。移動平均默認的動量值為0.1。在驗證時,訓練求得的均值/方差將用于標準化驗證數據。 4.例子>>> # With Learnable Parameters>>> m = nn.BatchNorm3d(100) #num_features指的是randn(20, 100, 35, 45, 10)中(N, C, D, H, W)的第二維C>>> # Without Learnable Parameters>>> m = nn.BatchNorm3d(100, affine=False) #num_features指的是randn(20, 100, 35, 45, 10)中(N, C, D, H, W)的第二維C>>> input = autograd.Variable(torch.randn(20, 100, 35, 45, 10)) #輸入Shape:(N, C, D, H, W) >>> output = m(input)1.37.6.Batch Norm
目前已知的Normalization的方法有4種,對于輸入數據為[N,C,(H * W)] (N代表tensor數據,C代表通道,H代表高,W代表寬)
下面圖形中表示的就是4種常見的BatchNorm,其中第一種比較常見。
?Batch Norm: Batch Norm:對每一個批次(N個tensor)的每個通道分別計算均值mean和方差var,如[10,4,9] 最終輸出是[0,1,2,3]這樣的1*4的tensor
?Layer Norm: 對于每一個tensor的所有channels進行均值和方差計算
?Instance Norm: 對于每個tensor的每個channels分別計算
?Group Norm: 引用了group的概念,比如BGR表示一個組----不常見
pytorch中的實現:
# -*- coding: UTF-8 -*-import torch import torch.nn as nnx = torch.rand(100, 16, 784) # 這里直接將28*28變為一維的784 layer = nn.BatchNorm1d(16) # 一維直接使用.BatchNorm1d即可 # 因為Batch Norm的參數直接是由channel數量得來的, # 因此這里直接給定了channel的數量為16,后續會輸出16個channel的統計信息 out = layer(x) # 進行前向計算 print(layer.running_mean)""" 輸出結果: tensor([0.0501, 0.0500, 0.0501, 0.0500, 0.0499, 0.0501, 0.0501, 0.0500, 0.0498,0.0498, 0.0500, 0.0501, 0.0501, 0.0500, 0.0501, 0.0500]) """可以自行對上述結果進行驗證,該結果的平均值恰好為0.5
1.37.7.Pipeline
Batch Normalization的規范化寫法為:
首先第一步先統計了當前規范化的均值和方差。接下來進行Normalize的操作,即將x值減去均值再除以根號下方差的平方與一個很小的誤差。最后再進行縮放,縮放成一個適宜的分布。
網友的解釋,如下:
注意到這里的最后一步也稱之為仿射(affine),引入這一步的目的主要是設計一個通道,使得輸出output至少能夠回到輸入input的狀態(當γ = 1 , β = 0時)使得BN的引入至少不至于降低模型的表現,這是深度網絡設計的一個套路。
整個過程見流程圖,BN在輸入后插入,BN的輸出作為規范后的結果輸入的后層網絡中。
代碼示例:
這里的weight即為σ值
這里還可以設置一些參數,如添加;training=True(表明當前的模式), affine=True(設置參數自動更新學習)。
Batch Norm同樣需要手動給予參數
Batch Norm具有相當優異的使用效果,如下圖所示:
使用了Batch Norm后,收斂速度加快、精度提高。上右圖可看出尖峰的偏差對比左側變小了很多。
再如案例:
# -*- coding: UTF-8 -*-import torch import torch.nn as nnm = nn.BatchNorm2d(2, affine=True) #權重w和偏重將被使用 input = torch.randn(1, 2, 3, 4) output = m(input)print("輸入圖片:") print(input) """ 輸出結果: tensor([[[[-1.7310, -1.5597, 0.8319, 0.9386],[ 0.8572, 1.6315, -0.2010, 0.1398],[-0.2074, 0.4479, -0.1920, -1.4322]],[[ 1.1964, -0.4497, -0.0277, -0.2446],[-1.0605, -1.1224, -1.1656, 0.2643],[ 0.1333, 2.2977, -1.0742, 1.3960]]]]) """print("歸一化權重:") print(m.weight) """ 輸出結果: tensor([1., 1.], requires_grad=True) """print("歸一化的偏重:") print(m.bias) """ 輸出結果: tensor([0., 0.], requires_grad=True) """print("歸一化的輸出:") print(output) """ 輸出結果: tensor([[[[-1.6394, -1.4734, 0.8449, 0.9483],[ 0.8694, 1.6199, -0.1564, 0.1740],[-0.1625, 0.4726, -0.1476, -1.3498]],[[ 1.1003, -0.4288, -0.0368, -0.2383],[-0.9962, -1.0537, -1.0939, 0.2345],[ 0.1128, 2.1234, -1.0090, 1.2858]]]],grad_fn=<NativeBatchNormBackward>) """print("輸出的尺度:") print(output.size()) """ 輸出結果: torch.Size([1, 2, 3, 4]) """# i = torch.randn(1,1,2) print("輸入的第一個維度:") print(input[0][0]) """ 輸出結果: tensor([[-1.7310, -1.5597, 0.8319, 0.9386],[ 0.8572, 1.6315, -0.2010, 0.1398],[-0.2074, 0.4479, -0.1920, -1.4322]]) """firstDimenMean = torch.Tensor.mean(input[0][0]) firstDimenVar = torch.Tensor.var(input[0][0],False) #Bessel's Correction貝塞爾校正不會被使用print(m.eps) """ 輸出結果: 1e-05 """print("輸入的第一個維度平均值:") print(firstDimenMean) """ 輸出結果: tensor(-0.0397) """print("輸入的第一個維度方差:") print(firstDimenVar) """ 輸出結果: tensor(1.0643) """bacthnormone = ((input[0][0][0][0] - firstDimenMean)/(torch.pow(firstDimenVar+m.eps,0.5))) * m.weight[0] + m.bias[0] print(bacthnormone) """ 輸出結果: tensor(-1.6394, grad_fn=<AddBackward0>) """1.37.8.參考博文
https://blog.csdn.net/loseinvain/article/details/86476010
https://cloud.tencent.com/developer/article/1549349
https://www.pianshen.com/article/4348414318/
https://www.jianshu.com/p/6358d261ade8
總結
以上是生活随笔為你收集整理的40_pytorch Batch Norm的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 39_上下采样、MaxPool2d、Av
- 下一篇: 炒股票当兼职靠谱吗 可以拿闲钱尝试一下