各种Normalization

举报
杜甫盖房子 发表于 2020/07/22 14:22:09 2020/07/22
【摘要】 介绍Normalization的基本原理和较为常用的Normalization方法,并对Normalization的作用原理进行一些讨论

为了减轻深度学习中的ICS(Internal Covariate Shift)Batch Normalization在2015年被提出1,效果很好,到现在已经成为了深度学习必不可少的工具。之后,为了解决BN效果依赖batch_size大小等局限,Layer Normalization(LN)2Instance Normalization(IN)3Group Normalization(GN)4Switchable Normalization(SN)5Weight Normalization(WN)6等方法也陆续被提出,在不同的任务领域中起到了加快收敛、提升效果等积极作用。无论是学习还是工程,了解Normalization都是有所裨益的。本文将阐述Normalization的基本原理,介绍较为常用的Normalization方法,并对Normalization的作用原理进行一些讨论。


Normalization基本原理

Normalization是一种对目标值进行规范化处理的函数,希望将目标值约束到某个分布区间内,来缓解深度学习中ICS的问题。各种Normalization,本质上都是对目标值x进行scaleshift处理:

其中,μ是目标值的均值,σ为目标值的方差。将目标值规范为均值为0,方差为1的正态分布范围,这样固然可以使当前目标值落入非线性函数激活区,同时使神经网络深层输入与浅层输出解耦,但同时也大大影响了神经网络的表达能力,尤其是非线性表达能力。所以在Normalization中,还要通过可学习的rescale参数γreshift参数β将目标值x规范为均值为β、方差为γ²的分布,来补偿神经网络的表达能力。

不同的Normalization方法,区别主要在于x的选择域不同、μ与σ的计算域不同,下面将详细介绍常用的Normalization方法。

常用Normalization

常用的Normalization中,BN、LN、IN、GN、SN都选择将输入特征图作为目标值x进行Normalization,而WN是将权重矩阵W作为目标值x进行Normalization。而BN等对特征图进行归一化时,μσ的计算域又各有异同。

Batch Normalization

对于一个(n, c, h, w)的特征图,BN对这个batchn个实例的对应channel(图中相同颜色的部分)进行计算,求出c个μ与σ,特征图中的每个值使用对应channel的μ与σ进行归一化,即:

其中ε是防止零除的微小常数。对于cchannel的特征图,将得到c组μ、σ、γ、β

下面我们看一下BNPytorch中的具体使用:

>>> inputs = torch.Tensor(2, 3, 4, 4)
>>> bn = torch.nn.BatchNorm2d(3, affine=True, track_running_stats=True)
>>> result = bn(inputs)


其中, affine参数控制BN是否学习rescalereshift参数,track_running_stats参数控制BN是否跨batch跟踪运行时的均值和方差,如果不跟踪这些统计数据,则在训练和eval模式下都只使用当前batch的统计数据 。可训练的参数weight即为公式中的γbias为βrunning_mean、running_var为跨batch跟踪得到的μ、β。可以看到,对于channel为3的feature map,weight,bias,running_mean, running_varsize均为3,与channel数相同。BN对参数初始化不敏感,可以加快收敛,而且BN对同一个batch中不同实例进行规范操作,相当于引入了随机噪声,可以增强模型的泛化能力。但BN也存在一些不足,首先是BN的效果严重依赖batch_size的大小,在GN的论文中作者对比了不同batch sizeImageNet的分类任务的效果如图,可以看到batch_size较小时BN的效果明显下降。

图片来源:Group Normalization论文插图

此外,推理时batch size 很多时是1,通常使用训练时的running_mean, running_var,如果推理数据与训练数据分布有差异,可能会存在效果偏差。同时,BN也无法适应如RNN等一个batch数据长度不等的动态输入。


Layer Normalization

为了规避对batch_size的依赖,同时适应动态输入,2016年,一种新的Normalization方式Layer Normalization被提出。同样对于(n, c, h, w)的特征图,LN对这个batchn个实例每个实例本身(图中相同颜色的部分)进行计算,求出n个μ与σ,特征图中的每个值使用对应实例的μ与σ进行归一化,即:



LN是计算每个实例本身的均值方差,推理时同样计算当前实例的均值方差,不需要依赖训练时的统计量,所以与BN不同的是,Ln不会保存训练时的running_mean、running_var。在进行rescalereshift时,Pytorch允许给定计算维度,可以对特征图中每个元素进行单独的仿射变换学习。

