引言
在机器学习领域,主要存在着两大流派,一派是统计学习方法,一派就是神经网络。统计学习方法大多具有严谨的数学推理,模型都有很完备的数学解释,像是SVM,就是通过核把非线性问题映射到高维空间变为线性问题。而神经网络则不然,一直没有找到合理的数学解释,迄今为止都属于实验推动,虽然说是思想来源于人类的神经元的模拟,但是没有数学解释垫背,终究没有那么大的底气。
神经网络在1943年就已经被提出了,然而直到1969年提出了感知机的概念,才算是烧出了第一块砖。然而感知机毕竟只是一块砖,力量太过于薄弱了,处理线性可分的问题都好说,遇到非线性可分的问题就呵呵,包括最基本的异或问题都搞不定。后来人们尝试着把感知机组合起来生成神经网络,并且在1986年发明了反向传播算法,这样就形成了神经网络的早期的基石。随后人们不断尝试着把网络一层一层的加深,形成深度网络,然而由于梯度消失等问题,早期的深度网络存在极大的问题。屋漏偏逢连夜雨,Vapnik大神搞出了SVM,效果出奇的好,直接秒杀了早期的神经网络,致使神经网络的发展进入了低潮期。2006年Hinton横空出世, 提出了深度神经网络,利用受限玻尔兹曼机通过非监督学习的方式学习网络结构,然后利用反向传播算法学习网络内部的参数值,后面经过几位大神的推广和发展,导致如今深度学习遍地开花,硕果累累。
下面我们首先介绍感知机,然后通过感知机引出早期的神经网络,最后介绍反向传播算法是如何训练学习神经网络的。
感知机
感知机的详细定义可以参见维基百科,这里感知机其实就是一个给定输入空间,能够映射到输出空间{0,1}的函数。具体的形式如下图所示:
给定输入,可以产生一个指定的二进制输出,其数学公式如下:
用向量的方式表示的话,则可以简化为下面的格式:
通过将过个感知机组合,可以形成感知机网络,如图所示,通过对上面的参数的学习,可以利用此感知机做决策。
S型神经元
上面介绍了感知机,但是如果输出结果只是0,1的话,那么这个好像不怎么好用啊,同时细微的参数变动有可能会引起结果的反转,这个模型就非常不理想了,因此引入S型神经元。
所谓的S型神经元就是输出函数为σ的感知机,函数如下所示:
其中
下图是S型神经元的函数形状,我们可以看到,sigmoid函数具有很优良的性质,首先他的输出可以是0到1之间的连续值,其次当我们选定阈值时,S型神经元可以退化为感知机。这是一个优良的数学模型。
神经网络
通过将多个S型神经元组合到一起,就搭建成了一个初步的神经网络,如下所示,其中input layer为输入层,output layer为输出层,中间的所有的层为隐藏层,所有的单节点都是一个S型神经元。
当然我们也可以构建多个输出的网络,如下所示:
给定了神经网络的架构,那么我们就可以很自然的通过给定输入然后得到相应的输出结果,那么现在还剩下一个问题,我们怎样去通过调整神经网络的参数来得到我们想要的结果呢?大神们已经为我们准备好了工具,那就是梯度下降算法。
代价函数
在介绍梯度下降算法之前,首先需要考虑一个问题,有了神经网络模型,给定了输入,可以得到输出,那么我们怎样去衡量输出的好坏呢?因此需要有个度量标准,这个度量标准就是代价函数。所谓的代价函数,就是衡量输出结果好坏的一个度量,一般我们可以定义下面的一个代价函数
其中𝑤表示网络中权重的集合, 𝑏表示偏置,𝑛是训练样本的个数,𝑎表示输入为x时的输出,y(x) 表示神经网络的输出。
因此我们希望的训练得到的模型就是使代价函数最小的模型,也就是说通过修改𝑤和𝑏的值,使得输出结果与实际结果的误差总和最小。
梯度下降算法
通过上面的分析,我们可以得出结论,神经网络的训练问题实际上本质就是一个最小化函数𝐶(𝑤,𝑏)的问题。下面我们先通过一个二维的模型来讨论函数的最小化问题。
在上面的函数中,我们可以一眼看到函数的最小值在哪里。但是如果我们没有画出函数的几何形状呢,我们要如何找到函数的最小值点呢?
我们可以这样想,当我们沿着𝑣1和 𝑣2的方向分别移动一个很小的量Δ𝑣1和Δ𝑣2,那么根据微积分,我们可以得到下面的函数:
(上面的函数省略掉了二阶偏导,不过不重要。)
那么只要找到一个选择v1和 v2的方法使ΔC为负,那么就可以保证函数一直是减小的,那么最终函数一定能到达到最小值(其实很多情况下是局部最小值)。
定义C的偏导如下:
定义:
则:
如果令
那么
,只要保证 η为正数,那么 ΔC≤0
因此可以使v沿着Δv的方向移动,就可以得到最小值。即:
将上面的二维函数扩展到多为函数,则可以得到相同的结论,即
其中
将上面的函数拓展到我们的神经网络中,可以得到下面的公式
上面的两个公式就是梯度下降算法。只要我们沿着梯度下降的方向更新𝑤和𝑏的值,那么就能够最小化代价函数。
通过我们不懈的努力,我们最终找到了更新神经网络的参数的方法,那么现在又有一个问题了,怎么计算和呢? 这又是一个难办的问题了。但是大神们依旧给我们解决了,那就是反向传播算法。
反向传播算法
神经元的误差
在介绍反向传播算法之前,首先明确几个小概念,
第一个就是下图
理解了,有助于我们下面的公式推导。
第二个就是神经元的激活值,如下图所示
第三,我们还要引入一个重要的概念:
即第层的第个神经元上的误差
定义
其中
为何要引入这个误差呢?请看下图:
假设在层的第个神经元上有输入进来时,有个扰动,他会增加很小的变化在神经元的带权输入上,使得神经元输出由变成,这个变化会向网络后面的层进行传播,最终导致整个代价产生的改变,因此是神经元误差的一种度量。
有了神经元的误差的概念,我们就可以逐步推导出反向传播算法的四个方程,进而能够逐步求得神经网络的权重和阈值的偏导,解决权重和阈值的更新问题。
反向传播的四个方程
我们首先列出反向传播的四个方程,然后在逐一证明这四个方程
首先对于(BP1),首先通过定义
由链式求导法则,可以得到:
求和是在输出层的所有𝑘个神经元上运行的, 但是我们可以注意到第个神经元的激活值,只跟𝑘=𝑗时第个神经元的输入有关,所以k≠j时 \frac{\partial a^{L}{k}}{\partial z^{L}_{j}}为0,因此可以得到下面的方程:
而
,所以可以得到下面的方程:
输出成向量的格式,即为:
对于(BP2),通过链式求导法则,可得到:
而
所以
所以可以得到:
转换为向量表示即为:
对于(BP3)
而
所以
因此方程成立
对于(BP4),通过链式求导法则
而
所以
所以可以得到:
自此,四个方程证明完毕。
有个上面的四个方程作为支撑,我们就可以得出反向传播算法了,如下所示:
反向传播算法从最后一层开始计算误差,然后根据误差不断向前反馈优化每一层的权重,进而调整整个网络的权重。其实这和自动控制里面的反馈有着同样的哲学原理。
神经网络权重的更新算法
有了上面的梯度下降算法以及反向传播算法,我们就可以得到神经网络的权重的更新算法,具体算法如下所示:
算法中有一点需要注意的是:
这里的梯度下降,我们用的是随机梯度下降算法。思想就是随机选取小批量的训练样本来计算梯度,因为如果针对全部的训练数据进行梯度下降的话,会比较耗时,随机梯度下降能够加速学习,本质上讲,就是用部分随机选取的数据替代全量数据。
拓展
关于神经元的选择
本文中我们选用了sigmoid函数,也就是S型神经元,实际上还有很多种神经元可以选择,不同的神经元对于不同的问题可能会有更好的效果,因此具体问题需要具体分析。本质上讲sigmoid函数并不是很好,因为我们可以看到sigmoid函数的值域是[0,1],这也就意味着对于同一神经元的所有权重要么同时增加,要么同时减少,这样会造成一定的偏置。
关于代价函数
本文中我们用到的的二次代价函数,实际上也是有很多的代价函数可供选择的,一样的需要具体问题具体分析选用那种代价函数,二次代价函数是比较简单的一种,也是比较有效的一种。但是坦率的讲,选用不同的代价函数会对学习效率有较大的影响,这个后面我们会进行详细的分析。
关于过拟合问题
本文没有涉及过拟合问题,实际上这是机器学习面对的一个大问题,如果发生了过拟合,那么会导致网络的泛化能力变差,也就是在训练数据集上效果非常好,在测试数据集上表现糟糕。后面博客会详细分析这一问题。
深度神经网络
我们知道上古时代就已经发明了神经网络,在远古时代,反向传播算法也已经被发明出来了,那么为何直到近几年深度网络才火起来呢?这是一个问题。后续的博文会讲到为何中古时代大家都没有用到深度神经网络,他们遇到了什么样的问题,这些问题又是怎样解决的。
————————————————
本文转自CSDN平台博主:changyuanchn
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/changyuanchn/article/details/80330927
|