神经网络的初始化参数方法

神经网络的参数也就是权重W很多,通过BP反向传播可以逐渐得到使Cost Function最小的参数,但是这些参数的初始值对于收敛的速度,最后的准确率有很大的影响,那么我们应该怎么初始化呢?

1.全部置为0

这种方法简单粗暴,但是是不可行的,试想权重全为0,那么前向传播结果为0,反向同样为0,无法更新。

2.置为很小的值

W=0.01*np.random.rand(D,H)
这种初始化方法在神经网络的层数很少时可以使用,层数多了就会出现问题,最后参数全部为0,首先在前向传播过程中输出为h(wx+b)因为w很小,所以输出很小,同时反向传播过程中梯度的变化也很小,那么参数的改变也很小,在不断的正向传播乘很小的数,反向传播又几乎不变的情况下,最后w会越来越小,趋近于0,出现梯度弥散现象。

3.Xavier initial

上面的初始化方法都是存在问题的,而在激活函数里可以看到sigmoid函数会出现饱和现象出现梯度消失,而ReLU核没有限制参数的范围,那么如果初始化出现问题势必会造成深度网络中参数过大失去控制,影响模型效果,而参数过小会使得参数趋向于0,那么Xavier就是针对反向传播效果很好的ReLU核在参数控制方面所做的努力,通过Xavier可以将参数置于


区间范围内,那么具体的推导方法时通过这篇文章学习的。
https://zhuanlan.zhihu.com/p/22028079
首先是与方差有关的定理:
1.w*x就会服从均值为0,方差为σ 2 的分布
2.w*x+w*x就会服从均值为0,方差为2*σ 2的分布.

我们在输入数据到神经网络的时候都要先对数据进行处理,具体来说我们可以将数据处理为均值为0,方差为σx的分布,我们将参数w初始化成均值为0,方差为σw的分布,我们假设第一次是大家喜闻乐见的卷积层,卷积层共有n个参数(n=channelkernel_hkernel_w),于是为了计算出一个线性部分的结果,我们有:


线性输出部分的一个结果值,实际上是由n个乘加计算出来的,那么下面是一道抢答题,按照我们刚才对x和w的定义,加上前面我们说过的两个方差计算公式,这个z会服从一个什么分布呢?
均值肯定还是0。
方差好像积累了一大堆东西:n*σ xw
为了更好地表达,我们将层号写在变量的上标处,于是就有:

对于k层就有:

继续把这个公式展开,就会得到它的最终形态:

可以看出,后面的那个连乘实际上看着就像个定时炸弹(相信看到这,我应该能成功地吸引大家的注意力,帮助大家把非线性函数线性化的事情忘掉了……),如果总是大于1,那么随着层数越深,数值的方差会越来越大,反过来如果乘积小于1,那么随着层数越深,数值的方差就会越来越小。niwi越来越大,就容易Hold不住导致溢出,越来越小,就容易导致数据差异小而不易产生有力的梯度。这就是深层模型的一大命门。
那么我们回头看最初的公式


如果两层的x的方差相等即:

那么
image.png

所以我们用均值为0,方差为上面的式子的数来初始化就可以。

这是通过前向传播所得到的结论,我们希望反向传播仍然有这样的特点,那么梯度的改变是遵循这样一种分布的,最后参数的变化是数值稳定的,那么我们来看看梯度的变化。

假设我们还是一个k层的网络,现在我们得到了第k层的梯度,那么对于第k-1层输入的梯度,有

也就是说,K-1层一个数值的梯度,相当于上一层的n个参数的乘加。这个n个参数的计算方式和之前方式一样,只是表示了输出端的数据维度,在此先不去赘述了。
于是我们如果假设每一层的参数也服从某种均值为0,方差为某值的分布就像前向传播那样,会有:



同样的,为了方差为定值,需要:

得到

但是两个n实际上不是同一个n。对于全连接来说,前向操作时,n表示了输入的维度,而后向操作时,n表示了输出的维度。而输出的维度也可以等于下一层的输入维度。所以两个公式实际上可以写作:


神经网络的初始化参数方法_第1张图片

这么看上去前向后向不是很统一,所以前辈将两者融合,得到了方差为:


的均匀分布。

那么我们假设数据落在[-a,a]之间那么方差为



此时计算所得
神经网络的初始化参数方法_第2张图片

所以Xavier 的范围就是这个,具体的初始化方法
W=np.random.randn(fan_in,fan_out)/np.sqrt(fan_in/2)(ReLU)
W=np.random.randn(fan_in,fan_out)/np.sqrt(fan_in)(tanh)
当然caffe等现成库是有的,直接设置一下就好。

你可能感兴趣的:(神经网络的初始化参数方法)