乐趣区

关于神经网络:Normalization的基本思想

简述

Normalization 的根本思维其实相当直观:因为深层神经网络在做非线性变换前的激活输出值(就是那个 x =WU+B,U 是输出)随着网络深度加深或者在训练过程中,其散布逐步产生偏移或者变动,之所以训练收敛慢,个别是整体散布逐步往非线性函数的取值区间的上上限两端凑近 (对于 Sigmoid 函数来说,意味着激活输出值 WU+ B 是大的负值或正值), 所以这导致反向流传时低层神经网络的梯度隐没 ,这是训练深层神经网络收敛越来越慢的实质起因,而 Normalization 就是通过肯定的规范化伎俩,把每层神经网络任意神经元这个输出值的散布强行拉回到均值为 0 方差为 1 的规范正态分布, 其实就是把越来越偏的散布强制拉回比拟规范的散布,这样使得激活输出值落在非线性函数对输出比拟敏感的区域,这样输出的小变动就会导致损失函数较大的变动,意思是这样让梯度变大,防止梯度隐没问题产生,而且梯度变大意味着学习收敛速度快,能大大放慢训练速度

简略来说:对于每个隐层神经元,把逐步向非线性函数映射后向取值区间极限饱和区聚拢的输出散布强制拉回到均值为 0 方差为 1 的比拟规范的正态分布,使得非线性变换函数的输出值落入对输出比拟敏感的区域,以此防止梯度隐没问题。因为梯度始终都能放弃比拟大的状态,所以很显著对神经网络的参数调整效率比拟高,就是变动大,就是说向损失函数最优值迈动的步子大,也就是说收敛地快。

BatchNormalization

import numpy as np

def Batchnorm(x, gamma, beta, bn_param):

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

    x_mean = np.mean(x, axis=(0, 2, 3), keepdims=True) #沿着通道计算每个 batch 的均值 u
    x_var = np.var(x, axis=(0, 2, 3), keepdims=True)  #沿着通道计算每个 batch 的方差 σ^2
    x_normalized = (x - x_mean) / np.sqrt(x_var + eps)  #对 x 做归一化,x’=(x-u)/ 开根号(σ^2+ε)
    results = gamma * x_normalized + beta  #退出缩放和平移变量 γ 和 β , 归一化后的值,y=γx’+β

    # 因为在测试时是单个图片测试,这里保留训练时的均值和方差,用在前面测试时用
    running_mean = momentum * running_mean + (1 - momentum) * x_mean
    running_var = momentum * running_var + (1 - momentum) * x_var

    bn_param['running_mean'] = running_mean
    bn_param['running_var'] = running_var

    return results, bn_param

退出缩放平移变量的起因是:保障每一次数据通过归一化后还保留原有学习来的特色,同时又能实现归一化操作,减速训练。这两个参数是用来学习的参数。

Layer Normalizaiton


BN 与 LN 的区别在于:

  • LN 中同层神经元输出领有雷同的均值和方差,不同的输出样本有不同的均值和方差;
  • BN 中则针对不同神经元输出计算均值和方差,同一个 batch 中的输出领有雷同的均值和方差。

所以,LN 不依赖于 batch 的大小和输出 sequence 的深度,因而能够用于 batchsize 为 1 和 RNN 中对边长的输出 sequence 的 normalize 操作。LN 用于 RNN 成果比拟显著,然而在 CNN 上,不如 BN。

def ln(x, b, s):
    _eps = 1e-5
    output = (x - x.mean(1)[:,None]) / tensor.sqrt((x.var(1)[:,None] + _eps))
    output = s[None, :] * output + b[None,:]
    return output

Instance Normalization


BN 重视对每个 batch 进行归一化,保障数据分布统一,因为判断模型中后果取决于数据整体散布。

然而图像风格化中,生成后果次要依赖于某个图像实例,所以对整个 batch 归一化不适宜图像风格化中,因此对 HW 做归一化。能够减速模型收敛,并且放弃每个图像实例之间的独立。Instance Normalization 在图像格调迁徙畛域体现优良。

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

Group Normalization

次要是针对 Batch Normalization 对小 batchsize 成果差,GN 将 channel 方向分 group,而后每个 group 内做归一化,算(C//G)H W 的均值,这样与 batchsize 无关,不受其束缚。

def GroupNorm(x, gamma, beta, G=16):

    # x_shape:[B, C, H, W]
    results = 0.
    eps = 1e-5
    x = np.reshape(x, (x.shape[0], G, x.shape[1]/16, x.shape[2], x.shape[3]))

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

总结

归一化层,目前次要有这几个办法,Batch Normalization(2015 年)、Layer Normalization(2016 年)、Instance Normalization(2017 年)、Group Normalization(2018 年)、Switchable Normalization(2018 年);
batchNorm 是在 batch 上,对 NHW 做归一化,对小 batchsize 成果不好;
layerNorm 在通道方向上,对 CHW 归一化,次要对 RNN 作用显著;
instanceNorm 在图像像素上,对 HW 做归一化,用在风格化迁徙;
GroupNorm 将 channel 分组,而后再做归一化;

参考文献

1、Batch Normalization[https://arxiv.org/pdf/1502.03…]
2、Layer Normalizaiton[https://arxiv.org/pdf/1607.06…]
3、Instance Normalization[https://arxiv.org/pdf/1607.08…]
4、Group Normalization[https://arxiv.org/pdf/1803.08…]
5、https://blog.csdn.net/liuxiao…

退出移动版