1. 摘要
本文尝试解释为什么在深度的神经网络中随机初始化会让梯度下降表现很差,并且在此基础上来帮助设计更好的算法。
作者发现 sigmoid 函数不适合深度网络,在这种情况下,随机初始化参数会让较深的隐藏层陷入到饱和区域。
作者提出了一个新的参数初始化方法,称之为 Xavier 初始化,来帮助深度网络更快地收敛。
2. 激活函数的作用以及训练过程中的饱和现象
2.1. 三种激活函数
T a n h ( x ) = 1 ? e ? x 1 + e ? x Tanh(x)=\frac{1-e^{-x}}{1+e^{-x}} Tanh(x)=1+e?x1?e?x?
S i g m o i d ( x ) = 1 1 + e ? x Sigmoid(x)=\frac{1}{1+e^{-x}} Sigmoid(x)=1+e?x1?
S o f t s i g n ( x ) = x 1 + ∣ x ∣ Softsign(x)=\frac{x}{1+|x|} Softsign(x)=1+∣x∣x?
2.2. Sigmoid 函数
通过观察训练过程中每一个隐藏层激活值的均值和方差,我们可以发现第 4 层的激活值很快就进入到了饱和区域,非常接近于 0。由于 Sigmoid 函数在接近于 0 的时候梯度很小,这样的话反向传播过程就会学习得很慢,虽然最终网络会慢慢离开饱和区域,但往往学到的解也不是最优的。
2.3. Tanh 函数和 Softsign 函数
由于 Tanh 函数和 Softsign 函数接近于 0 的时候梯度近似线性,所以它们不会遇到像 Sigmoid 上面的情况。但是,采用 Tanh 作为激活函数时,从第一层到第四层的激活值却也会在训练过程中依次进入饱和区域。而采用 Softsign 的话,所有层都逐渐进入饱和区域,但这个过程会更慢一点。
在训练完成后,我们可以发现以 Tanh 作为激活函数,最终每层的激活值大多落在饱和区域和 0 附近;以 Softsign 作为激活函数,最终每层的激活值大多落在 (-0.6, -0.8) 和 (0.6, 0.8) 区间。
3. 梯度以及它们的传播
3.1. 损失函数
作者发现采用似然损失比用二次的均方误差要好,因为采用似然损失不容易陷入到平缓区域,不会让训练过程变得很慢。如下图所示,可以看到采用二次损失的损失函数有很多平缓区域。
3.2. Xavier 初始化
针对一个对称的激活函数,并且其在原点处的导数为 1,那么我们有:
根据以上定义,可以得到:
假设初始时我们位于线性区域,权重之间互相独立,并且输入的特征具有一样的方差 V a r [ x ] Var[x] Var[x],第 i i i 层具有 n i n_i ni? 个神经元,那么有:
可参考 Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification 对比进行分析。
在前向过程中,为了保持信息,让每一层都具有一样的方差,即:
那么我们可以得到:
同样,考虑梯度的反向传播,我们可以得到:
为了保证每一层梯度的方差一致,也即:
我们有:
若同时考虑到前向传播的反向传播的约束,我们想要:
对此,我们用下面的方法来初始化参数
其中, U U U 代表均匀分布,其方差为
( b ? a ) 2 12 = 2 n j + n j + 1 \frac{(b-a)^2}{12} = \frac{2}{n_j+n_{j+1}} 12(b?a)2?=nj?+nj+1?2?
正好符合我们的预期。
可以看到,在前向传播过程中,旧的初始化方法,越靠后的层激活值越容易陷入到 0 区域,而采用新的初始化方法后,每一层的激活值分布基本相同。
在反向传播过程中,旧的初始化方法,越靠前的层梯度值越容易陷入到 0 区域,而采用新的初始化方法后,每一层的梯度分布基本相同。
5. 实验结果
获取更多精彩,请关注「seniusen」!