神经网络的参数有权重(weights)W和偏置(bias)b。训练神经网络,需要先给网络参数W和b赋初始值,然后经过前向传播和后向传播,迭代更新W和b。这些参数的初始值对于神经网络收敛的速度及神经网络的准确率有很大影响。那么,应该怎么初始化这些参数呢?
不能采用的方法
全0初始化
这部分会从神经网络前向传播及后向传播的角度进行分析,不熟悉前向传播和后向传播的朋友,可以参考我的另一篇博客:神经网络的前向传播和反向传播
假设神经网络有一个输入层、隐层、输出层,如下:
图1:神经网络结构图
以上神经网络中,layer1的输入为x1, x2, x3,layer2的值为z1, z2,经激活函数转换后输出a1, a2。layer3的值为z3。
layer1到layer2的权重矩阵为:
layer2到layer3的权重矩阵为:
则前向传播为(忽略bias):
根据《神经网络的前向传播和反向传播》中所述反向传播算法:
代码函数对权重的改变率(及导数)为:
(BP4)
(BP2)
由于w的初始值为0,则为0,导数为0,则w一直无法更新。
若bias为0,由于:
(BP3)
则bias也无法更新。
全相同常数初始化
不能全0初始化,那能不能采用相同的常数初始化呢?这样导数就不是0了。
我们还是以图1所示神经网络结构进行说明。如果w初始值一样,则隐层中的两个节点,其输入值、输出值完全一样,那么反向传播的时候,两个节点的梯度也完全相同。无论进行多少轮训练,这两个节点完全等价。无论这层有多少个节点,都相当于只有一个节点,其他节点的参数都是冗余的。
所以,每层的参数都不能是相同的常数。第一层全是a,第二层全是b这种也不可以。即,网络不能是对称的。
可以采用的方法
不能使用相同的常数,也就意味着对参数的初始化,需要随机性。那有哪些随机方法呢?下面逐一说明。
注:本节以coursera上Planar data classification为例进行说明,部分代码参考了 https://www.pianshen.com/article/3355323669/
随机初始化
先补一个全0初始值的cost曲线:
def initialize_parameters(n_x, n_h, n_y):
np.random.seed(2) # we set up a seed so that your output matches ours although the initialization is random.
W1 = np.zeros((n_h, n_x))
b1 = np.zeros((n_h, 1))
W2 = np.zeros((n_y, n_h))
b