>>> inputs = torch.Tensor(2, 3, 4, 4)
>>> ln = torch.nn.LayerNorm(inputs.size()[1:])
>>> result = ln(inputs)
>>> print(ln.weight.shape, ln.bias.shape)

torch.Size([3, 4, 4]) torch.Size([3, 4, 4])

BN可以理解为对不同样本的同一个特征进行归一化,LN则是对同一个样本的不同特征进行归一化,这在某种程度上可能会降低模型的表达能力,因此在进行仿射变换时逐元素学习仿射变换参数可以补偿损失的信息。也因为LN是对同一个样本进行处理,因此可以处理可变长度的输入,很适合NLP任务。此外,NLP的样本各个特征比较相似,因此channle上的分布也较为相似。所以LNNLP任务中取得了良好的效果,而在关注channel上差异信息的图像任务中BN效果更好。


Instance Normalization

对于风格迁移这种pix2pix的任务,每个样本的独特特征是很重要的,而BNbatch上进行了归一化,损失了样本独有特征,因此不适合此类任务。同样的,LN损失了channel特征,不适合图像任务。在这样的背景下,2017年,一种新的Normalization方法IN被提出。对于(n, c, h, w)的特征图,IN对这个batchn个实例每个实例的每个channel(图中相同颜色的部分)进行计算,求出n*c个μ与σ,特征图中的每个值使用对应实例对应channel的μ与σ进行归一化,即:

在后续工作Adaptive Instance Normalization7中,作者提出风格迁移本质上是将待迁移图片的feature map分布与风格图片的feature map分布对齐,由此提出了自适应实例归一化,简单的对齐待迁移图片与风格图片feature map中每个channel的均值和方差,就在实验中取得了不错的效果:


图片来源:Arbitrary Style Transfer in Real-time with Adaptive Instance Normalization论文插图

>>> inputs = torch.Tensor(2, 3, 4, 4)
>>> ins = torch.nn.InstanceNorm2d(num_features=3, affine=True, track_running_stats=False)
>>> result = ins(inputs)

IN参数与BN相同,但track_running_stats默认为false,推理时使用当前输入的统计量进行Normalization

Group Normalization

2018年,GN被提出。GN是一种介于LNIN 之间的方法,对于(n, c, h, w)的特征图,GNcchannel按照顺序分为G组(图中相同颜色的部分)进行计算,求出n*c//G个μ与σ,特征图中的每个值使用对应实例对应channel组的μ与σ进行归一化,即:

G=1时,GN 等价于LNG=C时,GN 等价于IN 。所以GNNormalization空间比LNIN更丰富。

GN的一种直觉是,feature map中各个channel并不是独立的,一些相关性较强、具有类似的分布的channel可以分为一组计算统计量。GN原文中进行了大量实验对比GNLN、IN尤其是BN的效果,在ImageNet上进行试验,batch_size足够大时BN效果显著,但GN在不同batch_size下稳定性更好。


图片来源:Group Normalization论文插图

>>> inputs = torch.Tensor(2, 6, 4, 4)
>>> gn = torch.nn.GroupNorm(num_groups=3, num_channels=6)
>>> result = gn(inputs)

GN的参数为分组数、channel数,可训练参数同样是c维的weightbias。对于要求batch_size很小的任务,GN是非常合适的选择。


Switchable Normalization

图片来源:Switchable Normalization论文代码库图示

上述normalization方法经过实验验证了各自适合的任务领域,但落在具体任务时,仍要根据经验人工选择Normalization方法,再经过对照试验确认方法与任务的适配性。为了使任务自适应的学习Normalization方法,2018年,SN被提出。如图,SN的统计量为BN、IN、LN的加权和,是可微的,可以在训练的过程中进行学习。具体的:

其中w为网络可学习的权重λ的softmax归一化,所有加权系数w和为1。

在具体实现时,对于(n, c, h, w)的特征图x

>>> N, C, H, W = x.size()
>>> x = x.view(N, C, -1)
>>> mean_in = x.mean(-1, keepdim=True)
>>> var_in = x.var(-1, keepdim=True)
>>> mean_ln = mean_in.mean(1, keepdim=True)
>>> temp = var_in + mean_in ** 2
>>> var_ln = temp.mean(1, keepdim=True) - mean_ln ** 2
>>> mean_bn = mean_in.mean(0, keepdim=True)
>>> var_bn = temp.mean(0, keepdim=True) - mean_bn ** 2
>>> running_mean.mul_(momentum) # 滑动平均
>>> running_mean.add_((1 - momentum) * mean_bn.data)
>>> running_var.mul_(momentum)
>>> running_var.add_((1 - momentum) * var_bn.data)
>>> softmax = nn.Softmax(0)
>>> mean_weight = softmax(mean_weight)
>>> var_weight = softmax(var_weight)
>>> mean = mean_weight[0] * mean_in + mean_weight[1] * mean_ln + mean_weight[2] * mean_bn
>>> var = var_weight[0] * var_in + var_weight[1] * var_ln + var_weight[2] * var_bn
>>> x = (x - mean) / (var + eps).sqrt()
>>> x = x.view(N, C, H, W)

