博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
机器学习之神经网络
阅读量:2379 次
发布时间:2019-05-10

本文共 6363 字,大约阅读时间需要 21 分钟。

引言

在机器学习领域,主要存在着两大流派,一派是统计学习方法,一派就是神经网络。统计学习方法大多具有严谨的数学推理,模型都有很完备的数学解释,像是SVM,就是通过核把非线性问题映射到高维空间变为线性问题。而神经网络则不然,一直没有找到合理的数学解释,迄今为止都属于实验推动,虽然说是思想来源于人类的神经元的模拟,但是没有数学解释垫背,终究没有那么大的底气。

神经网络在1943年就已经被提出了,然而直到1969年提出了感知机的概念,才算是烧出了第一块砖。然而感知机毕竟只是一块砖,力量太过于薄弱了,处理线性可分的问题都好说,遇到非线性可分的问题就呵呵,包括最基本的异或问题都搞不定。后来人们尝试着把感知机组合起来生成神经网络,并且在1986年发明了反向传播算法,这样就形成了神经网络的早期的基石。随后人们不断尝试着把网络一层一层的加深,形成深度网络,然而由于梯度消失等问题,早期的深度网络存在极大的问题。屋漏偏逢连夜雨,Vapnik大神搞出了SVM,效果出奇的好,直接秒杀了早期的神经网络,致使神经网络的发展进入了低潮期。2006年Hinton横空出世, 提出了深度神经网络,利用受限玻尔兹曼机通过非监督学习的方式学习网络结构,然后利用反向传播算法学习网络内部的参数值,后面经过几位大神的推广和发展,导致如今深度学习遍地开花,硕果累累。

下面我们首先介绍感知机,然后通过感知机引出早期的神经网络,最后介绍反向传播算法是如何训练学习神经网络的。

感知机

感知机的详细定义可以参见,这里感知机其实就是一个给定输入空间,能够映射到输出空间{0,1}的函数。具体的形式如下图所示:

感知机

给定输入,可以产生一个指定的二进制输出,其数学公式如下:

