机器学习基础笔记(5):神经网络

在机器学习中,神经网络(Neural Network)一般指“神经网络学习”这种经典的监督学习算法,是机器学习与神经网络两个学科的交叉。目前神经网络最广泛的一种定义为“神经网络是由具有适应性的简单单元组成的广泛并行互连的网络,它的组织能够模拟生物神经系统对真实世界物体所做出的交互反应”。

Hyplus目录

1 神经元模型

神经网络中最基本的单元是神经元(Neuron)。在生物神经网络的原始机制中,每个神经元通常由多个树突(Dendrite),一个轴突(Axon)和一个细胞体(Cell Body),树突短而多分支,轴突长而只有一个。在功能上,树突用于传入其它神经元传递的神经冲动,而轴突用于将神经冲动传出到其它神经元,当树突或细胞体传入的神经冲动使得神经元兴奋时,该神经元就会通过轴突向其它神经元传递兴奋。神经元的生物学结构如下图所示:

一直沿用至今的M-P神经元模型(McCulloch and Pitts,1943)正是对这一结构进行了抽象,其中树突对应于输入部分,每个神经元收到n个其他神经元传递过来的输入信号,这些信号通过带权重的连接(Connection)传递给细胞体,这些权重又称为连接权(Connection Weight)。细胞体分为两部分,前一部分计算总输入值(即输入信号的加权和,或者说累积电平),后一部分先计算总输入值与该神经元阈值(Threshold)的差值,然后通过激活函数(Activation Function)的处理,产生输出从轴突传送给其它神经元。M-P神经元模型如下图所示:

与线性分类十分相似,神经元模型最理想的激活函数也是阶跃函数,即将神经元输入值与阈值的差值映射为输出值1或0,若差值大于零输出1,对应兴奋;若差值小于零则输出0,对应抑制。但阶跃函数不连续、不光滑,故在M-P神经元模型中,亦采用Sigmoid函数来近似, Sigmoid函数将较大范围内变化的输入值挤压到(0,1)输出值范围内,故又称为挤压函数(Squashing Function)。(详见“线性模型”之“逻辑斯蒂回归”)

将多个神经元按一定的层次结构连接起来,就得到了神经网络。它是一种包含多个参数的模型,例如10个神经元两两连接,则有100个参数需要学习(假设每个神经元有9个连接权以及1个阈值),若将每个神经元都看作一个函数,则整个神经网络就是由这些函数相互嵌套而成。


2 感知机与多层网络

感知机(Perceptron)是由两层神经元组成的一个简单模型,输入层接收外界输入信号后传递给输出层,输出层是 M-P 神经元,亦称阈值逻辑单元(Threshold Logic Unit)。令y=f\left (\sum\limits_{i=1}^n w_ix_i-\theta\right ),其中f为阶跃函数。感知机能容易地实现逻辑x_1 \wedge x_2)、x_1 \vee x_2)、\neg x_1)运算。简单感知机的输入层与输出层示意图如下图所示:

给定训练数据集,权值w_i\ (i=1,2,\dots,n)以及阈值\theta可通过学习得到。阈值\theta可视为一个固定输入为x_{n+1}=-1哑结点(Dummy Node)所对应的连接权重w_{n+1},这样,权重和阈值的学习即可统一为权重的学习。感知机学习规则非常简单,设激活函数为阶跃函数,当训练样本(\mathbf{x},y)进入感知机学习后,会产生一个输出值\hat t,若该输出值与样本的真实标记不一致,则感知机会对权重进行调整,通式如下所示

\begin{aligned}
w_i\gets w_i+\Delta w_i
\end{aligned}

基于梯度下降法(在BP神经网络等模型里的使用详见后述子节)调整感知机权重的过程如下:首先计算预测值为

\begin{aligned}
\hat y &= f\left (\sum\limits_{i=1}^{n} w_ix_i-\theta \right )\\
&=f\left (\sum\limits_{i=1}^{n+1} w_ix_i \right ),\ x_{n+1}=-1
\end{aligned}

