谈一谈深度学习中的归一化问题
如下图所示,以3个隐藏层的神经网络为例,每层网络只有一个神经元:
其中H表示**函数,这里选择sigmoid函数为**函数。损失函数为
根据梯度下降法和反向传播算法来更新w1、w2、w3、w4:
其中H函数表示sigmoid**函数。
若wi的初始化值小于1;当x位于sigmoid函数两侧时,其dH(x)/dx的导数接近于0。因此经过多层的反向传播,导致损失函数J对w1的倒数接近于0。这就是梯度消失或梯度弥散。
因此,层数越靠前的网络越容易出现梯度消失,如下图所示。
梯度消失的原因:网络太深,导致梯度无法方向传播;**函数选择不当,即**函数存在饱和性;w初始化太小。梯度爆炸的原理和梯度消失类似,不再多说。
解决方法:
1.选择合适的**函数,可以选择RELU、Leaky ReLU、maxout、ELU等。
2.当**函数为tanh时,w可以用Xavier进行初始化,即W = np.random.randn( fan_in, fan_out) / np.sqrt(fan_in);当**函数为ReLU,可以使用He进行初始化,即W = np.random.randn( fan_in, fan_out) / np.sqrt(fan_in / 2)。
3.使用批归一化:输入层的数据,已经人为的归一化,后面网络每一层的输入数据分布是一直在发生变化的,前面层训练参数的更新将导致后面层输入数据分布的变化,因此必然会引起后面每一层输入数据分布的改变。为了使每一层的数据(**值)分布变得统一,对每一层的数据进行归一化的处理后,再经过**函数。
批归一化的作用:
1.**值随着参数W的变化,其分布也发生变化,当其数值趋近**函数的非线性饱和区,如sigmoid函数两端,这样使得梯度接近于0,随着网络层次的加深而造成梯度消失,进而无法进行训练。若将**值拉到均值为0、方差为1的分布区域,这样大部分数据就从梯度趋于0的位置变换到梯度较大的区域,从而解决了梯度消失。由于归一化影响了原始网络输出层的表达能力,因此引入参数γ和β进行调整。
2.若样本特征较为分散,可能导致神经网络学习速度缓慢甚至无法学习,即梯度下降难以收敛。将样本的每一层数据进行批归一化,则特征的分布较为统一,训练速度加快,甚至训练效果更好,即加快收敛速度。