神经网络

写在前面:
这篇文章,是我在看Jiawei的书时候写的。由于该书在BP的推导公式上面省略了特别特别多。因此,本篇博客的公式推导不太适合初学者理解。
后来,看了周志华老师的西瓜书后,发现上面关于BP的推导非常详细,本想重新修改本篇文章,后来发现已经有一位兄弟把周老师的推导过程发在了他的博客上,因此我也就不做无用功了,就在参考文章里面给出了链接。各位读者不妨反复参看这一推导过程,相信对于BP会有新的理解。
神经网络要详解的话,是一个很大的内容。要往细了说,激活函数,梯度下降,损失函数,BP推导都可以单独成文。因此本文不可能讲得不可能面面俱到,所以在涉及有些内容时,直接就引用了其他大牛写的文章。诸位读者参考他们的就行了。
本章文章旨在跑通神经网络的整个流程。

首先要明白这样一点:后向传播算法在多层前馈神经网络上学习
对于新手来说,可能会以为后向传播算法就是神经网络。但实际上不是这样的,学习这一章节,特别重要的是要“知其然”和“知其所以然”。
具体来说的话,就是要理解神经网络的思想和梯度下降法。理解了这两个之后,你就自然会明白为什么会选择BP算法来训练神经网络了(BP是计算梯度的利器!!!)。
推荐反复参看这两篇文章,第一篇文章对理解BP算法为什么是计算梯度的利器很有帮助;第二篇文章对于把握算法的整体结构,细节和思想都有很大的帮助!!!
如何直观解释BP算法-胡逸夫的回答
如何简单形象有趣的解释神经网络-YJango的回答
前馈神经网络的结构
神经网络之所以叫神经网络,是因为它模拟了人的大脑的神经单元的工作方式。(之前看到不少文章说神经网络算法和人的神经没有任何关系,这完全是瞎说。实际上该算法构造可以被看作受仿生学(?)启发的)
神经网络有很多神经网络层构成,而每一层又由许多单元组成。第一层叫输入层,中间的各个层叫隐藏层,最后一层叫输出层。在这里要额外介绍的一点是:除了输出层,每一层都可以有一个偏置结点
那么什么是偏置结点呢?实际上偏置结点是为了描述训练数据中没有的特征。偏置结点对于下一层的每一个结点的权重的不同而产生不同的偏置,于是可以认为偏置是每一个结点(除输入层外)的属性。
更直白来说,偏置充当阀值,用来描述单元活性。
而一般的书上都把这个偏置结点省略掉了的。
这里写图片描述
虽然图中隐藏层只画了一层,但其层数并没有限制。传统的神经网络通常只设置一层,而最近的深度学习则通常达到了上百层。
这里写图片描述

在描述神经网络的BP训练算法之前,我们来看神经网络各层都有哪些属性 。
1.除输入层以外,每一个神经单元都有一个输出值,定义为Oj;
2.相邻层之间的结点的链接有一个权重W,其值在【-1,+1】之间;
3.除输入层之外,每一层的各个节点都有一个输入值。其值为上一层所有单元的输出加权和加上偏置,定义为净输入;
4.除输入层外,每一层都有一个偏置值,其值在【0,1】之间或者可把它当作一个固定的-1值;
5.除输入层外,每个结点的输出值等于该结点的净输入值作非线性变换,该变换所用函数被称为激活函数;
6.我们通常认为输入层没有输入值。其输出值即为训练数据的属性,比如一条记录X={(1,2,3),类别1}。那么输入层的三个结点的输出值分别为1,2,3。因此输入层的结点个数一般等于训练数据的属性个数。

因此,训练一个BP神经网络,实际上就是调整网络的权重和偏置这两个参数
在算法的发展中,早期的BP神经网络的训练过程还不是很清楚,因为它把计算梯度和更新打在了一起。因此早期的训练过程就分为两部分:
1.前向反馈,逐层波浪式的传递输出值;
2.逆向反馈,反向逐层调整权重和偏置。
首先来看前向反馈。

而随着神经网络的继续发展,现在把原来打包式的做法拆开成了
1)求梯度;
2)梯度下降。
所以现在我们再提到backprop,一般只是指第一步:求梯度。这就是为什么好多文章直接说BP就是个链式法则,因为确实就是链式法则。但是这种说法其实是有欠缺的,因为我们想要的是搞清这个流程。

