DL 入门:常用激活函数及其应用
在学习神经网络的时候见到了许多的激活函数,但是对每一个函数的理解不够深刻,在此总结一下激活函数的用途以及常见的激活函数。
0x01 激活函数
理论上,神经网络可以拟合任意非线性函数和线性函数,其可以拟合非线性函数的原因就在于这个激活函数是非线性的。
如果激活函数是线性的,那么 $W_2(W_1x+b_1)+b_2$ 也只是简单的线性叠加,最后得到的也只能是线性函数。
如果激活函数是非线性的,那么 $g(Wx+b)$ 得出来的可以是线性的,也可以是非线性的,最后两者类型的函数都可以拟合出来。
0x02 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 函数的输出值在 0 和 1 之间,因此该激活函数常用于二分类的输出层,其他地方很少用。
比如说,Kaggle 举办的 Dogs vs. Cats,判断是狗的概率,反之则是猫的概率。
0x03 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
$$f(x) = max(0, x)$$
- 定义域 (−∞, +∞)
- 值域 [0, +∞)
- 加速算法收敛(与 Sigmoid & Tanh 相比)
- 易于计算,只有比较和本身
- 神经元傲娇易于失活
ReLU 的原名叫做 Rectified Linear Unit,中文名字叫做 线性修正单元 。
加速算法收敛(优点)
由于它的非线性、梯度不饱和(梯度一直存在)特征,能够大幅提高收敛速度。
实验表明(Krizhevsky et al.),ReLU 比 tanh 的收敛速度快 6 倍。
易于计算(优点)
没有复杂和大开销的计算,只有比较是否大于 0 和输出自身这两种运算,大大加快了正向传播的速度
易于失活(缺点)
在训练的时候,神经元很傲娇,梯度过大的时候神经元会失活。
例如,一个非常大的梯度流过一个 ReLU 神经元,更新过参数之后,这个神经元再也不会对任何数据有激活现象了,那么这个神经元的梯度就永远都会是 0.
如果 learning rate 很大,那么很有可能网络中的 40% 的神经元都”dead”了。
应用场景
应用于各种类型的神经网络,常见的有卷积神经网络的隐藏层等。
比如说,Udacity ML 毕业项目之一的猫狗大战,在隐藏层中大量使用 ReLU 作为激活函数。
Leaky ReLU
$$f(x) = max(0.01x, x)$$
ReLU 虽然性能优异,但是其会出现部分失活神经元的缺点还是让人头疼。于是人们在 ReLU 的基础上,发明了 Leaky ReLU 来解决这个问题。
其中式子中的 0.01 可以作为超参数进行调整,也就是说 Leaky ReLU 可以变成 $f(x) = max(\alpha x, x)$ 。
虽然解决了失活神经元的问题,但是实践中并没有发现 Leaky ReLU 总是比 ReLU 优异。