Batch Normalization、Instance normalization简单理解

本文介绍了深度学习中两种重要的归一化技术——BatchNormalization(BN)和InstanceNormalization(IN)。BN主要解决内部协变量漂移问题,加速模型训练,适用于大batchsize;而IN则作用于单个图像,常用于生成模型如风格迁移,保持图像实例间特性。两者均通过计算均值和方差进行归一化,并可通过γ和β参数调整。BN对整个batch操作,可能导致图像细节丢失,而IN则保留了这些细节。文章提供了相关代码示例,并提到了GroupNormalization作为BN和IN的替代选择。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. Batch Normalization

首先,简短介绍一下Batch Normalization,通常Batch Normalization更为大家所知,所以在此简要介绍BN来引入Instance Normalization

引入BN层主要是为了解决"Internal Covariate Shift"问题,关于这个问题李宏毅老师有个视频讲解比较形象[4],可以参考。Batch Normalization主要是作用在batch上,对NHW做归一化,对小batchsize效果不好,添加了BN层能加快模型收敛,一定程度上还有的dropout的作用。

BN的基本思想其实相当直观:因为深层神经网络在做非线性变换前的激活输入值(就是那个x=WU+B,U是输入)随着网络深度加深或者在训练过程中,其分布逐渐发生偏移或者变动,之所以训练收敛慢,一般是整体分布逐渐往非线性函数的取值区间的上下限两端靠近(对于Sigmoid函数来说,意味着激活输入值WU+B是大的负值或正值),所以这导致反向传播时低层神经网络的梯度消失,这是训练深层神经网络收敛越来越慢的本质原因而BN就是通过一定的规范化手段,把每层神经网络任意神经元这个输入值的分布强行拉回到均值为0方差为1的标准正态分布,其实就是把越来越偏的分布强制拉回比较标准的分布,这样使得激活输入值落在非线性函数对输入比较敏感的区域,这样输入的小变化就会导致损失函数较大的变化,意思是这样让梯度变大,避免梯度消失问题产生,而且梯度变大意味着学习收敛速度快,能大大加快训练速度。

在BN论文中有下面这样一幅图,比较清楚的表示了BN具体是怎么操作的:
在这里插入图片描述

前三步就是对一个batch内的数据进行归一化,使得数据分布一致:沿着通道计算每个batch的均值,计算每个batch的方差,对 X X X做归一化。重点在第四步,**加入缩放和平移参数 γ , β \gamma,\beta γ,β **。这两个参数可以通过学习得到,增加这两个参数的主要目的是完成归一化之余,还要保留原来学习到的特征。

总结如下:

  • 沿着通道计算每个batch的均值 μ \mu μ
  • 沿着通道计算每个batch的方差 σ 2 \sigma ^ 2 σ2
  • 对x做归一化, x ′ = ( x − μ ) / σ 2 + ϵ x' = (x-\mu) / \sqrt{\sigma ^2 + \epsilon} x=(xμ)/σ2+ϵ
  • 加入缩放和平移变量 γ \gamma γ β \beta β ,归一化后的值, y = γ x ′ + β y=\gamma x' + \beta y=γx+β

2. Instance Normalization

IN和BN最大的区别是,IN作用于单张图片,BN作用于一个batch。IN多适用于生成模型中,例如风格迁移。像风格迁移这类任务,每个像素点的信息都非常重要,BN就不适合这类任务。BN归一化考虑了一个batch中所有图片,这样会令每张图片中特有的细节丢失。IN对HW做归一化,同时保证了每个图像实例之间的独立。

论文中所给的公式如下:
在这里插入图片描述

总结如下:

  • 沿着通道计算每张图的均值 μ \mu μ
  • 沿着通道计算每张图的方差 σ 2 \sigma ^ 2 σ2
  • 对x做归一化, x ′ = ( x − μ ) / σ 2 + ϵ x' = (x-\mu) / \sqrt{\sigma ^2 + \epsilon} x=(xμ)/σ2+ϵ
  • 加入缩放和平移变量 γ \gamma γ β \beta β ,归一化后的值, y = γ x ′ + β y=\gamma x' + \beta y=γx+β
def Instancenorm(x, gamma, beta):

    # x_shape:[B, C, H, W]
    results = 0.
    eps = 1e-5

    x_mean = np.mean(x, axis=(2, 3), keepdims=True)
    x_var = np.var(x, axis=(2, 3), keepdims=True0)
    x_normalized = (x - x_mean) / np.sqrt(x_var + eps)
    results = gamma * x_normalized + beta
    return results

pytorch中使用BN和IN:

class IBNorm(nn.Module):
    """ Combine Instance Norm and Batch Norm into One Layer
    """

    def __init__(self, in_channels):
        super(IBNorm, self).__init__()
        in_channels = in_channels
        self.bnorm_channels = int(in_channels / 2)
        self.inorm_channels = in_channels - self.bnorm_channels 

        self.bnorm = nn.BatchNorm2d(self.bnorm_channels, affine=True)
        self.inorm = nn.InstanceNorm2d(self.inorm_channels, affine=False) # IN,多用于风格迁移
        
    def forward(self, x):
        bn_x = self.bnorm(x[:, :self.bnorm_channels, ...].contiguous())  
        in_x = self.inorm(x[:, self.bnorm_channels:, ...].contiguous()) 

        return torch.cat((bn_x, in_x), 1)

下图来自何凯明大神2018年的论文Group Normalization[3],可以说很直观了。

在这里插入图片描述

Reference:

[1] Ioffe S, Szegedy C. Batch normalization: Accelerating deep network training by reducing internal covariate shift[C]//International conference on machine learning. PMLR, 2015: 448-456.

[2] Ulyanov D, Vedaldi A, Lempitsky V. Instance normalization: The missing ingredient for fast stylization[J]. arXiv preprint arXiv:1607.08022, 2016.

[3] Wu Y, He K. Group normalization[C]//Proceedings of the European conference on computer vision (ECCV). 2018: 3-19.

[4] 【深度学习李宏毅 】 Batch Normalization (中文)

[4] *深入理解Batch Normalization批标准化

[5] Batch Normalization原理与实战

[6] *BatchNormalization、LayerNormalization、InstanceNorm、GroupNorm、SwitchableNorm总结

GroupNorm、SwitchableNorm总结](https://blog.csdn.net/liuxiao214/article/details/81037416)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

烤粽子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值