前向反馈
在训练网络前,我们需要随机初始化权重和偏置。对每一个权重取【-1,1】的一个随机实数,每一个偏置取【0,1】的一个随机实数,之前就进行前向传输。
神经网络的训练是由多趟迭代完成的,每一趟迭代都使用训练集的所有记录,而每一次训练网络只使用一条记录。
首先设置输入层的输出值,假设属性的个数为100,那我们就设置输入层的神经单元个数为100,输入层的结点Ni的初始值为记录第i维上的属性值xi。对输入层的操作就这么简单,之后的每层就要复杂一些了,除输入层外,其他各层的输入值是上一层输入值按权重累加的结果值加上偏置,每个结点的输出值等该结点的输入值作非线性变换。
这里在作非线性变换时会涉及到激活函数。关于为什么要引入激活函数,会在之后详细说明,这里暂且先记下。
这里写图片描述

前向传输的输出层的计算过程公式如下:
这里写图片描述
书P261有公式的详细解释。
OK,对隐藏层和输出层的每一个结点都按照如上图的方式计算输出值,就完成前向传播的过程。

逆向反馈
逆向反馈从最后一层即输出层开始,我们训练神经网络作分类的目的往往是希望最后一层的输出能够描述数据记录的类别,比如对于一个二分类的问题,我们常常用两个神经单元作为输出层,如果输出层的第一个神经单元的输出值比第二个神经单元大,我们认为这个数据记录属于第一类,否则属于第二类。
第一次前向反馈时,整个网络的权重和偏置都是我们随机取,因此网络的输出肯定还不能描述记录的类别,因此需要调整网络的参数,即权重值和偏置值,而调整的依据就是网络的输出层的输出值与类别之间的差异,通过调整参数来缩小这个差异,这就是神经网络的优化目标。
上面说到,调整的依据是网络输出层的输出值与类别之间的差异。这个差异是通过损失函数来计算的,而最终我们调整权重和偏置的目的就是为了最小化损失函数。
由于网络的输出层有多个输出结点,我们需要将输出层每个输出结点的差值平方求和,于是得到每一个训练样例的损失函数为:
这里写图片描述
至于为什么要引入损失函数,这个也放在后面说。
OK,书接上文。根据实例的输入,从前向后依次计算,得到输出层每个单元的输出,然后计算误差,再然后将这个误差逆向传播至每一层每一个神经元(就是计算每一层的每一个单元的梯度项(误差),这一步实际上是最体现BP算法的优越性的。)。最后从前往后依次进行更新权重和阀值。
对于输出层的每个单元,它的误差为:
这里写图片描述
对于隐藏层的每个单元,它的误差为:
这里写图片描述
这里可以看到,误差是按权重累加的。熟悉了BP过程的同学再看这个公式应该就会很明了了。
 计算完各单元的误差之后,就可以利用误差对权重和偏置进行更新,首先看权重的更新:
 这里写图片描述
这里会涉及到一个“入”参数。这个参数被称为“学习率”,为什么要引入这个参数,也放在后面讲。
更新完权重后,还需要更新偏置
这里写图片描述
OK,至此,我们完成了一次神经网络的训练过程,通过不断的使用所有数据记录进行训练,从而得到一个分类模型。不断地迭代,不可能无休止的下去,总归有个终止条件。

训练终止条件
1.前一周期所有的权重的变化值都小于某个指定的阀值,则证明训练得差不多了,可以停止了;
2.前一周期无分类的元组百分比小于某个阀值;
3.超过指定的迭代次数。

为什要引入激活函数?
我们知道神经网络可以用于分类(预测)和数值预测(预测连续值输出)。
假如说,我们不运用激活函数的话,则输出就仅仅是一个简单的线性函数,整个神经网络就仅仅是一个线性回归模型 ,并且这个线性回归模型的执行效果还很差。
我们希望我们的神经网络不仅仅可以学习和计算线性函数而且还可以承担比这复杂得多的任务,不仅能处理简单的数据类型还能处理诸如图像,音视频之类的复杂数据类型。它可以计算和学习任何函数,几乎我们可以想到的任何过程都可以表示为神经网络的函数计算。
因此现在我们需要的是一个可以学习和表示几乎任何东西的神经网络模型,以及可以将输入映射到输出的任意复杂函数。
而这而这一切都归结于这一点,我们需要应用激活函数f(x),以便使网络更加强大,增加它的能力,使它可以学习复杂的事物,复杂的表单数据,以及表示输入输出之间非线性的复杂的任意函数映射。
直白理解就是,我们需要激活函数(非线性函数)来增强我们的神经网络的能力!
神经网络强大到可以学习世界上任何的事物,所以必须引入非线性。
事实上,我们的世界也就是非线性的。
其他更细致的请参考下面的文章:
什么是激活函数?它有什么作用?
神经网络之激活函数

