各种Normalization
ICS(Internal Covariate Shift)
,Batch Normalization
在2015年被提出1,效果很好,到现在已经成为了深度学习必不可少的工具。之后,为了解决BN
效果依赖batch_size
大小等局限,Layer Normalization(LN)
2、Instance Normalization(IN)
3、Group Normalization(GN)
4、Switchable Normalization(SN)
5、Weight Normalization(WN)
6等方法也陆续被提出,在不同的任务领域中起到了加快收敛、提升效果等积极作用。无论是学习还是工程,了解Normalization
都是有所裨益的。本文将阐述Nor
malization
的基本原理,介绍较为常用的Normalization
方法,并对Normalization
的作用原理进行一些讨论。
Normalization
基本原理
Normalization
是一种对目标值进行规范化处理的函数,希望将目标值约束到某个分布区间内,来缓解深度学习中ICS
的问题。各种Normalization
,本质上都是对目标值x进行scale
与shift
处理:
其中,μ是目标值的均值,σ为目标值的方差。将目标值规范为均值为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
对这个batch
的n
个实例的对应channel
(图中相同颜色的部分)进行计算,求出c
个μ与σ,特征图中的每个值使用对应channel
的μ与σ进行归一化,即:
其中ε是防止零除的微小常数。对于c
个channel
的特征图,将得到c
组μ、σ、γ、β。
下面我们看一下BN
在Pytorch
中的具体使用:
>>> inputs = torch.Tensor(2, 3, 4, 4)
>>> bn = torch.nn.BatchNorm2d(3, affine=True, track_running_stats=True)
>>> result = bn(inputs)
其中, affine
参数控制BN
是否学习rescale
与reshift
参数,track_running_stats
参数控制BN
是否跨batch
跟踪运行时的均值和方差,如果不跟踪这些统计数据,则在训练和eval
模式下都只使用当前batch
的统计数据 。可训练的参数weight
即为公式中的γ,bias
为β,running_mean、running_var
为跨batch
跟踪得到的μ、β。可以看到,对于channel
为3的feature map
,weight,bias,running_mean, running_var
的size
均为3,与channel
数相同。BN对参数初始化不敏感,可以加快收敛,而且BN对同一个batch中不同实例进行规范操作,相当于引入了随机噪声,可以增强模型的泛化能力。但BN也存在一些不足,首先是BN的效果严重依赖batch_size的大小,在GN的论文中作者对比了不同batch size下ImageNet的分类任务的效果如图,可以看到batch_size较小时BN的效果明显下降。
图片来源:Group Normalization论文插图
batch size
很多时是1,通常使用训练时的running_mean, running_var
,如果推理数据与训练数据分布有差异,可能会存在效果偏差。同时,BN
也无法适应如RNN
等一个batch
为了规避对batch_size
的依赖,同时适应动态输入,2016年,一种新的Normalization
方式Layer Normalization
被提出。同样对于(n, c, h, w)
的特征图,LN
对这个batch
的n
个实例每个实例本身(图中相同颜色的部分)进行计算,求出n
个μ与σ,特征图中的每个值使用对应实例的μ与σ进行归一化,即:
LN
是计算每个实例本身的均值方差,推理时同样计算当前实例的均值方差,不需要依赖训练时的统计量,所以与BN
不同的是,Ln
不会保存训练时的running_mean、running_var
。在进行rescale
与reshift
时,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上的分布也较为相似。所以LN
在NLP
任务中取得了良好的效果,而在关注channel
上差异信息的图像任务中BN
效果更好。
对于风格迁移这种pix2pix的任务,每个样本的独特特征是很重要的,而BN
在batch
上进行了归一化,损失了样本独有特征,因此不适合此类任务。同样的,LN
损失了channel
特征,不适合图像任务。在这样的背景下,2017年,一种新的Normalization
方法IN
被提出。对于(n, c, h, w)
的特征图,IN
对这个batch
的n
个实例每个实例的每个channel
(图中相同颜色的部分)进行计算,求出n*c
个μ与σ,特征图中的每个值使用对应实例对应channel
的μ与σ进行归一化,即:
Adaptive Instance Normalization
7中,作者提出风格迁移本质上是将待迁移图片的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
。
2018年,GN
被提出。GN
是一种介于LN
与IN
之间的方法,对于(n, c, h, w)
的特征图,GN
将c
个channel
按照顺序分为G
组(图中相同颜色的部分)进行计算,求出n*c//G
个μ与σ,特征图中的每个值使用对应实例对应channel
组的μ与σ进行归一化,即:
G=1
时,GN
等价于LN
,G=C
时,GN
等价于IN
。所以GN
的Normalization
空间比LN
、IN
更丰富。
的一种直觉是,feature map
中各个channel
并不是独立的,一些相关性较强、具有类似的分布的channel
可以分为一组计算统计量。GN
原文中进行了大量实验对比GN
与LN、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
维的weight
与bias
。对于要求batch_size
很小的任务,GN
是非常合适的选择。
图片来源: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论文插图
前面的方法都是对feature map
的Normalization
,而WN
顾名思义,则是直接对weight
进行Normalization
。权值上的Normalization
完全没有引入额外参数,同时也避免了对batch
的依赖,可以应用在动态输入的网络中。具体的,WN
将weight
分解为一个参数向量V和一个参数标量g:
对于一个神经元来说,有:
Normalization
基本原理中μ=0、σ=||V||、β=0的情况,本质上也是对数据进行规范化操作。WN
对初始化更敏感,论文中作者建议了一种初始化的策略:对V使用均值为0、标准差为0.05的正态分布进行初始化,对g和b使用初始样本的统计量进行初始化。具体的:
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
两个参数,对应于公式中的g,V。在训练时,分别对g,V进行更新。推理时,可以使用torch.nn.utils.remove_weight_norm(cnn)
将卷积层还原为分解前的形式。对于噪声敏感的任务如风格迁移等,WN
可以得到比较好的效果。
的有效性
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
[3]Instance Normalization: The Missing Ingredient for Fast Stylization
[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]
- 点赞
- 收藏
- 关注作者
评论(0)