前言
本文旨在学习和记录,如需转载,请附出处https://www.jianshu.com/p/113246eb8f3b
一、网络参数初始化
在神经网络训练中,训练最小化损失函数以找到一个最优解。但是,不同的网络初始化可能会产生不同的结果。本节主要探讨不同网络参数初始化的效果。
二、网络参数初始化都为0
很显然,如果网络参数都初始化为0时,那么所有的神经元都是一样的功能,网络从一开始训练到结束,所有的神经元的值都是一样的,那么我们的训练就会失败,因为我们期望每个神经元学习的功能是不一样,比如有的神经元对某一类的图片比较敏感,他的值比较大,对某些类的图片不敏感,值比较小。
所以,将网络参数初始化为0或者其他参数很显然是不可以,所以神经元功能一样,都是对称的
初始化高斯分布
标准差较小的初始化
# 均值为0标准差为0.01
w = 0.01*np.random.randn(Din, Dout)
import numpy as np
dims = [4096]*7
hs = []
x = np.random.randn(16,dims[0])
for Din, Dout in zip(dims[:-1],dims[1:]):
W = 0.01*np.random.randn(Din, Dout)
x = np.tanh(x.dot(W))
hs.append(x)
print(np.mean(hs[0],axis=0))
可以发现使用tanh激活函数时,采用小的标准差数值还算比较稳定,但是所有的激活值有像0靠近的趋势,如果所有的值都为0了,学习将失败。如果网络层数加深,很明显最后所有激活值都趋近于0.
标准差较大的初始化
import numpy as np
dims = [4096]*7
hs = []
x = np.random.randn(16,dims[0])
for Din, Dout in zip(dims[:-1],dims[1:]):
W = 0.05*np.random.randn(Din, Dout)
x = np.tanh(x.dot(W))
hs.append(x)
print(np.mean(hs[0],axis=0))
可以发现如果给初始化给较大的标准差,那么tanh所有的激活值都在tanh饱和区范围,我们都知道在饱和区梯度近似为0,所以学习也将失败。
三、Xavier initialization
Xavier initialization方法来源于Understanding the difficulty of training deep feedforward neural networks,该方法的主要思想是为了使网络中信息流动的更好,每一层输出的方差应该尽量相等。
Xavier initialization假设使用的是对称线性激活函数,在x=0处的导数为1。
则:
已知输入数据和权重都是0均值,所以:
这里的代表所有数据每一维的组合。
为了保证输出和输入有相同的方差,所以对权重方差的要求有:
上面计算都是正向传播过程中的,反向传播也是类似的
所以保证前向传播和反向传播的每一层方差一致,有:
实际实验中,因为不一定相等,所以综合考虑有:
又对在[a,b]的均匀分布有:
所以真实的xavier initialization为:
code
这里的code只考虑了前向传播
import numpy as np
dims = [4096]*7
hs = []
x = np.random.randn(16,dims[0])
for Din, Dout in zip(dims[:-1],dims[1:]):
W = np.random.randn(Din, Dout)/np.sqrt(Din)
x = np.tanh(x.dot(W))
hs.append(x)
print(np.mean(hs[0],axis=0))
可以发现对多层神经网络来说,采用tanh激活函数,xavier initialization都工作的很好。
采用ReLU激活函数
import numpy as np
dims = [4096]*7
hs = []
x = np.random.randn(16,dims[0])
for Din, Dout in zip(dims[:-1],dims[1:]):
W = np.random.randn(Din, Dout)/np.sqrt(Din)
x = np.maximum(x.dot(W),0)
hs.append(x)
print(np.mean(hs[0],axis=0))
可以发现,xavier initialization对ReLU激活函数并不是工作的很好,实验中激活值都有趋近于0的迹象,xavier initialization的前提假设是激活函数时线性对称的,ReLU不满足要求,所以就不足为奇了
四、Kaiming initialization
Kaiming initialization也叫He initialzation,是2015年由何凯明提出的,主要针对的是Xavier initialization对Tanh激活函数能表现的很好,可是对ReLU激活函数却表现的很差。
思想:ReLU激活函数只激活输出为正的部分,作者假设每一层有一般的神经元被激活,另一半为0,所以,保持方差不变,在xavier initialization的基础上需要除以2.
所以Kaiming Initialization可以写为:
或者:
code
import numpy as np
dims = [4096]*7
hs = []
x = np.random.randn(16,dims[0])
for Din, Dout in zip(dims[:-1],dims[1:]):
W = np.random.randn(Din, Dout)*np.sqrt(2/Din)
x = np.maximum(x.dot(W),0)
hs.append(x)
print(np.mean(hs[0],axis=0))
可以发现,Kaiming Initialization对ReLU激活函数能工作的很好。
五、结论
1、网络初始化不能全为0;
2、网络参数初始化用随机高斯分布(均值为0),其标准差不能太大,在标准差小的情况下、网络层数不多的情况下可以工作的很好;
3、Xavier initialization适合激活函数采用Tanh的网络
4、Kaiming Initialization适合激活函数采用ReLU的网络
六、参考
- Understanding the difficulty of training deep feedforward neural networks
- Delving deep into rectifiers: Surpassing human-level performance on ImageNet classification
- cs231n教程