采用均方误差作为损失函数E=\dfrac12 (y-\hat y)^2,使用梯度下降法寻找最小的均方误差\min E,负的梯度方向为最速下降方向,则有

\begin{aligned}
\frac{\partial E}{\partial w_i} &=-(y-\hat y)\frac{\partial \hat y}{\partial w_i}\\
&=-(y-\hat y)\frac{\partial f\left (\sum\limits_{i=1}^{n+1} w_ix_i \right )}{\partial w_i}
\end{aligned}

因为f为阶跃函数,故有\dfrac{\partial f\left (\sum\limits_{i=1}^{n+1} w_ix_i \right )}{\partial w_i}=x_i。令下降步长为\eta \in (0,1),则

\begin{aligned}
\Delta w_i &=-\frac{\partial E}{\partial w_i}\eta\\
&=\eta (y-\hat y)x_i
\end{aligned}

通常称\eta学习率(Learning Rate)。可见感知机是通过逐个样本输入来更新权重:首先设定好初始权重(一般为随机),逐个地输入样本数据,若输出值与真实标记相同则继续输入下一个样本,若不一致则更新权重,然后再重新逐个检验,直到每个样本数据的输出值都与真实标记相同。容易看出,感知机模型总是能将训练数据的每一个样本都预测正确,和决策树模型总是能将所有训练数据都分开一样,感知机模型很容易产生过拟合问题。并且,由于感知机模型只有一层功能神经元(Functional Neuron),因此其功能十分有限,仅能线性可分(Linearly Separable)的问题,例如前述的“与”“或”“非”,感知机的学习过程一定会收敛(Converge);对于异或x_1 \oplus x_2)这种如此简单的非线性可分问题,感知机学习过程将会发生振荡(fluctuation),不能求得合适解。

因此要解决非线性可分问题,需要考虑使用多层功能神经元,即神经网络。只需两层感知机即可解决异或问题。输入层与输出层之间的一层神经元称为隐含层(Hidden Layer,隐藏层隐层),隐层和输出层的神经元都是具有激活函数的功能神经元。更常用的神经网络称为多层前馈神经网络(Feedforward Neural Network,FNN),该结构(如下图所示)满足以下几个特点:

  • 每层神经元与下一层神经元之间完全互连
  • 神经元之间不存在同层连接
  • 神经元之间不存在跨层连接

由上所述的特点可知:此处的“前馈”指的是网络拓扑结构中不存在环或回路,并非指该网络只能向前传播而不能向后传播(后述的BP神经网络正是基于FNN而增加了反馈调节机制)。神经网络的学习过程就是根据训练数据来调整神经元之间的连接权(Connection Weight)以及每个神经元的阈值(换句话说,神经网络所学到的东西都蕴含在网络的连接权与阈值中)。


3 BP神经网络

多层网络的学习能力比单层感知机强得多,继续使用前述简单感知机的权重调整规则显然不够用。BP神经网络(Error Backpropagation,误差逆传播反向传播算法)正是为学习多层前馈神经网络而设计,还可推广到其他类型神经网络中,是迄今为止最成功的的神经网络学习算法。

给定训练集D=\{(\mathbf{x}_1,\mathbf{y}_1),(\mathbf{x}_2,\mathbf{y}_2),\dots,(\mathbf{x}_m,\mathbf{y}_m)\},\mathbf{x}_i\in \mathbb{R}^d,\mathbf{y}_i\in \mathbb{R}^l,即输入示例由d个属性描述,输出l维实值向量。给出一个如下图所示的拥有d个输入神经元、l个输出神经元、q个隐层神经元的多层前馈网络结构,其中输出层第j个神经元的阈值为\theta_j,隐层第h个神经元的阈值为\gamma_h。输入层第i个神经元与隐层第h个神经元之间的连接权为v_{ih},隐层第h个神经元与输出层第j个神经元之间的连接权为w_{hj}。记隐层第h个神经元接收到的输入为\alpha_h=\sum\limits_{i=1}^d v_{ih}x_{i},输出层第j个神经元接收到的输入为\beta_j=\sum\limits_{h=1}^qw_{hj}b_h,其中b_h为隐层第h个神经元的输出。假设隐层和输出层神经元都使用Sigmoid函数。

