首先,问题描述:

当很多个使用sigmoid的Layers 加到神经网络中时,损失函数的梯度会接近0,这会导致 network难以训练。因为我们使用梯度乘以学习率来更新权值参数的。

那么为什么呢?

像sigmoid这样的激活函数,它把输入从一个大的空间压缩到一个只有0到1的范围内的很小的空间,作为下一层的输入。因此在输入层一个大的改变,通过sigmoid,最终到输出只有一个小的改变,也就是说导数变小了。

sigmoid求梯度推导 sigmoid梯度消失_sigmoid求梯度推导


上图,蓝色实线是sigmoid函数形态,红色虚线是其导数的几何形态。我们可以看出,当输入值很大或很小时,也就是说当输入值向横轴的两端延伸时,导数接近于0

如果是只有几个sigmoid层的浅层神经网络,这并不会引起很大的问题。然而,当非常多的sigmoid层时,它会导致梯度太小而无法训练,这就是我们说的梯度消失。

神经网络的梯度通过反向传播来得到,简单的说,反向传播通过从最终层到初始层,误差逐层传播来得到梯度,通过链式求导法则,每一层的导数会乘到一起来计算初始层的导数。

然后,当n个隐层使用像sigmoid这样的激活函数时,会有n个非常小的导数值乘到一起,这样,随着我们逐层反向传播到初始层,梯度会呈指数级的下降。

显然极小的梯度值使得初始层的权值和偏置几乎无法有效的更新。而这些初始层,在识别输入数据的基础模式是至关重要的,它的不准确将导致整个神经网络的不准确。

解决方法

最简单的解决方法是使用另一种激活函数,比如 ReLU,它通常不会产生一个很小的导数

另外还有一个方法,是batch normalization

由前面的叙述,我们知道,梯度消失的产生,是因为sigmoid把输入从很大的空间映射到了一个很小的空间,尤其是当|X|很大的时候,它的导数都是接近0的。batch normalization 通过简单的标准化,来减轻该问题的产生,

sigmoid求梯度推导 sigmoid梯度消失_神经网络_02


我们可以看到,input标准化后,它会落在绿色的区域内,因此他的导数也不会太小。