0%

ReLU 激活函数中神经元死亡问题

最近在看 MobileNetV3 的结构特征,又碰到了新的激活函数,查看了其与 ReLU 的联系,联想到之前看到过的 ReLU 的问题,做个记录。

ReLU 激活函数可以算作是深度学习领域的 GOAT 了,虽然现在出现了很多变种和发展,但是综合使用范围和效果,其当之无愧。ReLU 之所以能获得广泛认可和应用,离不开自身的特性(图我就不画了)。

  1. 单侧抑制。当输入小于 0 时,神经元处于抑制状态,也就是输出为 0。
  2. 宽阔的激活边界。当输入大于 0 时,神经元全部出于激活状态,激活值取值边界无穷大,无饱和区。
    1. Sigmoid 存在梯度小时问题,就是因为当出于饱和区时,导数趋近于 0,更新缓慢,拖累收敛。
    2. 另一方面,Sigmoid 这类激活函数的导数绝对值小于 1,链式法则的情况下在连乘的时候很容易迅速变小为接近于 0,也是导致梯度消失的原因。
  3. 稀疏性。相比于 Sigmoid 之类的激活函数,稀疏性是 ReLU 的优势。Sigmoid 把抑制区设置为一个极小值,但是不为 0,因此要参与运算,而 ReLU 的抑制区的结果直接为 0,不参与后续计算,简单粗暴的造成网络稀疏性,而且计算十分简单。
    1. 稀疏性和单侧抑制有很多生物神经学上的解释,对于大多数深度学习从业者而言,其计算简单和对网络稀疏性(防止过拟合)的优点才是真正关注的。

ReLU 凭借上述优点获得了无数青睐,但是也不能忽视其存在的不足,甚至一些不足就是由于其自身特性带来的。比如最常见的 ReLU Dying 问题。

ReLU Dying 问题是指当出现异常输入时,在反向传播中会产生大的梯度,这种大的梯度会导致神经元死亡和梯度消失。等等,ReLU 不就是为了解决梯度消失的问题吗?我们提取这里的关键词,异常输入,大梯度,神经元死亡,一一解释。

上图是一个典型的神经元。

现在假设,这个神经元已经经过若干次迭代,其参数 $(\vec w, b)$ 已经迭代得趋于稳定。现在,神经元接收到了一个异常输入 $\vec x$。比方说,它的某一维特征 $x_i$ 与对应的权重 $w_i$ 的乘积 $w_ix_i$ 非常大。一般来说,这意味着 $x_i$ 的绝对值非常大。于是,ReLU 的输入就会很大,对应 ReLU 的输出 $y$ 也就会很大。好了,假设这个 ReLU 神经元期望的输出(ground truth)是 $\hat y$,这个时候损失就会很大——损失一般是 $\lvert y - \hat y\rvert$ 的增函数,记为 $f\bigl(\lvert y - \hat y\rvert\bigr)$。

于是,在反向传播过程中,传递到 ReLU 的输入时的梯度就是 $g = f\bigl(\lvert y - \hat y\rvert\bigr)$ 。考虑对于偏置 $b$ 有更新:

考虑到大梯度 $g$ 是一个很大的正数,于是 $b$ 可能被更新为一个很小的负数。此后,对于常规输入来说,ReLU 的输入大概率是个负数。这也就是说,ReLU 大概率是关闭的。这时,梯度无法经 ReLU 反向传播至 ReLU 的输入函数。也就是说,这个神经元的参数再也不会更新了。这就是所谓的神经元死亡

如此看来,尽管 ReLU 解决了因激活函数导数的绝对值小于 1,在反向传播连乘的过程中迅速变小消失至 0 的问题,但由于它在输入为负的区段导数恒为零,而使得它对异常值特别敏感。这种异常值可能会使 ReLU 永久关闭,而杀死神经元。

由此可见,神经网络中的梯度消失问题是个多元化的问题,不仅仅局限于由于激活函数导数连乘导致的梯度消失。

话说回来,很多激活函数比如 LeakyReLU 把小于 0 的输入的输出不设为 0,从而缓解这个问题,其实现在这个问题已经被 BN 解决了。回到上述我们分析的原因,导致 ReLU Dying 的前提是异常输入,如果 Conv-BN-ReLU 这种结构,由于 BN 的归一化操作,异常输入基本不存在了,所以这个问题也被解决了,这也是目前 ReLU 仍然流行使用的原因。