1、梯度消失和爆炸
梯度消失:一是在深层网络中;二是采用了不合适的损失函数,比如sigmoid(导数最大为0.25,神经网络的反向传播是逐层对函数偏导相乘,因此当神经网络层数非常深的时候,最后一层产生的偏差就因为乘了很多的小于1的数而越来越小,最终就会变为0,从而导致层数比较浅的权重没有更新,这就是梯度消失。)。
梯度爆炸:一般出现在深层网络和权值初始化值太大的情况下。前面层会比后面层变化的更快,就会导致权值越来越大,梯度爆炸的现象就发生了。
前向传播得到的结果与实际的结果得到一个偏差,然后通过梯度下降法的思想,通过偏导数与残差的乘积通过从最后一层逐层向前去改变每一层的权重。通过不断的前向传播和反向传播不断调整神经网络的权重,最终到达预设的迭代次数或者对样本的学习已经到了比较好的程度后,就停止迭代,那么一个神经网络就训练好了。
反向传播是梯度的连乘向前传更新权重。如果此部分大于1,那么层数增多的时候,最终的求出的梯度更新将以指数形式增加,即发生梯度爆炸;如果此部分小于1,那么随着层数增多,求出的梯度更新信息将会以指数形式衰减,即发生了梯度消失。
2、解决方法
(1)梯度消失(深度网络中出现更多):
用ReLU激活函数来替代sigmoid函数;
合理的初始化权重值。初始化权重,使每个神经元尽可能不要取极大或极小值,以躲开梯度消失的区域。
残差学习;
批量归一化。
(2)梯度爆炸:
减少学习率;
权重正则化;
因为梯度爆炸的时候,我们的程序会收到NaN错误。我们也可以设置一个梯度阈值,当梯度超过这个阈值的时候可以直接截取。
批量归一化。
3、权重初始化
我们可以通过改变权重w的分布,使掩藏层输入量尽量接近于0 而不是使权重w接近0,如果x非常非常小,则权重应该稍微大点,这样在正常的激活函数下能够分布在0附近。这就是我们为什么需要进行权重初始化的原因了。
(1)初始化为0或一固定值问题:
w初始化全为0,很可能直接导致模型失效,无法收敛。全零初始化方法在前向传播过程中会使得隐层神经元的激活值均为0,在反向过程中根据BP公式,不同维度的参数会得到相同的更新。需要破坏这种“对称性”。
因此可以对w初始化为随机值解决(在cnn中,w的随机化,也是为了使得同一层的多个filter,初始w不同,可以学到不同的特征,如果都是0或某个值,由于计算方式相同,可能达不到学习不同特征的目的)
(2)高斯分布初始化
可以选择随机初始化为很小的值(非常接近0的小数,正如我们上面所讨论的不能等于0)。上述建议的一个问题是,随机初始化神经元的输出的分布有一个随输入量增加而变化的方差。
目的是为了使神经元的输出服从均值为0,方差为1的正态分布,产生有效的激活。
Xavier 初始化是兼顾了BP过程的除以( (n_in + n_out)/2 ),还有初始化方法是截断正态分布,将权重在离均值两个标准差外的值去掉。
深度学习权重的初始化的太小,那信号将会在每层传递时逐渐缩小导致难以产生作用,如果权重初始化的太大,那信号将在每层间传递逐渐放大导致发散和失效,根据深度学习大牛的理论说明列,权重应该是满足均值为0,(Xavier初始化)方差为2除以两层神经元个数之和,就是权重链接的那两层。满足的分布就是均匀分布或者高斯分布。
(3)批量归一化
批量归一化放在激活函数之前,使网络对初始化更鲁棒。
参考文献:https://blog.csdn.net/qq_25737169/article/details/78847691