对训练例(\mathbf{x}_k,\mathbf{y}_k),假定神经网络的输出为\hat \mathbf{y}_k=(\hat y_1^k,\hat y_2^k,\dots,\hat y_l^k),即

\begin{aligned}
\hat y_j^k=f(\beta_j-\theta_j)
\end{aligned}

则网络在(\mathbf{x}_k,\mathbf{y}_k)上的均方误差(为了后续求导的便利,暂将系数改为\dfrac12)为

\begin{aligned}
E_k=\frac12 \sum\limits_{j=1}^l (\hat y_j^k - y_j^k)^2
\end{aligned}

如上图所示的神经网络中有(d+l+1)q+l个参数需确定。BP是一个迭代学习算法,在迭代的每一轮中采用广义的感知机学习规则对参数进行更新估计,即与前述感知机对权重进行调整的通式类似,任意参数v的更新估计式为

\begin{aligned}
v \gets v + \Delta v
\end{aligned}

3.1 梯度下降策略

接下来以图中隐层到输出层的连接权w_{hj}为例推导其更新公式:BF算法基于梯度下降(Gradient Descent)策略,以目标的负梯度方向对参数进行调整,对前述的误差E_k,给定学习率\eta,有

\begin{aligned}
\Delta w_{hj} = -\eta \frac{\partial E_k}{\partial w_{hj}}
\end{aligned}

注意到w_{hj}先影响到第j个输出层神经元的输入值\beta_j,再影响到其输出值\hat y_j^k,然后影响到E_k,则根据链式法则有

\begin{aligned}
\frac{\partial E_k}{\partial w_{hj}}=\frac{\partial E_k}{\partial \hat y_j^k}\cdot \frac{\partial \hat y_j^k}{\partial \beta_j}\cdot \frac{\partial \beta_j}{\partial w_{hj}}
\end{aligned}

为了求得更新公式,根据E_k\hat y_j^k的定义式,又根据Sigmoid函数的性质f'(x)=f(x)(1-f(x)),定义新变量并进一步化简可得

\begin{aligned}
 g_j &= - \frac{\partial E_k}{\partial \hat y_j^k}\cdot \frac{\partial \hat y_j^k}{\partial \beta_j} \\
  &= -(\hat y_j^k - y_j^k)f'(\beta_j-\theta_j)\\
 &= \hat y_j^k(1-\hat y_j^k)(y_j^k-\hat y_j^k)
\end{aligned}

由定义易知\dfrac{\partial \beta_j}{\partial w_{hj}}=b_h,将其以及上述所有式子代入待求更新公式,即可得最终结果为

\begin{aligned}
\Delta w_{hj}=\eta g_j b_h
\end{aligned}

类似可得

\begin{aligned}
\Delta \theta_j &= -\eta g_j\\
\Delta v_{ih} &= \eta e_h x_i\\
\Delta \gamma_h &= -\eta e_h
\end{aligned}

其中

\begin{aligned}
 e_h &= - \frac{\partial E_k}{\partial b_h}\cdot \frac{\partial b_h}{\partial \alpha_h} \\
 &= -\sum\limits_{j=1}^l \frac{\partial E_k}{\partial \beta_j}\cdot \frac{\partial \beta_j}{\partial b_h} f'(\alpha_h-\gamma_h)\\
 &= \sum\limits_{j=1}^l w_{hj}g_j f'(\alpha_h-\gamma_h)\\
 &= b_h(1-b_h)\sum\limits_{j=1}^l w_{hj}g_j
