Batch Normalization
Batch Normalization: 批标准化
- 批:一批数据,通常为mini-batch
- 标准化:0均值,1方差
优点:
1、可以用更大的学习率,加速模型的收敛
2、可以不用精心设计权值初始化
3、可以不用dropout或者较小的dropout
4、可以不用L2或者较小的weight decay
5、可以不用LRN(local response normalization)
计算方式

代码
import torch
import numpy as np
import torch.nn as nn
import sys, os
hello_pytorch_DIR = os.path.abspath(os.path.dirname(__file__)+os.path.sep+".."+os.path.sep+"..")
sys.path.append(hello_pytorch_DIR)
from tools.common_tools import set_seed
set_seed(1) # 设置随机种子
class MLP(nn.Module):
def __init__(self, neural_num, layers=100):
super(MLP, self).__init__()
self.linears = nn.ModuleList([nn.Linear(neural_num, neural_num, bias=False) for i in range(layers)])
self.bns = nn.ModuleList([nn.BatchNorm1d(neural_num) for i in range(layers)])
self.neural_num = neural_num
def forward(self, x):
for (i, linear), bn in zip(enumerate(self.linears), self.bns):
x = linear(x)
# x = bn(x)
x = torch.relu(x)
if torch.isnan(x.std()):
print("output is nan in {} layers".format(i))
break
print("layers:{}, std:{}".format(i, x.std().item()))
return x
def initialize(self):
for m in self.modules():
if isinstance(m, nn.Linear):
# method 1
nn.init.normal_(m.weight.data, std=1) # normal: mean=0, std=1
# method 2 kaiming
# nn.init.kaiming_normal_(m.weight.data)
neural_nums = 256
layer_nums = 100
batch_size = 16
net = MLP(neural_nums, layer_nums)
# net.initialize()
inputs = torch.randn((batch_size, neural_nums)) # normal: mean=0, std=1
output = net(inputs)
print(output)
不进行权值初始化的结果

我们可以看到在第99层得到的方差是非常小的,导致网络模型无法使用。梯度消失。
对权值进行初始化,采用均值为0,标准差为1的正态分布
取消net.initialize()的注释,我们可以从下图发现,标准差特别大,而且在第35层出现了nan。梯度爆炸。
采用kaiming方法进行权值初始化

此时我们的数据尺度有一个很好的分布,标准差前后相差不大。
加入BN层

效果更好。
使用BN层的同时不进行权值初始化

效果仍然很好,所以有了BN层我们可以不用精心设置权值初始化,甚至可以不进行权值初始化。
RMB二分类的BN层效果
1、原始LeNet,不进行权值初始化

2、原始LeNet,进行权值初始化

3、有BN层的LeNet,不进行权值初始化
在LeNet的每一个卷积后添加BN层。

_BatchNorm
__init__(self, num_features, eps=1e-5, momentum=0.1, affine=True, track_running_stats=True)
nn.BatchNorm1d
nn.BatchNorm2d
nn.BatchNorm3d
参数:
- num_features: 一个样本特征数量
- eps:分母修正项
- momentum: 指数加权平均估计当前mean/var
- affine: 是否需要affine transform
- track_running_stats: 是训练状态还是测试状态
主要属性:

- running_mean: 均值
- running_var: 方差
- weight: affine transform 中的gamma
- bias: affine transform 中的beta
训练:均值和方差采用指数加权平均计算
测试:当前统计值
running_mean = (1-momentum) * pre_running_mean + momentum * mean_t
running_var = (1-momentum) * pre_running_var + momentum * var_t
批标准化(BatchNormalization)详解
本文详细介绍了批标准化(BatchNormalization)的概念及其在深度学习中的应用。通过实验对比,展示了批标准化如何解决梯度消失和梯度爆炸问题,以及其在权重初始化、Dropout使用和LeNet模型上的效果提升。文章深入探讨了BatchNormalization的计算方式和参数设置,为读者提供了全面的理解。
1053

被折叠的 条评论
为什么被折叠?