output={
0,1,ifjifjwjxjthresholdswjxj>thresholds
o u t p u t = { 0 , i f ∑ j w j ∗ x j ≤ t h r e s h o l d s 1 , i f ∑ j w j ∗ x j > t h r e s h o l d s

用向量的方式表示的话,则可以简化为下面的格式:

output={
0,1,if wx+b0if wx+b>0
o u t p u t = { 0 , i f   w ∗ x + b ≤ 0 1 , i f   w ∗ x + b > 0

通过将过个感知机组合,可以形成感知机网络,如图所示,通过对上面的参数的学习,可以利用此感知机做决策。

这里写图片描述

S型神经元

上面介绍了感知机,但是如果输出结果只是0,1的话,那么这个好像不怎么好用啊,同时细微的参数变动有可能会引起结果的反转,这个模型就非常不理想了,因此引入S型神经元。

这里写图片描述

所谓的S型神经元就是输出函数为 σ σ 的感知机,函数如下所示:

σ=11+ez σ = 1 1 + e − z

其中

z=jwjxj+b z = ∑ j w j ∗ x j + b

下图是S型神经元的函数形状,我们可以看到,sigmoid函数具有很优良的性质,首先他的输出可以是0到1之间的连续值,其次当我们选定阈值时,S型神经元可以退化为感知机。这是一个优良的数学模型。

这里写图片描述

神经网络

通过将多个S型神经元组合到一起,就搭建成了一个初步的神经网络,如下所示,其中input layer为输入层,output layer为输出层,中间的所有的层为隐藏层,所有的单节点都是一个S型神经元。

这里写图片描述

当然我们也可以构建多个输出的网络,如下所示:

这里写图片描述

给定了神经网络的架构,那么我们就可以很自然的通过给定输入然后得到相应的输出结果,那么现在还剩下一个问题,我们怎样去通过调整神经网络的参数来得到我们想要的结果呢?大神们已经为我们准备好了工具,那就是梯度下降算法。

代价函数

在介绍梯度下降算法之前,首先需要考虑一个问题,有了神经网络模型,给定了输入,可以得到输出,那么我们怎样去衡量输出的好坏呢?因此需要有个度量标准,这个度量标准就是代价函数。所谓的代价函数,就是衡量输出结果好坏的一个度量,一般我们可以定义下面的一个代价函数

C(w,b)=12nx||y(x)a||2 C ( w , b ) = 1 2 n ∑ x | | y ( x ) − a | | 2

其中 w w 表示网络中权重的集合,

b
表示偏置, n n 是训练样本的个数,
a
表 示 输 入 为 x 时 的 输 出 , y(x)$ 表示神经网络的输出。

因此我们希望的训练得到的模型就是使代价函数最小的模型,也就是说通过修改 w w

b
的值,使得输出结果与实际结果的误差总和最小。

梯度下降算法

通过上面的分析,我们可以得出结论,神经网络的训练问题实际上本质就是一个最小化函数 C(w,b) C ( w , b ) 的问题。下面我们先通过一个二维的模型来讨论函数的最小化问题。

这里写图片描述

在上面的函数中,我们可以一眼看到函数的最小值在哪里。但是如果我们没有画出函数的几何形状呢,我们要如何找到函数的最小值点呢?

我们可以这样想,当我们沿着 v1 v 1 v2 v 2 的方向分别移动一个很小的量 Δv1 Δ v 1 Δv2 Δ v 2 ,那么根据微积分,我们可以得到下面的函数:

ΔCCv1Δv1+Cv2Δv2 Δ C ≈ ∂ C ∂ v 1 ∗ Δ v 1 + ∂ C ∂ v 2 ∗ Δ v 2

(上面的函数省略掉了二阶偏导,不过不重要。)

那么只要找到一个选择 v1 v 1 v2 v 2 的方法使 ΔC Δ C 为负,那么就可以保证函数一直是减小的,那么最终函数一定能到达到最小值(其实很多情况下是局部最小值)。

定义 C C 的偏导如下:

C=(Cv1,Cv2) ▽ C = ( ∂ C ∂ v 1 , ∂ C ∂ v 2 )

定义:

Δv=(Δv1,Δv2)T Δ v = ( Δ v 1 , Δ v 2 ) T

则:

ΔC=CΔv Δ C = ▽ C ∙ Δ v

如果令

Δv=ηC Δ v = − η ▽ C

那么

ΔC=η||C||2 Δ C = − η | | ▽ C | | 2
,只要保证
η η
为正数,那么
ΔC0 Δ C ≤ 0

因此可以使 v v 沿着 Δv Δ v 的方向移动,就可以得到最小值。即:

vv=vηv v → v ′ = v − η ▽ v

将上面的二维函数扩展到多为函数,则可以得到相同的结论,即

vv=vηv v → v ′ = v − η ▽ v

其中

Δv=ηC Δ v = − η ▽ C

C=(Cv1,......,Cvm) ▽ C = ( ∂ C ∂ v 1 , . . . . . . , ∂ C ∂ v m )

Δv=(Δv1,......,Δvm)T Δ v = ( Δ v 1 , . . . . . . , Δ v m ) T

将上面的函数拓展到我们的神经网络中,可以得到下面的公式

wkwk=wkηCwk w k → w k ′ = w k − η ∂ C ∂ w k

blbl=blηCbl b l → b l ′ = b l − η ∂ C ∂ b l

上面的两个公式就是梯度下降算法。只要我们沿着梯度下降的方向更新 w w

b
的值,那么就能够最小化代价函数。

通过我们不懈的努力,我们最终找到了更新神经网络的参数的方法,那么现在又有一个问题了,怎么计算 Cwk ∂ C ∂ w k Cbl ∂ C ∂ b l 呢? 这又是一个难办的问题了。但是大神们依旧给我们解决了,那就是反向传播算法。

反向传播算法

神经元的误差

在介绍反向传播算法之前,首先明确几个小概念,

第一个就是下图

这里写图片描述

理解了 wljk w j k l ,有助于我们下面的公式推导。

第二个就是神经元的激活值 alj a j l ,如下图所示

这里写图片描述

其中, lth l t h 层的第 jth j t h 个神经元的激活值 alj a j l 就和 (l1)th ( l − 1 ) t h 层的激活值通过下面的方程可以关联起来了

alj=σ(kwljkal1k+blj) a j l = σ ( ∑ k w j k l a k l − 1 + b j l )

第三,我们还要引入一个重要的概念:

即第 lth l t h 层的第 jth j t h 个神经元上的误差 δlj δ j l

定义 δlj=Czlj δ j l = ∂ C ∂ z j l

其中 zlj=kwljkal1k+blj z j l = ∑ k w j k l a k l − 1 + b j l

为何要引入这个误差呢?请看下图:

这里写图片描述

假设在 lth l t h 层的第 jth j t h 个神经元上有输入进来时,有个扰动,他会增加很小的变化 Δzlj Δ z j l 在神经元的带权输入上,使得神经元输出由 σ(zlj) σ ( z j l ) 变成 σ(zlj+Δzlj) σ ( z j l + Δ z j l ) ,

这个变化会向网络后面的层进行传播,最终导致整个代价产生 CzljΔzlj ∂ C ∂ z j l Δ z j l 的改变,因此 Czlj ∂ C ∂ z j l 是神经元误差的一种度量。

有了神经元的误差的概念,我们就可以逐步推导出反向传播算法的四个方程,进而能够逐步求得神经网络的权重和阈值的偏导,解决权重和阈值的更新问题。

反向传播的四个方程

我们首先列出反向传播的四个方程,然后在逐一证明这四个方程

这里写图片描述

首先对于(BP1),首先通过定义

δlj=Czlj δ j l = ∂ C ∂ z j l
由链式求导法则,可以得到:

δLj=kCaLkaLkzLj δ j L = ∑ k ∂ C ∂ a k L ∂ a k L ∂ z j L

求和是在输出层的所有 k k 个神经元上运行的, 但是我们可以注意到第 kth k t h 个神经元的激活值 aLk a k L 只跟 k=j k = j 时 第 j^{th} 个 神 经 元 的 输 入 z^{L}{j} , 有 关 , 所 以 k \neq j \frac{\partial a^{L}{k}}{\partial z^{L}_{j}} $ 为0,因此可以得到下面的方程:

δ
j
L
=
C
a
j
L
a
j
L
z
j
L

alj=σ(zLj) a j l = σ ( z j L )
,所以可以得到下面的方程:

δLj=CaLjσ(zLj) δ j L = ∂ C ∂ a j L σ ′ ( z j L )

输出成向量的格式,即为:

δL=aCσ(zL) δ L = ▽ a C ⊙ σ ′ ( z L )

对于(BP2),通过链式求导法则,可得到:

δlj=Czlj=kCzl+1kzl+1kzlj=kzl+1kzljδl+1k δ j l = ∂ C ∂ z j l = ∑ k ∂ C ∂ z k l + 1 ∂ z k l + 1 ∂ z j l = ∑ k ∂ z k l + 1 ∂ z j l δ k l + 1

zl+1k=jwl+1kjalj+bl+1k=jwl+1kjσ(zlj)+bl+1k z k l + 1 = ∑ j w k j l + 1 a j l + b k l + 1 = ∑ j w k j l + 1 σ ( z j l ) + b k l + 1

所以

zl+1kzlj=wl+1kjσ(zlj) ∂ z k l + 1 ∂ z j l = w k j l + 1 σ ′ ( z j l )

所以可以得到:

δlj=kwl+1kjδl+1kσ(zlj) δ j l = ∑ k w k j l + 1 δ k l + 1 σ ′ ( z j l )

转换为向量表示即为:

δl=(wl+1(δl+1)T)σ(zl) δ l = ( w l + 1 ( δ l + 1 ) T ) ⊙ σ ′ ( z l )

对于(BP3)

δlj=Czlj=Cbljbljzlj δ j l = ∂ C ∂ z j l = ∂ C ∂ b j l ∂ b j l ∂ z j l

zlj=jwlkjal1j+blk z j l = ∑ j w k j l a j l − 1 + b k l

所以

zljblj=1 ∂ z j l ∂ b j l = 1

因此方程成立

对于(BP4),通过链式求导法则

δlj=Czlj=Cwljkwljkzlj δ j l = ∂ C ∂ z j l = ∂ C ∂ w j k l ∂ w j k l ∂ z j l

zlj=jwlkjal1j+blk z j l = ∑ j w k j l a j l − 1 + b k l

所以

zljwljk=al1k ∂ z j l ∂ w j k l = a k l − 1

所以可以得到:

Cwljk=al1kδlj ∂ C ∂ w j k l = a k l − 1 δ j l

自此,四个方程证明完毕。

有个上面的四个方程作为支撑,我们就可以得出反向传播算法了,如下所示:

这里写图片描述

反向传播算法从最后一层开始计算误差,然后根据误差不断向前反馈优化每一层的权重,进而调整整个网络的权重。其实这和自动控制里面的反馈有着同样的哲学原理。

神经网络权重的更新算法

有了上面的梯度下降算法以及反向传播算法,我们就可以得到神经网络的权重的更新算法,具体算法如下所示:

这里写图片描述

算法中有一点需要注意的是:
这里的梯度下降,我们用的是随机梯度下降算法。思想就是随机选取小批量的训练样本来计算梯度,因为如果针对全部的训练数据进行梯度下降的话,会比较耗时,随机梯度下降能够加速学习,本质上讲,就是用部分随机选取的数据替代全量数据。

拓展

关于神经元的选择

本文中我们选用了sigmoid函数,也就是S型神经元,实际上还有很多种神经元可以选择,不同的神经元对于不同的问题可能会有更好的效果,因此具体问题需要具体分析。本质上讲sigmoid函数并不是很好,因为我们可以看到sigmoid函数的值域是[0,1],这也就意味着对于同一神经元的所有权重要么同时增加,要么同时减少,这样会造成一定的偏置。

关于代价函数

本文中我们用到的的二次代价函数,实际上也是有很多的代价函数可供选择的,一样的需要具体问题具体分析选用那种代价函数,二次代价函数是比较简单的一种,也是比较有效的一种。但是坦率的讲,选用不同的代价函数会对学习效率有较大的影响,这个后面我们会进行详细的分析。

关于过拟合问题

本文没有涉及过拟合问题,实际上这是机器学习面对的一个大问题,如果发生了过拟合,那么会导致网络的泛化能力变差,也就是在训练数据集上效果非常好,在测试数据集上表现糟糕。后面博客会详细分析这一问题。

深度神经网络

我们知道上古时代就已经发明了神经网络,在远古时代,反向传播算法也已经被发明出来了,那么为何直到近几年深度网络才火起来呢?这是一个问题。后续的博文会讲到为何中古时代大家都没有用到深度神经网络,他们遇到了什么样的问题,这些问题又是怎样解决的。

你可能感兴趣的文章
Android WebView挂马漏洞--各大厂商纷纷落马
查看>>
MongoDB 地理位置索引的实现原理
查看>>
MongoDB与MySQL的插入、查询性能测试
查看>>
深入理解OAuth2.0协议
查看>>
https原理:证书传递、验证和数据加密、解密过程解析
查看>>
MySQL在大型网站的应用架构演变
查看>>
sphinx教程1__mysql sphinx引擎插件式热安装
查看>>
sphinx教程2__安装、配置和使用
查看>>
ttserver 缓存使用和过期设置
查看>>
php pconnect 长连接原理
查看>>
php memcached使用中的坑
查看>>
php变量引用和计数_refcount_gc和is_ref_gc
查看>>
windows环境下php和Php扩展编译,扩展dll文件编译
查看>>
magento 验证码
查看>>
magento 获取自定义产品属性和属性值
查看>>
magento获取产品的好评率
查看>>
magento 获取产品的销售量
查看>>
magento缓存系列详解:clean cache
查看>>
magento缓存系列详解:如何缓存一个block
查看>>
magento性能优化系列二:db篇
查看>>