损失函数
损失函数可以作为衡量参数修正优劣的指标。
损失函数越小,其整个模型的性能就越好。
在整个过程中,我们是通过比较预测值和目标值来不断修正权重的。
那么如何进行比较呢?当然不是简单的相加相减。于是,这里就引出了损失函数
在神经网络中,因为后向传播是使用梯度下降法来搜索权重的集合的,因此这里的损失函数通常采用的就是平方损失函数。
实际上,损失函数并不止这一种。
这里要知道的时,如果损失函数是凸函数,梯度下降法得到的解就一定是全局最优解。(可参考这篇文章(梯度下降))
参考文章机器学习中的损失函数

学习率
在多层的神经网络中,误差曲面可能有多个局部极小值,这意味着使用梯度下降算法找到的可能是局部极小值(权重看上去收敛,但不是最优解),而不是全局最小值,为此引入了这一参数。
此外,从全局来思考的话,BP采用梯度下降法来训练:通过使loss值向当前点对应梯度的反方向不断移动来降低loss,而一次移动多少就是由学习速率来决定的(爬山法)。
这里写图片描述

总结
纵观来看,BP算法的推导过程主要是利用梯度下降算法最小化损失函数的过程。
其中我认为很重要很重要的是关于非线性(激活)函数的变换。或者更具体的来说是在前向传播中,从输入到净输入再到输出这一步。得益于这一系列的变换操作,就可以把复杂的非线性问题用简单的线性方法去解决。事实上,若是你了解了SVM的思想你会发现,在空间变换这一块,这两个算法的处理非常相似。都是通过非线性映射把原始数据变换到高维空间。
然后就是要深刻的理解BP算法是如何极大的方便我们计算梯度的,最好自己计算一下,理解它的这种(逐层(每一个层逐个(每一个逐线)))的计算顺序。
要理解目前来说,计算梯度和更新是分开的。
要知道如何选择合适的激活函数和损失函数(当然这一点并不好做,如何设置参数,调整参数一直是现阶段使用的ANN的一个大问题。因为它和训练数据的关系相当紧密。比如就损失函数来说,离散型数据更适合交叉熵损失,离散型更适合均方误差。)。
要知道梯度下降分随机梯度下降,标准梯度下降,批量梯度下降以及对应的BP算法(标准?累积?)
要知道之所以叫反向传播算法,是因为前向传播计算会有大量的冗余
要知道损失函数本质上就是一个单纯的对权值wij有关的函数

推荐反复参看这两篇文章,第一篇文章对理解BP算法为什么是计算梯度的利器很有帮助;第二篇文章对于把握算法的整体结构,细节和思想都有很大的帮助!!!
如何直观解释BP算法-胡逸夫的回答
如何简单形象有趣的解释神经网络-YJango的回答
本文旨在理清思路,因此省略了很多推导细节。

若是有同学了解神经网络的发展历史,就会知道感知机模型是来源于线性模型的(如PLA)。线性模型本质上也是在寻找性能最好的w,也是要最小化损失。其实这也是早期的神经网络的缺陷。为什么?因为它是来自于简单的线性模型啊,所以注定以为这功能不会强大。因此,神经网络才一度陷入困局。之后才在神经网络中引入了非线性因素(激活函数),神经网络才又得以继续发展。所以线性模型的真的是十分基础又十分重要的

本节参考借鉴引用了:
数据挖掘系列(9)——BP神经网络算法与实践
多层神经网络BP算法 原理及推导
深入浅出|深度学习算法之BP神经网络 详细公式推导
(这个文章参考了西瓜书上的这一章节的内容,不过在关于参数更新方式上,这个博主还是理解成了更新和计算梯度同时进行。实际上,在前面我也说到,目前计算和更新是分开的。)
磅!神经网络浅讲:从神经元到深度学习
BP算法双向传,链式求导最缠绵(深度学习入门系列之八)
(这篇文章给出了详细的公式推导和计算示例。完全符合西瓜书上的结论!可反复参看)
神经网络的动态模拟:
Tensorflow

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值