在深层神经网络中,对权重W的初始化往往用标准正态缩小来进行
但有时使用 randn*0.01 而有时却使用 randn*sqrt(d) 来缩写
经查资料可知,对于不同的激活函数如sigmoid、tanh或ReLU等,所使用的缩写倍数并不相同
结论:
- 对于sigmoid函数用0.01: w = 0.01* np.random.randn(N,NL)
- 对于tanh函数用根号(1/NL):w = np.random.randn(N,NL) / sqrt(1/ NL)
- 对于ReLU函数用根号(2/NL):w = np.random.randn(N, NL) / sqrt(2 / NL)
* N是本层的神经元个数(本层维度),NL是上一层的神经元个数(上一层维度)
资料参考:
1、
2、《深度学习:吴恩达编程作业问题L1W4》https://blog.csdn.net/weixin_43868020/article/details/107850036https://blog.csdn.net/weixin_43868020/article/details/1078500363、《吴恩达·深度学习 》第二门课 1.11 神经网络的权重初始化http://www.ai-start.com/dl2017/html/lesson2-week1.html#header-n266
将《权重W 参数初始化 · deep learning》全文摘录如下:
权重W初始化
全部初始化为0
全部初始化为0,导致一个问题就是每个神经元的输出是一样的,那么在反向传播时,更新的梯度肯定也是一样的,也就是说不管怎么迭代,网络的里参数全部都是一样的,这就没法玩了。
高斯随机初始化
W = 0.01* np.random.randn(D,H)
我们依然想要靠近0的初始化,所以采用零均值,标准差为1的高斯分布,然后乘以0.01,相当与将权重缩小100倍来初始化,这样可以打破上一种初始化方式的的对称,名字叫symmetry breaking.
这种初始化方式在小网络中还能用,但是放到比较深的网络就跪了。lecture5的ppt给出了实验结果图,使用这种方式初始化,随着深度的增加,大概到第三层以后,每层输出的均值和标准差基本为0。也就是说所有的激活函数输出为0.这就导致了反向传播过程中,梯度消失,因为W∗XW∗X的导数肯定是和XX有关,XX现在为0,那么梯度也就为0了。这样就没法玩了。 当初始化参数过大,比如
W = 1.0* np.random.randn(D,H)
这会导致神经元饱和,输出要么是-1,要么是+1,梯度依然为0。 以上例子都是以tanh函数为激活函数举例。
Xavier 初始化
w = np.random.randn(fan_in, fan_out) / sqrt(fan_in) # fan_in是输入的个数
推理过程见笔记,基于的思想是保证每一层的输入和输出的方差一致。即找出什么样的W可以使Var(s)=Var(x)Var(s)=Var(x)成立,其中s=∑niwixis=∑inwixi.
如果使用ReLU作为激活函数,初始化方式为
w = np.random.randn(fan_in, fan_out) / sqrt(fan_in/2)
稀疏初始化
将权重矩阵为0,但是为了打破对称,可以只连接部分神经元,其他神经元不连接,连接的神经元个数一般设为10. 有点类似dropout的做法。
bias初始化
一般bias初始化为0,对于ReLu类的激活函数,bias初始化为0.01,防止其开始被抑制导致一直无法更新梯度。