BatchNorm, LayerNorm, InstanceNorm和GroupNorm

简介

这一篇介绍四种Norm的方式. 之前我们介绍过BatchNorm的方法, Batch Normalization技术介绍. 这一篇会将BatchNorm, LayerNorm, InstanceNorm和GroupNorm这四种Normailzation的技术一起进行比较和说明.

参考资料

  • Pytorch Normalization Layers(官方文档使用说明): Normalization layers
  • Pytorch Normalization中文介绍: ytorch常用normalization函数
  • 下面大图的来源(Twitter上的一张图片): Summary and visualization of different normalization techniques

 

四种Normalization方式介绍

下图是四种Normalization方式的一个汇总(我个人感觉这个图看起来方便一些).

  • 图中每一个正方体块表示一个数据(比如说这里一个正方体就是一个图像)
  • 每一个正方体中的C, H, W分别表示channel(通道个数), height(图像的高), weight(图像的宽)
  • 下图介绍了4中Norm的方式, 如Layer Norm中NHWC->N111表示是将后面的三个进行标准化, 不与batch有关.
  • 我们可以看到, 后面的LayerNorm, InstanceNorm和GroupNorm这三种方式都是和Batch是没有关系的.

BatchNorm, LayerNorm, InstanceNorm和GroupNorm_第1张图片

下面我们使用一个(2, 2, 4)的数据来举一个例子, 我们可以将其看成有2个图像组成的单通道的图像.

 

生成测试使用数据

我们首先生成测试使用的数据, 数据的大小为(2, 2, 4);

  1. x_test = np.array([[[1,2,-1,1],[3,4,-2,2]],
  2.                    [[1,2,-1,1],[3,4,-2,2]]])
  3. x_test = torch.from_numpy(x_test).float()
  4. x_test
  5. """
  6. tensor([[[ 1.,  2., -1.,  1.],
  7.          [ 3.,  4., -2.,  2.]],
  8.  
  9.         [[ 1.,  2., -1.,  1.],
  10.          [ 3.,  4., -2.,  2.]]])
  11. """

 

测试LayerNorm与GroupNorm

关于这里的计算的细节, 会在后面的计算细节描述部分进行叙述. 这里就看一下如何使用Pytorch来进行计算, 和最终计算得到的结果.

LayerNorm就是对(2, 2, 4), 后面这一部分进行整个的标准化. 可以理解为对整个图像进行标准化.

  1. m = nn.LayerNorm(normalized_shape = [2,4])
  2. output = m(x_test)
  3. output
  4. """
  5. tensor([[[-0.1348,  0.4045, -1.2136, -0.1348],
  6.          [ 0.9439,  1.4832, -1.7529,  0.4045]],
  7.  
  8.         [[-0.1348,  0.4045, -1.2136, -0.1348],
  9.          [ 0.9439,  1.4832, -1.7529,  0.4045]]], grad_fn=)
  10. """

GroupNorm中group的数量是1的时候, 是与上面的LayerNorm是等价的.

  1. # Separate 2 channels into 1 groups (equivalent with LayerNorm)
  2. m = nn.GroupNorm(num_groups=1, num_channels=2, affine=False)
  3. output = m(x_test)
  4. output
  5. """
  6. tensor([[[-0.1348,  0.4045, -1.2136, -0.1348],
  7.          [ 0.9439,  1.4832, -1.7529,  0.4045]],
  8.  
  9.         [[-0.1348,  0.4045, -1.2136, -0.1348],
  10.          [ 0.9439,  1.4832, -1.7529,  0.4045]]])
  11. """

 

测试InstanceNorm和GroupNorm

InstanceNorm就是对(2, 2, 4), 标红的这一部分进行Norm.

  1. m = nn.InstanceNorm1d(num_features=2)
  2. output = m(x_test)
  3. output
  4. """
  5. tensor([[[ 0.2294,  1.1471, -1.6059,  0.2294],
  6.          [ 0.5488,  0.9879, -1.6465,  0.1098]],
  7.  
  8.         [[ 0.2294,  1.1471, -1.6059,  0.2294],
  9.          [ 0.5488,  0.9879, -1.6465,  0.1098]]])
  10. """

上面这种InstanceNorm等价于当GroupNormnum_groups的数量等于num_channel的数量.

  1. # Separate 2 channels into 2 groups (equivalent with InstanceNorm)
  2. m = nn.GroupNorm(num_groups=2, num_channels=2, affine=False)
  3. output = m(x_test)
  4. output
  5. """
  6. tensor([[[ 0.2294,  1.1471, -1.6059,  0.2294],
  7.          [ 0.5488,  0.9879, -1.6465,  0.1098]],
  8.  
  9.         [[ 0.2294,  1.1471, -1.6059,  0.2294],
  10.          [ 0.5488,  0.9879, -1.6465,  0.1098]]])
  11. """

 

计算细节描述

我们看一下在上面的LayerNorm和InstanceNorm中的结果是如何计算出来的. 我们只看第一行第一列的数据1进行标准化的过程. 下面是详细的计算的过程(这里的计算结果与上面直接计算的结果是相同的).

BatchNorm, LayerNorm, InstanceNorm和GroupNorm_第2张图片

 

每一种方式适合的场景

这里我也是没有自己测试过, 就先放一下我看到的别人写的内容.

  • batchNorm是在batch上,对小batchsize效果不好;
  • layerNorm在通道方向上,主要对RNN作用明显;
  • instanceNorm在图像像素上,用在风格化迁移;
  • GroupNorm将channel分组,然后再做归一化, 在batchsize<16的时候, 可以使用这种归一化;

你可能感兴趣的:(自然语言处理,语音,深度学习)