SN是一个任务无关的归一化方法,论文在分类,检测,风格迁移等多种任务上对SN进行了实验, 均取得了良好的效果:

分类:

检测:

风格迁移:

图表来源:Switchable Normalization论文插图

Weight Normalization

前面的方法都是对feature mapNormalization,而WN顾名思义,则是直接对weight进行Normalization。权值上的Normalization完全没有引入额外参数,同时也避免了对batch的依赖,可以应用在动态输入的网络中。具体的,WNweight分解为一个参数向量V和一个参数标量g

对于一个神经元来说,有:

可以看作是Normalization基本原理中μ=0、σ=||V||、β=0的情况,本质上也是对数据进行规范化操作。与之前的方法相比,WN对初始化更敏感,论文中作者建议了一种初始化的策略:对V使用均值为0、标准差为0.05的正态分布进行初始化,对gb使用初始样本的统计量进行初始化。具体的:

Pytorch中也提供了WN的方法:

>>> inputs = torch.Tensor(2, 6, 4, 4)
>>> cnn = torch.nn.utils.weight_norm(torch.nn.Conv2d(in_channels=6, out_channels=32, kernel_size=3))
>>> print(cnn.weight.shape, cnn.weight_g.shape, cnn.weight_v.shape)
>>> result = cnn(inputs)

torch.Size([32, 6, 3, 3]) torch.Size([32, 1, 1, 1]) torch.Size([32, 6, 3, 3])

可以看到,对一个卷积层使用WN,该层原始weight不变,另外多出weight_g, weight_v两个参数,对应于公式中的gV。在训练时,分别对gV进行更新。推理时,可以使用torch.nn.utils.remove_weight_norm(cnn)将卷积层还原为分解前的形式。对于噪声敏感的任务如风格迁移等,WN可以得到比较好的效果。


Normalization的有效性

BN中,作者提出了internal covariate shift(ICS)的概念。具体的,机器学习有个基本假设:源空间的训练数据和目标空间的待预测数据独立同分布。如果数据的分布不同,则称为数据偏移。covariate shift是数据偏移的一种,是指训练数据和待预测数据的条件概率相同,边缘概率不同。internal covariate shift即为层间信号的covariate shift,会使深度学习模型对初始化敏感,上层参数反复适应下层参数的变化,层间输出容易陷入下层饱和区,从而导致模型难训练、不易收敛。  

但在后续的研究8中通过实验指出,BN的性能增益和ICS的减少之间似乎没有任何联系,在某种意义上,BN甚至不能减少网络的ICS

该论文在BN层后面增加了独立同分布并且均值不为0、方差不为1的随机噪声,这种噪声注入会产生严重的ICS,使得每层在每个时间的输入分布都是不同的,以此来衡量这种故意引入的分布不稳定性对BN的影响,标准网络、添加BN、添加BN与噪声的实验中各层的激活分布结果如图:

图片来源:How Does Batch Normalization Help Optimization?论文插图

可以看到,应用了BN的网络也依然存在ICS,而添加了噪声的网络也并没有影响BN的效果。说明BN的有效性与ICS之间的相关性并不高。后续实验中,对比标准网络与加入BN的网络的损失和梯度如图,可以看到,加入了BN的网络损失和梯度都更平滑,实验通过L-Lipschitz函数衡量得到加入BN的网络损失曲面更平滑,因此,BN的有效性体现在平滑损失曲面及梯度上。

图片来源:How Does Batch Normalization Help Optimization?论文插图

[1]Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift

[2]Layer Normalization

[3]Instance Normalization: The Missing Ingredient for Fast Stylization

[4]Group Normalization

[5]Differentiable Learning-to-Normalize via Switchable Normalization

[6]Weight Normalization: A Simple Reparameterization to Accelerate Training of Deep Neural Networks

[7]Arbitrary Style Transfer in Real-time with Adaptive Instance Normalization

[8]How Does Batch Normalization Help Optimization?

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。