最近在看 MobileNetV3 的结构特征,又碰到了新的激活函数,查看了其与 ReLU 的联系,联想到之前看到过的 ReLU 的问题,写了这篇文章
ReLU 激活函数可以算作是深度学习领域的 GOAT 了,虽然现在出现了很多变种和发展,但是综合使用范围和效果,其当之无愧。ReLU 之所以能获得广泛认可和应用,离不开自身的特性(图我就不画了)。
- 单侧抑制。当输入小于 0 时,神经元处于抑制状态,也就是输出为 0。
- 宽阔的激活边界。当输入大于 0 时,神经元全部出于激活状态,激活值取值边界无穷大,无饱和区。
- Sigmoid 存在梯度小时问题,就是因为当出于饱和区时,导数趋近于 0,更新缓慢,拖累收敛。
- 另一方面,Sigmoid 这类激活函数的导数绝对值小于 1,链式法则的情况下在连乘的时候很容易迅速变小为接近于 0,也是导致梯度消失的原因。
- 稀疏性。相比于 Sigmoid 之类的激活函数,稀疏性是 ReLU 的优势。Sigmoid 把抑制区设置为一个极小值,但是不为 0,因此要参与运算,而 ReLU 的抑制区的结果直接为 0,不参与后续计算,简单粗暴的造成网络稀疏性,而且计算十分简单。
- 稀疏性和单侧抑制有很多生物神经学上的解释,对于大多数深度学习从业者而言,其计算简单和对网络稀疏性(防止过拟合)的优点才是真正关注的。
ReLU 凭借上述优点获得了无数青睐,但是也不能忽视其存在的不足,甚至一些不足就是由于其自身特性带来的。比如最常见的 ReLU Dying 问题。
ReLU Dying 问题是指当出现异常输入时,在反向传播中会产生大的梯度,这种大的梯度会导致神经元死亡和梯度消失。等等,ReLU 不就是为了解决梯度消失的问题吗?我们提取这里的关键词,异常输入,大梯度,神经元死亡,一一解释。
上图是一个典型的神经元。
现在假设,这个神经元已经经过若干次迭代,其参数 w\mathbf{w}w 和 bbb 已经迭代得趋于稳定。现在,神经元接收到了一个异常输入 x\mathbf{x}x。比方说,它的某一维特征 xix_ixi 与对应的权重 wiw_iwi 的乘积 wixiw_i x_iwixi 非常大。一般来说,这意味着 xix_ixi 的绝对值非常大。于是,ReLU 的输入就会很大,对应 ReLU 的输出 yyy 也就会很大。好了,假设这个 ReLU 神经元期望的输出(ground truth)是 y^\hat{y}y^,这个时候损失就会很大——损失一般是 ∣y−y^∣|y - \hat{y}|∣y−y^∣ 的增函数,记为 f(∣y−y^∣)f(|y - \hat{y}|)f(∣y−y^∣)。
于是,在反向传播过程中,传递到 ReLU 的输入时的梯度就是 g=f(∣y−y^∣)g=f(|y - \hat{y}|)g=f(∣y−y^∣)。考虑对于偏置 bbb 有更新:
b=b−α⋅gb = b - \alpha \cdot gb=b−α⋅g
其中,α\alphaα 是学习率。
考虑到大梯度ggg是一个很大的正数,于是 b bb 可能被更新为一个很小的负数。此后,对于常规输入来说,ReLU 的输入大概率是个负数。这也就是说,ReLU 大概率是关闭的。这时,梯度无法经 ReLU 反向传播至 ReLU 的输入函数。也就是说,这个神经元的参数再也不会更新了。这就是所谓的神经元死亡。
如此看来,尽管 ReLU 解决了因激活函数导数的绝对值小于 1,在反向传播连乘的过程中迅速变小消失至 0 的问题,但由于它在输入为负的区段导数恒为零,而使得它对异常值特别敏感。这种异常值可能会使 ReLU 永久关闭,而杀死神经元。
由此可见,神经网络中的梯度消失问题是个多元化的问题,不仅仅局限于由于激活函数导数连乘导致的梯度消失。
话说回来,很多激活函数比如 LeakyReLU 把小于 0 的输入的输出不设为 0,从而缓解这个问题,其实现在这个问题已经被 BN 解决了。回到上述我们分析的原因,导致 ReLU Dying 的前提是异常输入,如果 Conv-BN-ReLU 这种结构,由于 BN 的归一化操作,异常输入基本不存在了,所以这个问题也被解决了,这也是目前 ReLU 仍然流行使用的原因。
总结和思考
ReLU作为深度学习领域的"GOAT",优点包括单侧抑制、宽阔的激活边界和稀疏性。但它也存在不足,最常见的是ReLU Dying问题。这个问题是指当出现异常输入时,在反向传播中会产生大的梯度,这种大的梯度会导致神经元死亡和梯度消失。因此,需要根据具体问题选择适当的激活函数。