一、常见初始化方式
1、正态分布随机初始化
torch.nn.init.normal_(X(Tensor), mean: float = 0.0, std: float = 1.0)
2、均匀分布随机初始化
torch.nn.init.uniform_(X(Tensor), a: float = 0.0, b: float = 1.0)
3、Xavier初始化
条件:基于激活函数是线性的,如tanh,不适用于Relu,sigmoid等,且激活函数需要关于0对称,在传播时,方差不变
推导:
基于上图,
假定,X,w是0均值,则后两项为0,简化为
同理,反向传播时应有相似表达
(1)当X,w服从均匀分布时,
torch.nn.init.xavier_uniform_(X(Tensor), gain: float = 1.0)
(2)当X,w服从正态分布时,
torch.nn.init.xavier_normal_(X(Tensor), gain: float = 1.0)
4、kaiming初始化
证明了每一层初始权重仅和当前层神经元的数目相关
(1)均匀分布
torch.nn.init.kaiming_uniform_(X(Tensor), a=0, mode='fan_in', nonlinearity='leaky_relu')
(2)正态分布
torch.nn.init.kaiming_normal_(X(Tensor), a=0, mode='fan_in', nonlinearity='leaky_relu')
二、网络参数初始化为0(或初始化为统一值可以吗)
不行。会导致网络中所有神经元学习到的是相同的特征。不同神经元的输出一样,相同输出导致梯度更新完全一样,使更新后参数保持一样的状态,那么就无法训练模型。
具体来说:如果权重初始化为0,在前向传播的过程中,当前层的输出乘以全为0的权重,那么输出就为0,即下一层的输入为0,经过下一层的激活函数(若为sigmoid)输出全为0.5,即为下层的输入全相同,直到最后的输出也相同,而在反向传播计算梯度,由于每一层的操作都是相同的(同样权重的卷积层和激活函数),导致同一隐藏层的参数更新的幅度是一样的,同时初值也一样,就导致权重参数永远一样。
三、随机初始化的优缺点
优点:事先人为预估了输入的分布,随机初始化+BN还是能够很快收敛,但是估计分布很难,网络也不可以很深,同时BN只能算是一个减少随机初始化影响的办法(没有办法的办法)。
缺点:网络输出数据的方法会随着该层神经元个数的改变而变化,因为np.random.randn()其实是一个均值为0,方差为1的高斯分布,当神经网络的层数增多时,会发现越往后面的层的激活函数(使用tanH)的输出值几乎都接近于0,激活函数输出值接近于0会导致梯度非常接近于0,因此会导致梯度消失。
四、bias为什么可以初始化为0
因为一般的卷积层之后都会接BN层,但是对于BN层,bias无作用,且占内存,所以一般设为0
推导如下:
BN层公式为
x=x0*w0+b0,对于E[x]
E[x]=E[x0*w0+b0]=E[x0*w0]+b0,带入原式,发现b0被减
对于Var[x]
Var[x]=Var[x0*w0+b0]=w0*w0[x0],b0不起作用
因此b可以初始化为0
五、为什么需要一个好的初始化参数的方式
首先,网络能有一个较好的收敛速度,能尽可能使其收敛到全局最优,能够在一定程度上缓解梯度消失以及爆炸。
六、什么是一个好的初始化方法
期望为0,且参数正负各半
初始化参数不能过大,也不能过小,过大可能使数据在各层传递时逐渐放大而导致梯度消失或者爆炸,过小则会导致特征在每层间逐渐缩小而难以产生作用
以上内容均来源于各个版主、牛客网总结