神经网络:激活函数#
在上一节的练习里我们已经试过了:光是往网络里堆隐藏层,并不足以表达出非线性。线性运算作用在线性运算上,结果仍然是线性的。
关于这一点的实际证明过程,可以可以参见内容「深度学习线性回归入门:多项式回归与神经网络建模基础」 第3.1.5节内容。
那么问题来了——要怎么配置一个神经网络,它才能学会取值之间的非线性关系?办法是往模型里插入一些非线性的数学运算。
其实这套路子你有点眼熟。课程前面我们就在线性模型的输出上动过非线性的手脚:在逻辑回归那一讲里,我们把线性回归模型的输出送进一个 sigmoid 函数,让它输出 0 到 1 之间的连续值,也就是一个概率。
同样的原理照样能搬到神经网络上。我们回到之前练习 2里的那个模型,只不过这一次,在输出每个节点的取值之前,我们先给它套一层 sigmoid 函数:
试着点一下播放按钮右边的 >| 按钮,一步步走过每个节点的计算过程,再对照图形下方的 Calculations(计算过程)面板,看看每个节点的取值究竟是怎么算出来的。你会发现两件事:每个节点的输出,如今都是上一层节点的线性组合再做一次 sigmoid 变换的结果;而且所有输出值都被压在 0 到 1 之间。
在这里,sigmoid 扮演的就是神经网络的激活函数(activation function)——在神经元的输出值被送进下一层的计算之前,先对它做一次非线性的变换。
加上了激活函数,再叠层才真正有意义。非线性一层压着一层,我们才有可能建模输入与预测输出之间那些非常复杂的关系。简单说,每一层实际上都在原始输入之上,学到了一个更复杂、层次更高的函数。想对这套机制再建立一些直觉,可以看看 Chris Olah 的这篇博客。
常见的激活函数#
常用作激活函数的数学函数有三个:sigmoid、tanh 和 ReLU。
前面已经讲过的 sigmoid 函数,对输入 $x$ 做如下变换,输出落在 0 到 1 之间:
$$ F(x)=\frac{1} {1+e^{-x}} $$提示: sigmoid 这个词常被更宽泛地用来指代任何 S 形的曲线。而上面这个具体的函数 $F(x)=\frac{1} {1+e^{-x}}$,更准确的技术名称其实是 logistic 函数。
这条曲线长这样:

tanh(“双曲正切"的缩写)把输入 $x$ 变换成 -1 到 1 之间的输出值:
$$ F(x)=tanh(x) $$这条曲线长这样:

提示: sigmoid 函数的取值范围是 0 到 1,tanh 函数的取值范围是 -1 到 1。
修正线性单元(rectified linear unit,简称 ReLU)激活函数用下面这套算法来变换输出:
如果输入值 $x$ 小于 0,返回 0。
如果输入值 $x$ 大于或等于 0,返回输入值本身。
用 max() 函数表示,ReLU 在数学上就是:
这条曲线长这样:

作为激活函数,ReLU 往往比 sigmoid、tanh 这类平滑函数表现得好上一点。原因在于,它在神经网络训练过程中不那么容易被梯度消失问题(vanishing gradient problem)找上门。而且,ReLU 的计算量也比这两个函数小得多。
其他激活函数#
实践中,任何数学函数都可以拿来当激活函数。假设 $\sigma$ 表示我们的激活函数,那么网络中一个节点的取值由下面这个式子给出:
$$ \sigma(\boldsymbol w \cdot \boldsymbol x+b) $$Keras 开箱即用地支持很多种激活函数。不过话说回来,我们还是建议从 ReLU 开始。
概括#
现在,我们的模型具备了人们通常所说的神经网络的所有标准组成部分:
一组类似于神经元的节点,按层排列。
一组学习得到的权重和偏置,表示神经网络中每一层与其下一层之间的连接。下一层可以是另一个神经网络层,也可以是其他类型的层。
一个激活函数,用于变换层中每个节点的输出。不同的层可以具有不同的激活函数。
需要注意的是: 神经网络不一定总是比特征交叉更好,但神经网络确实提供了一种灵活的替代方案,在很多情况下都能很好地发挥作用。
MLWM: 关于「神经元、全连接层、隐藏层」这几个概念的更完整梳理,可以参见内容「深度学习线性回归入门:多项式回归与神经网络建模基础」;激活函数如何把线性网络掰成非线性模型,参见「激活函数原理:Sigmoid、Tanh、ReLU 与 LeakyReLU」;梯度消失问题怎么来、怎么解,可以看「反向传播与梯度下降:梯度消失与爆炸的解决方法」。
关键术语:
- 激活函数(Activation function)
- Sigmoid 函数(Sigmoid function)
- 梯度消失问题(Vanishing gradient problem)