【pytorch】BN层计算

官方文档
有一个针对BN层的详细的理解:

Pytorch的BatchNorm层使用中容易出现的问题

class torch.nn.BatchNorm2d(num_features, eps=1e-05, momentum=0.1, affine=True)[source]

对小批量(mini-batch)3d数据组成的4d输入进行批标准化(Batch Normalization)操作
在这里插入图片描述

在每一个小批量(mini-batch)数据中,计算输入各个维度的均值和标准差。gamma与beta是可学习的大小为C的参数向量(C为输入大小)

在训练时,该层计算每次输入的均值与方差,并进行移动平均。移动平均默认的动量值为0.1。

在验证时,训练求得的均值/方差将用于标准化验证数据。

参数:

  • num_features: 来自期望输入的特征数,该期望输入的大小为’batch_size x num_features x height
  • x width’ eps: 为保证数值稳定性(分母不能趋近或取0),给分母加上的值。默认为1e-5。 momentum:
    动态均值和动态方差所使用的动量。默认为0.1。
  • affine: 一个布尔值,当设为true,给该层添加可学习的仿射变换参数。 Shape:
  • 输入:(N, C,H, W) - 输出:(N, C, H, W)(输入输出相同)
### 自定义或调整 PyTorch 中 Batch Normalization 的行为 在 PyTorch 中,`nn.BatchNorm1d`, `nn.BatchNorm2d`, 和 `nn.BatchNorm3d` 是用于不同维度数据的批量归一化。如果需要自定义或调整这些的行为,可以通过以下方式实现: #### 1. 修改现有参数 PyTorch 提供了多个可配置参数来控制 Batch Normalization 的行为。以下是常用参数及其作用: - **num_features**: 输入通道数。 - **eps**: 防止除零操作的小数值,默认为 `1e-5`[^2]。 - **momentum**: 跟踪运行平均值和方差时使用的动量因子,默认为 `0.1`。 - **affine**: 是否学习缩放和平移参数 γ 和 β,默认为 `True`。 - **track_running_stats**: 是否跟踪全局均值和方差,默认为 `True`。 可以轻松通过设置上述参数来自定义 BN 行为。例如: ```python import torch.nn as nn bn_layer = nn.BatchNorm2d(num_features=64, eps=1e-3, momentum=0.01, affine=True, track_running_stats=False) ``` #### 2. 替换统计计算逻辑 若需更改默认的均值和方差计算逻辑,可通过继承 `nn.Module` 并重写前向传播函数实现。例如,在训练阶段使用其他统计数据替代小批内的均值和方差: ```python class CustomBatchNorm(nn.Module): def __init__(self, num_features, eps=1e-5, momentum=0.1, affine=True, track_running_stats=True): super(CustomBatchNorm, self).__init__() self.bn = nn.BatchNorm2d( num_features=num_features, eps=eps, momentum=momentum, affine=affine, track_running_stats=track_running_stats ) def forward(self, x): # 使用自定义均值和方差替换默认值 batch_mean = x.mean(dim=(0, 2, 3), keepdim=True).detach() batch_std = x.std(dim=(0, 2, 3), unbiased=False, keepdim=True).detach() + 1e-5 normalized_x = (x - batch_mean) / batch_std return self.bn.weight * normalized_x + self.bn.bias ``` #### 3. 实现完全自定义的 BN 对于更复杂的场景,可以直接从头构建 BN 。这涉及手动完成正则化、缩放以及平移的操作: ```python class FullyCustomBatchNorm(nn.Module): def __init__(self, num_features, eps=1e-5, momentum=0.1, device=None, dtype=None): factory_kwargs = {'device': device, 'dtype': dtype} super(FullyCustomBatchNorm, self).__init__() self.num_features = num_features self.eps = eps self.momentum = momentum self.register_buffer('running_mean', torch.zeros((1, num_features, 1, 1), **factory_kwargs)) self.register_buffer('running_var', torch.ones((1, num_features, 1, 1), **factory_kwargs)) self.gamma = nn.Parameter(torch.ones((1, num_features, 1, 1), **factory_kwargs)) # Scale parameter self.beta = nn.Parameter(torch.zeros((1, num_features, 1, 1), **factory_kwargs)) # Shift parameter def forward(self, x): if self.training: mean = x.mean([0, 2, 3], keepdim=True) var = x.var([0, 2, 3], unbiased=False, keepdim=True) self.running_mean.mul_(1 - self.momentum).add_(mean.detach(), alpha=self.momentum) self.running_var.mul_(1 - self.momentum).add_(var.detach(), alpha=self.momentum) else: mean = self.running_mean var = self.running_var x_normalized = (x - mean) / torch.sqrt(var + self.eps) out = self.gamma * x_normalized + self.beta return out ``` 以上代码展示了如何创建一个完整的自定义 BN ,支持训练模式下的动态更新和推理模式下固定统计量的功能。 --- #### 总结 通过对 PyTorch 默认 BN 参数的调整或者重新设计其内部机制,能够灵活满足特定需求。无论是简单地改变超参还是深入定制核心功能,都可以借助 PyTorch 的模块化特性高效达成目标[^1].
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值