\end{aligned}

学习率\eta \in (0,1)控制着沿反梯度方向下降的步长,若太大则下降太快容易震荡,若太小则收敛速度过慢,一般常设\eta=0.1或其他值,或将输出层与隐含层设置为不同的学习率。

3.2 BP算法基本流程

根据前述推导,标准BP算法的基本流程如下所示:

  • 输入:训练集D=\{ (\mathbf{x}_k,\mathbf{y}_k) \}_{k=1}^m;学习率\eta
  • 过程
    • (0,1)范围内随机初始化网络中所有连接权和阈值
    • repeat
      • for all (\mathbf{x}_k,\mathbf{y}_k)\in D do
        • 根据当前参数计算当前样本的输出\hat \mathbf{y}_k
        • 计算输出层神经元的梯度项g_j
        • 计算隐层神经元的梯度项e_h
        • 更新连接权w_{hj},v_{ih}与阈值\theta_j,\gamma_h
      • end for
    • until 达到停止条件
  • 输出:连接权与阈值确定的多层前馈神经网络

BP算法的更新规则是基于每个样本的预测值与真实类标的均方误差来进行权值调节,即BP算法每次更新只针对于单个样例。需要注意的是,BP算法的最终目标是要最小化整个训练集D上的累积误差,即

\begin{aligned}
E=\frac1m \sum\limits_{k=1}^m E_k
\end{aligned}

若直接基于累积误差最小化的更新规则,则可得累积BP算法(Accumulated Error Backpropagation),即在每次读取整个训练集D一遍后才对参数进行更新,因此参数更新频率相比标准BP算法低得多,但在很多任务中,尤其在训练集D非常大时,累积误差下降到一定程度之后,进一步下降会非常缓慢,此时往往标准BP算法会获得较好的解。

一般而言,只需包含一个足够多神经元的隐层,FFN就能以任意精度逼近任意复杂度的连续函数。但对于如何设置隐层神经元个数的问题,至今仍没有好的解决方案,实际应用中常使用试错法(Trial-by-error)进行调整。

BP神经网络强大的学习能力经常造成过拟合问题,有以下两种策略来缓解BP网络的过拟合:

  • 早停(Early Stopping):将数据分为训练集与验证集,训练集用于计算梯度、更新连接权和阈值,验证集用于评估性能;若在训练过程中,训练集误差降低但验证集误差升高,则在连续发生指定次数该情况后停止训练,并返回具有最小验证集误差的连接权和阈值。
  • 正则化(Regularization):在累积误差函数中增加一个用于描述网络复杂度的部分,例如连接权与阈值的平方和。如下所示,其中\lambda \in (0,1)用于对累积经验误差与网络复杂度这两项进行折中,常通过交叉验证法来估计
\begin{aligned}
E=\lambda \frac1m \sum\limits_{k=1}^m E_k + (1-\lambda) \sum\limits_i w_i^2
\end{aligned}

4 全局最小与局部最小

神经网络模型学习的过程实质上是一个寻找最优参数的过程,例如BP算法试图通过最速下降来寻找使得累积经验误差最小的权值与阈值。通常会提到以下两种“最优”:对最优连接权\mathbf{w}^*和最优阈值\theta^*,若存在\varepsilon\gt 0,使得

  • \forall (\mathbf{w};\theta)\in\{(\mathbf{w};\theta)\mid \left \| (\mathbf{w};\theta)-(\mathbf{w}^*;\theta) \right \| \le \varepsilon \},\ E(\mathbf{w};\theta)\ge E(\mathbf{w}^*;\theta^*),则(\mathbf{w}^*;\theta^*)局部极小解(Local Minimum)
  • 对参数空间中的任意(\mathbf{w};\theta)E(\mathbf{w};\theta)\ge E(\mathbf{w}^*;\theta^*),则(\mathbf{w}^*;\theta^*)全局最小解(Global Minimum)

