Batch Normalization和Layer Normalization和Group normalization


前言

  批量规范化和层规范化在神经网络中的每个批次或每个层上进行规范化,而GroupNorm将特征分成多个组,并在每个组内进行规范化。这种规范化技术使得每个组内的特征具有相同的均值和方差,从而减少了特征之间的相关性。通常,组的大小是一个超参数,可以手动设置或自动确定。
  相对于批量规范化,GroupNorm的一个优势是它对批次大小的依赖性较小。这使得GroupNorm在训练小批量样本或具有不同批次大小的情况下更加稳定。另外,GroupNorm还可以应用于一维、二维和三维的输入,适用于不同类型的神经网络架构。
  GroupNorm的一种变体是分组卷积(Group Convolution),它将输入通道分成多个组,并在每个组内进行卷积操作。这种结构可以减少计算量,并提高模型的效率。

在这里插入图片描述

  • BatchNorm:batch方向做归一化,算N* H*W的均值
  • LayerNorm:channel方向做归一化,算C* H* W的均值
  • InstanceNorm:一个channel内做归一化,算H*W的均值
  • GroupNorm:将channel方向分group,然后每个group内做归一化,算(C//G) * H * W的均值

一、Group normalization

  Group normalization(GroupNorm)是深度学习中用于规范化神经网络激活的一种技术。它是一种替代批量规范化(BatchNorm)和层规范化(LayerNorm)等其他规范化技术的方法。

import torch
import torch.nn as nn

class GroupNorm(nn.Module):
    def __init__(self, num_groups, num_channels, eps=1e-5):
        super(GroupNorm, self).__init__()
        self.num_groups = num_groups
        self.num_channels = num_channels
        self.eps = eps
        
        self.weight = nn.Parameter(torch.ones(1, num_channels, 1, 1))
        self.bias = nn.Parameter(torch.zeros(1, num_channels, 1, 1))
    
    def forward(self, x):
        batch_size, num_channels, height, width = x.size()
        
        # 将特征重塑成 (batch_size * num_groups, num_channels // num_groups, height, width)
        x = x.view(batch_size, self.num_groups, -1, height, width)
        
        # 计算每个组内的均值和方差
        mean = x.mean(dim=(2, 3, 4), keepdim=True)
        var = x.var(dim=(2, 3, 4), keepdim=True)
        
        # 规范化
        x = (x - mean) / torch.sqrt(var + self.eps)
        
        # 重塑特征
        x = x.view(batch_size, num_channels, height, width)
        
        # 应用缩放和平移
        x = x * self.weight + self.bias
        
        return x

# 使用示例
group_norm = GroupNorm(num_groups=4, num_channels=64)
inputs = torch.randn(32, 64, 32, 32)
outputs = group_norm(inputs)
print(outputs.shape)

二、批量规范化(Batch Normalization)

  BatchNorm的基本思想是对每个特征通道在一个小批次(即一个批次中的多个样本)的数据上进行规范化,使得其均值接近于0,方差接近于1。这种规范化可以有助于加速神经网络的训练,并提高模型的泛化能力。
  具体而言,对于给定的一个特征通道,BatchNorm的计算过程如下:

  1. 对于一个小批次中的输入数据,计算该特征通道上的均值和方差。
  2. 使用计算得到的均值和方差对该特征通道上的数据进行规范化,使得其均值为0,方差为1。
  3. 对规范化后的数据进行缩放和平移操作,使用可学习的参数进行调整,以恢复模型对数据的表示能力。

  通过在训练过程中对每个小批次的数据进行规范化,BatchNorm有助于解决梯度消失和梯度爆炸等问题,从而加速模型的收敛速度。此外,BatchNorm还具有一定的正则化效果,可以减少模型对输入数据的依赖性,增强模型的鲁棒性。

import torch
import torch.nn as nn

class BatchNorm(nn.Module):
    def __init__(self, num_features, eps=1e-5, momentum=0.1):
        super(BatchNorm, self).__init__()
        self.num_features = num_features
        self.eps = eps
        self.momentum = momentum
        
        # 可学习的参数
        self.weight = nn.Parameter(torch.ones(num_features))
        self.bias = nn.Parameter(torch.zeros(num_features))
        
        # 移动平均的均值和方差
        self.running_mean = torch.zeros(num_features)
        self.running_var = torch.ones(num_features)
    
    def forward(self, x):
        if self.training:
            # 在训练模式下,计算当前Batch的均值和方差
            mean = x.mean(dim=(0, 2, 3), keepdim=True)
            var = x.var(dim=(0, 2, 3), keepdim=True)
            
            # 更新移动平均的均值和方差
            self.running_mean = (1 - self.momentum) * self.running_mean + self.momentum * mean.squeeze()
            self.running_var = (1 - self.momentum) * self.running_var + self.momentum * var.squeeze()
        else:
            # 在推理模式下,使用移动平均的均值和方差
            mean = self.running_mean.unsqueeze(0).unsqueeze(2).unsqueeze(3)
            var = self.running_var.unsqueeze(0).unsqueeze(2).unsqueeze(3)
        
        # 归一化
        x = (x - mean) / torch.sqrt(var + self.eps)
        
        # 缩放和平移
        x = x * self.weight.unsqueeze(0).unsqueeze(2).unsqueeze(3) + self.bias.unsqueeze(0).unsqueeze(2).unsqueeze(3)
        
        return x
batch_norm = BatchNorm(num_features=64)
inputs = torch.randn(32, 64, 32, 32)
outputs = batch_norm(inputs)
print(outputs.shape)

三、层规范化(Layer Normalization)

  与批量规范化相比,层规范化更适用于对序列数据或小批次样本进行规范化,例如自然语言处理任务中的文本序列。它在每个样本的特征维度上进行规范化,使得每个样本在特征维度上具有相似的分布。
层规范化的计算过程如下:
对于每个样本,计算该样本在特征维度上的均值和方差。

  1. 使用计算得到的均值和方差对该样本的特征进行规范化,使得其均值为0,方差为1。
  2. 对规范化后的特征进行缩放和平移操作,使用可学习的参数进行调整,以恢复模型对数据的表示能力。
import torch
import torch.nn as nn

class LayerNorm(nn.Module):
    def __init__(self, num_features, eps=1e-5):
        super(LayerNorm, self).__init__()
        self.num_features = num_features
        self.eps = eps
        
        # 可学习的参数
        self.weight = nn.Parameter(torch.ones(num_features))
        self.bias = nn.Parameter(torch.zeros(num_features))
    
    def forward(self, x):
        # 计算输入张量的均值和方差
        mean = x.mean(dim=(1, 2, 3), keepdim=True)
        var = x.var(dim=(1, 2, 3), keepdim=True)
        
        # 归一化
        x = (x - mean) / torch.sqrt(var + self.eps)
        
        # 缩放和平移
        x = x * self.weight.unsqueeze(0).unsqueeze(2).unsqueeze(3) + self.bias.unsqueeze(0).unsqueeze(2).unsqueeze(3)
        
        return x

# 使用示例
layer_norm = LayerNorm(num_features=64)
inputs = torch.randn(32, 64, 32, 32)
outputs = layer_norm(inputs)
print(outputs.shape)
  • 48
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Batch Normalization(批归一化)和 Layer Normalization(层归一化)都是用于神经网络中的正则化技术,旨在提高模型的训练效果和泛化能力。 Batch Normalization是在深度神经网络中应用广泛的技术之一。它的主要思想是通过对每个批次(batch)的输入进行归一化,使得输入在每个特征维度上具有零均值和单位方差。这样做的好处是可以加速网络的收敛速度,减轻梯度消失问题,并有一定的正则化效果。Batch Normalization层通常在全连接层或卷积层之后,激活函数之前添加。 Layer Normalization是与Batch Normalization类似的技术,但它的归一化方式不是基于批次,而是基于每个样本在特征维度上进行归一化。具体而言,Layer Normalization对每个样本的特征进行归一化,使得每个样本在特征维度上具有零均值和单位方差。与Batch Normalization不同,Layer Normalization可以应用于任意大小的批次,甚至可以应用于单个样本。Layer Normalization通常在循环神经网络(RNN)等需要处理可变长度序列数据的模型中使用。 虽然Batch NormalizationLayer Normalization有不同的归一化方式,但它们的目标都是通过减少内部协变量转移(Internal Covariate Shift)来加速训练过程,并提高模型的泛化能力。它们在训练深度神经网络时都可以发挥重要作用,具体选择哪种方法取决于应用场景和网络结构。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值