批量归一化 - BatchNorm

批量归一化(Batch Normalization),由Google于2015年提出,是近年来深度学习(DL)领域最重要的进步之一。该方法依靠两次连续的线性变换,希望转化后的数值满足一定的特性(分布),不仅可以加快了模型的收敛速度,也一定程度缓解了特征分布较散的问题,使深度神经网络(DNN)训练更快、更稳定。

  • 损失出现在最后,后面的层训练较快
  • 数据在最底部
    • 底部的层训练较慢
    • 底部层一变化,所有都得跟着变
    • 最后的那些层需要重新学习多次
    • 导致收敛变慢
  • 我们可以在学习底部层的时候避免变化顶部层吗?

固定小批量里面的均值和方差
μ B = 1 ∣ B ∣ ∑ i ∈ B x i   a n d   σ B 2 = 1 ∣ B ∣ ∑ i ∈ B ( x i − μ B ) 2 + ϵ \mu_B = \frac{1}{|B|}\sum\limits_{i\in B}x_i\ and\ \sigma_B^2=\frac{1}{|B|}\sum\limits_{i\in B}(x_i-\mu_B)^2+\epsilon μB=B1iBxi and σB2=B1iB(xiμB)2+ϵ
然后再做额外的调整(可学习的参数)
x i + 1 = γ x i − μ B σ B + β x_{i+1}=\gamma\frac{x_i-\mu_B}{\sigma_B}+\beta xi+1=γσBxiμB+β
其中, γ \gamma γ β \beta β可学习的参数。

批量归一化层

  • 可学习的参数为 γ \gamma γ β \beta β
  • 作用在
    • 全连接层和卷积层输出上,激活函数前(批量归一化是线性变换)
    • 全连接层和卷积层输入上
  • 对于全连接层,作用在特征维
  • 对于卷积层,作用在通道维

总结:

  • 批量归一化固定小批量中的均值和方差,然后学习出适合的偏移和缩放

  • 可以加速收敛速度(增大学习率),但一般不改变模型精度

当使用了批量归一化层之后,再使用丢弃法的话,效果就没有太大了。

应用BatchNorm于LeNet模型

class MyLeNet(nn.Module):
    def __init__(self, *args, **kwargs) -> None:
        super().__init__(*args, **kwargs)
        self.model = nn.Sequential(
            Reshape(),
            nn.Conv2d(1,6,kernel_size=5,padding=2),
            nn.BatchNorm2d(6),
            nn.Sigmoid(),
            nn.MaxPool2d(2,stride=2),
            nn.Conv2d(6,16,kernel_size=5),
            nn.BatchNorm2d(16),
            nn.Sigmoid(),
            nn.MaxPool2d(2,stride=2),
            nn.Flatten(),
            nn.Linear(16*5*5,120),
            nn.BatchNorm1d(120),
            nn.Sigmoid(),
            nn.Linear(120,84),
            nn.BatchNorm1d(84),
            nn.Sigmoid(),
            nn.Linear(84,10)
        )

    def forward(self,x):
        return self.model(x)
posted @ 2023-10-25 13:53  mango1698  阅读(43)  评论(0编辑  收藏  举报  来源