在学习神经网络的时候见到了许多的激活函数,但是对每一个函数的理解不够深刻,在此总结一下激活函数的用途以及常见的激活函数。

0x01 激活函数


Activation Process

理论上,神经网络可以拟合任意非线性函数和线性函数,其可以拟合非线性函数的原因就在于这个激活函数是非线性的

如果激活函数是线性的,那么 $W_2(W_1x+b_1)+b_2$ 也只是简单的线性叠加,最后得到的也只能是线性函数。

如果激活函数是非线性的,那么 $g(Wx+b)$ 得出来的可以是线性的,也可以是非线性的,最后两者类型的函数都可以拟合出来。

0x02 Sigmoid

Sigmoid

$$f(x)=\frac{1}{1+e^{-x}}$$

  • 定义域 (−∞, +∞)
  • 值域 (0, 1)
  • 输入值在两端时会出现梯度消失(Sigmoids saturate and kill gradients)
  • 输出值不是 0 均值的(Sigmoid outputs are not zero-centered.)

输入值在两端会会出现梯度消失(缺点)

从图中我们可以得知,当函数输入的很小火很大的时候(即逼近函数上下界的时候),函数趋于平缓,也就是说导数将趋于 0 ,则梯度就接近与 0。

由于神经网络的权值更新依靠的就是激活函数的导数,当激活函数的导数趋于 0 的时候,梯度接近于 0 ,权值更新就几乎停滞不前了。

由于 Sigmoid 函数梯度容易消失的特征,所以业内都很少在隐藏层使用,多用于输出层

输出值不是 0 均值的(缺点)

Sigmoid 函数的输出值恒大于0,这会导致模型训练的收敛速度变慢。

举个例子,对 $g(Wx+b)$ ,如果所有的 $x$ 均为正数或负数,那么其对 $W$ 的导数总是正数或负数,这会导致如下图红色箭头所示的阶梯式更新,这显然并非一个好的优化路径。

深度学习往往需要大量时间来处理大量数据,模型的收敛速度是尤为重要的。所以总体上来讲,训练深度学习网络尽量标准化输入和标准化输出。

Sigmoid Zero Problem

应用场景

由于 Sigmoid 函数的输出值在 0 和 1 之间,因此该激活函数常用于二分类的输出层,其他地方很少用。

比如说,Kaggle 举办的 Dogs vs. Cats,判断是狗的概率,反之则是猫的概率。

0x03 Tanh

Tanh

$$f(x)=\frac{e^{x}-e^{-x}}{e^{x}+e^{-x}}$$

$$tanh(x)=2sigmoid(2x)-1$$

  • 定义域 (−∞, +∞)
  • 值域 (-1, 1)
  • 输入值在两端时会出现梯度消失

Tanh 的原名叫做 Hyperbolic function,中文名字叫做 双曲正切函数

Tanh 从某种意义来说是 Sigmoid 的进化类型,该函数解决了 Sigmoid 函数的输出不是 0 均值的,因此 Tanh 比 Sigmoid 效果会好一些。

直观点理解就是将 Sigmoid 函数图像向下移动,直到中心点(对称点)与原点重合。

但是 Tanh 和 Sigmoid 都有同一个问题,即当函数输入在定义域两端时容易出现梯度消失问题,因此我们也很少在隐藏层中使用。

应用场景

需要输出对称的结果的时候,比如 (-1, 1), (-6, 6) 之类的。

比如说,Udacity ML 毕业项目之一的 DeepTelsa,输出车辆转向角度的预测。

0x04 ReLU

ReLu

$$f(x) = max(0, x)$$

  • 定义域 (−∞, +∞)
  • 值域 [0, +∞)
  • 加速算法收敛(与 Sigmoid & Tanh 相比)
  • 易于计算,只有比较和本身
  • 神经元傲娇易于失活

ReLU 的原名叫做 Rectified Linear Unit,中文名字叫做 线性修正单元

加速算法收敛(优点)

ReLU Speed Up Convergence

由于它的非线性、梯度不饱和(梯度一直存在)特征,能够大幅提高收敛速度

实验表明(Krizhevsky et al.),ReLU 比 tanh 的收敛速度快 6 倍。

易于计算(优点)

没有复杂和大开销的计算,只有比较是否大于 0 和输出自身这两种运算,大大加快了正向传播的速度

易于失活(缺点)

在训练的时候,神经元很傲娇,梯度过大的时候神经元会失活。

例如,一个非常大的梯度流过一个 ReLU 神经元,更新过参数之后,这个神经元再也不会对任何数据有激活现象了,那么这个神经元的梯度就永远都会是 0.

如果 learning rate 很大,那么很有可能网络中的 40% 的神经元都”dead”了。

应用场景

应用于各种类型的神经网络,常见的有卷积神经网络的隐藏层等。

比如说,Udacity ML 毕业项目之一的猫狗大战,在隐藏层中大量使用 ReLU 作为激活函数。

Leaky ReLU

ReLU Speed Up Convergence

$$f(x) = max(0.01x, x)$$

ReLU 虽然性能优异,但是其会出现部分失活神经元的缺点还是让人头疼。于是人们在 ReLU 的基础上,发明了 Leaky ReLU 来解决这个问题。

其中式子中的 0.01 可以作为超参数进行调整,也就是说 Leaky ReLU 可以变成 $f(x) = max(\alpha x, x)$ 。

虽然解决了失活神经元的问题,但是实践中并没有发现 Leaky ReLU 总是比 ReLU 优异。

0x06 Reference

CS231n Convolutional Neural Networks for Visual Recognition

Activations - Keras Document

深度学习中的激活函数与梯度消失

神经网络之激活函数 - CSDN