卷积神经网络基础---批量归一化(BN层、 Batch Normalization)

原文链接:https://blog.csdn.net/weixin_43972154/article/details/120199833

1. BN层的作用
BN层使得神经网络能够设定较高的初始学习率,加速模型收敛过程;
将数据进行归一化处理,即在网络的每一层输入的时候,插入了一个归一化层,然后再进入网络的下一层。这样能提高网络的泛化能力,使得网络能够使用误差更小的L2损失函数。
为什么要将数据进行归一化处理?
因为一旦训练数据与测试数据的分布不同,网络的泛化能力就会大大降低;此外,一旦每批训练数据的分布各不相同,那么网络就要在每次迭代都去学习适应不同的分布,这样将会大大降低网络的训练速度。

2. 源码
m = K.mean(X, axis=-1, keepdims=True) //计算均值
std = K.std(X, axis=-1, keepdims=True) //计算标准差
X_normed = (X - m) / (std + self.epsilon) //归一化
out = self.gamma * X_normed + self.beta //重构变换


3. 在超分辨率处理过程中BN层的缺点
神经网络最后重建的SR图像在色彩、对比度、亮度上要求和输入一致,改变的仅仅是分辨率和一些像素细节。但是任何图像经过BN层后,其色彩的分布都会被归一化。也就是说,它破坏了图像原本的对比度信息,因此BN层的加入会影响SR的结果,导致不可预测的伪影。
但是在ResNet使用了BN层,这是因为ResNet中引入了一种叫残差网络结构,其和普通的CNN的区别在于从输入源直接向输出源多连接了一条传递线来来进行残差计算。在ResNet网络中,图像的对比度信息可以通过跳转连接直接传递,所以也就不必担心BN层的破坏。

批量归一化(Batch Normalization, BN)和 Dropout 是两种常用的正则化技术,它们可以加速模型的收敛速度,并提升模型的泛化能力

1. 批量归一化(Batch Normalization)

作用:
  • 加速训练收敛:通过减少内部协变量偏移(Internal Covariate Shift),使得输入分布更加稳定,从而可以使用更高的学习率,加速训练收敛速度
  • 提高稳定性:批量归一化有助于控制梯度的变化范围,防止梯度爆炸或消失
  • 减少对初始化的依赖:使得网络对权重初始化的依赖减小,简化了超参数的选择
  • 正则化效果:批量归一化本身具有一定的正则化作用,可以减少模型的过拟合风险
使用位置:
  • 通常位于卷积层或全连接层之后,激活函数之前
注意事项:
  • 在训练过程中,批量归一化层会维护均值和方差的指数移动平均,以供推理阶段使用
  • 选择合适的小批量大小(Batch Size)对批量归一化的效果有重要影响

2. Dropout

作用:
  • 减少过拟合:通过在训练过程中随机丢弃部分神经元,防止模型对训练数据的过度拟合
  • 增强泛化能力:使模型在未见数据上表现更好
使用位置:
  • 通常位于卷积层或全连接层之后
  • 不建议在批量归一化(BatchNorm)层后直接使用 Dropout,因为两者正则化效果可能重叠,导致训练不稳定
注意事项:
  • Dropout 的丢弃率(如 0.2 或 0.5)需要根据具体任务调整
  • 在推理阶段,Dropout 不会被应用,所有神经元都会参与计算

综合应用

在实际的卷积神经网络中,通常会结合使用批量归一化和 Dropout 来优化模型性能。例如,在构建卷积层时,可以在卷积操作后应用批量归一化,再应用 Dropout。这种组合可以加速模型的收敛速度,同时提高模型的泛化能力
示例代码:
Python复制
import torch
import torch.nn as nn

class ConvBlock(nn.Module):
    def __init__(self, in_channels, out_channels, kernel_size, dropout_rate=0.2):
        super(ConvBlock, self).__init__()
        self.conv = nn.Conv2d(in_channels, out_channels, kernel_size=kernel_size)
        self.bn = nn.BatchNorm2d(out_channels)
        self.relu = nn.ReLU()
        self.dropout = nn.Dropout(dropout_rate)

    def forward(self, x):
        x = self.conv(x)
        x = self.bn(x)
        x = self.relu(x)
        x = self.dropout(x)
        return x
在这个示例中,卷积层后依次应用了批量归一化、ReLU 激活函数和 Dropout
posted @   yinghualeihenmei  阅读(278)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示