要成为局部极小点,只需满足该点在参数空间中的梯度为零。如上图所示,局部极小可以有多个,而全局最小只有一个。全局最小一定是局部极小,但局部最小却不一定是全局最小。显然在很多机器学习算法中,都试图找到目标函数的全局最小。梯度下降法的主要思想就是沿着负梯度方向去搜索最优解:负梯度方向是函数值下降最快的方向,若迭代到某处的梯度为0,则表示达到一个局部最小,参数更新停止。

因此在现实任务中,通常使用以下策略尽可能地“跳出局部极小”,从而进一步接近全局最小:

  • 以多组不同参数值初始化多个神经网络,按标准方法训练,迭代停止后,取其中误差最小的解作为最终参数。
  • 使用模拟退火(Simulated Annealing)技术:在每一步都以一定的概率接受比当前解更差的结果,从而有助于“跳出”局部极小;在每步迭代过程中,接受“次优解”的概率要随着时间的推移而逐渐降低,从而保证算法稳定。
  • 使用随机梯度下降:在计算梯度时加入随机因素,使得即便陷入局部极小点,计算出的梯度仍可能不为零,从而有机会跳出局部极小继续搜索。

此外,遗传算法(Genetic Algorithm)也常用于训练神经网络以更好地逼近全局最小。需注意的是,上述用于跳出局部极小的技术大多属于启发式算法(Heuristic Algorithm),理论上尚缺乏保障。

其他常见神经网络:RBF(Radial Basis Function,径向基函数)网络、ART(Adaptive Resonance Theory,自适应谐振理论)网络、SOM(Self-Organizing Map,自组织映射)网络、级联相关(Cascade-Correlation)网络、Elman网络(最常用的递归神经网络之一)、Boltzmann机


5 深度学习

本节仅简要介绍基础概念,更多内容详见深度学习基础笔记(PyTorch)

理论上,参数越多,模型复杂度就越高,容量(Capability)就越大,从而能完成更复杂的学习任务。深度学习(Deep Learning,DL)模型指的就是极其复杂而强大的模型,最新的大型深度学习模型中有上百亿甚至更多个参数。

存在两种增大模型复杂度的方法:一是增加隐层的数目,二是增加隐层神经元的数目。前者更有效一些,因为其不仅增加了功能神经元的数量,还增加了激活函数嵌套的层数。但对于多隐层神经网络,经典算法(如标准BP算法)往往会在误差逆传播时发散(Diverge),无法收敛达到稳定状态。

因此,要想有效地训练多隐层神经网络,一般有以下两种方法:

  • 无监督逐层训练(Unsupervised Layer-wise Training):每次训练一层隐结点,将上一层隐结点的输出作为输入来训练,本层隐结点训练完成后,其输出再作为下一层的输入来训练,该过程称为预训练(Pre-training)。全部预训练完成后,再对整个网络进行微调(Fine-tuning)训练。典型例子为深度信念网络(Deep Belief Network,DBN),其将大量的参数进行分组,先找出每组较好的设置,再基于这些局部最优的结果来训练全局最优。
  • 权共享(Weight Sharing):令同一层神经元使用完全相同的连接权。典型例子为卷积神经网络(Convolutional Neural Network,CNN),如下图所示,这样做可以大大减少需要训练的参数数目。

深度学习可理解为一种特征学习(Feature Learning)或表示学习(Representation Learning),无论是DBN还是CNN,都通过多个隐层将与输出目标联系不太密切的初始输入转化成与输出目标更加密切的表示,使原本只通过单层映射难以完成的任务变为可能。即通过多层处理,逐渐将初始的“低层”特征表示转化为“高层”特征表示,从而使得最后可以用简单的模型来完成复杂的学习任务。

传统任务中,样本的特征需要人类专家来设计,该过程称为特征工程(Feature Engineering)。特征好坏对泛化性能有至关重要的影响。而深度学习为全自动数据分析带来了可能,可以自动产生更好的特征。

发表评论