视觉机器学习读书笔记--------BP学习

反向传播算法(Back-Propagtion Algorithm)即BP学习属于监督式学习算法,是非常重要的一种人工神经网络学习方法,常被用来训练前馈型多层感知器神经网络。

一、BP学习原理

1、前馈型神经网络

是指网络在处理信息时,信息只能由输入层进入网络,随后逐层向前进行传递,一直到输出层,网络中不存在环路;前馈神经网络是神经网络中的典型分层结构,根据前馈网络中神经元转移函数、网络层数、各层基本单元数目以及权重调整方式的不同,可以形成不同功能特点的神经网络。前馈型神经网络由输入层、中间层(隐层)和输出层组成,输入层无计算功能,只是为了表征输入矢量各元素数值;中间层和输出层的结点均在计算节点,对应于不同的计算函数,表示为δ(x),常用非线性函数,如sigmoid和tanh函数:

如图1所示,sigmoid和tanh函数对应图形均为S形状,主要区别在于函数取值范围不一样,sigmoid函数的取值范围为(0,1),而tanh函数的取值范围为(-1,1).

如图2所示,相邻层之间的节点为全连接,连接强度采用权重参数表示。网络输出层的具体形式由所要进行的任务决定,如在多分类问题中,输出层的每一维可以表示对应类别的预测置信度。在前馈网络中,网络层数、节点连接权重共同确定具体的前馈网络实例。在给定神经网络的结构之后,神经网络的训练目的是根据训练样本来学习网络节点之间的连接权重,使神经网络在未知的测试数据集合上进行相同任务时,能够取得更好的测试性能。

2、问题形式化

以常见的分类任务为例,对前馈网络的学习问题进行形式化。前馈网络输入和输出的维数、范围由实际应用问题的特点决定。如图2所示,其网络输入为x=[x1,x2,...,xni]T,解决问题的输入特征为ni维。一般地,需要将输入特征的取值范围归一化到特定区间,提高网络训练过程的收敛速度。假设样本的类别信息共有m种可能,网络输出y可以表示为n0维的类别向量,即y=[y1,y2,...,yno]T,其中向量的每一维表示样本属于相应类别的置信度。整个网络对应的函数可以表示为y=f(x),对应于网络的一次前向计算过程,即根据输入样本的特征向量预测出样本的类别信息。在确定前馈网络的具体结构后,即确定网络层数、各层节点数、层与层之间的连接关系以后,前馈网络的训练目标就是确定连接不同节点的权重,即网络中每个连接权重Wij(l)的值,这里Wij(l)表示连接地l层第j个神经元和第l+1层第i个神经元之间的权重。

为了确定网络的所有连接权重,最常见的方法就是通过被称为训练集的样本集合来学习出这些权重参数。一个包含N个样本的训练集可以表示为X={xn,tn}n=1N,这里xn表示该样本对应的ni维输入特征。tn为n0维的类别向量,其中取值为1的维度表示该样本对应的类别标签。定义损失函数l(θ;xn,tn)来计算一组特定的模型参数在一个样本上的损失值,这里θ是一个参数集合,表示所有的连接权重,即θ={Wijl,bjl},这里Wijl表示连接第l层第j个节点和第l+1层第i个节点之间的权重,bjl为第l+1层第i个节点的偏置项。

为了得到最优的连接权重数值,需要求解如下的最优化问题:

该优化问题的目标是求取特定的参数值,使得损失函数在训练集上的总损失和最小。由于损失函数的具体定义不同,上述最优化问题的求解过程也会相应不同。当损失函数的导数存在时,BP学习算法给出一种通用过程来求解上述最优化问题。

3、算法推导

BP学习算法基于最优化理论中非常成熟的梯度下降算法,首先从一个初始值出发,沿着目标函数值得负梯度方向寻找比当前函数值更小的目标函数值,接着以新目标函数值所对应的位置出发,重复上述过程,直到算法找到在一个局部区域中拥有最小目标函数值以及相对应的位置。BP学习算法是梯度下降算法在学习前馈神经网络参数中的一个具体应用特例。令        ,通过使用梯度下降法求取L(θ)的最小值,可以找到得到L(θ)的最小值时所对应的θ值,从而得到前馈网络所有的连接权重值。

使用BP学习算法训练前馈网络的基本思想是:首先通过一个前向过程计算训练样本中的输入特征经过前向网络后的实际输出值,然后将输出值与期望值进行比较,得到误差信号,再根据误差信号从后向前调节各神经网络层神经元之间的连接强度;然后再次重复进行前向过程计算,使误差减小,再将新的输出值与期望值进行比较,得到新的比先前小的误差信号;接着根据较小的误差信号,从后向前重新调节各神经网络层神经元之间的连接强度,这个前向过程和后向过程不断地多次进行直到误差满足要求为止。。

以损失函数选取最为常见的平方和误差为例,推导BP算法。

以平方和误差作为优化目标,则损失函数l(θ;xn,tn)可以表示为:l(θ;xn,tn)=1/2||tn-yn||2,这里yn表示前馈网络的输入为xn时所得到的输出函数值。相应地,整个训练集上的目标损失函数L(θ)可以表示为:

该目标函数相对于参数θ的梯度方向为:

假设参数θ的初始值为θ0,根据梯度下降法,可以按照如下方式不断更新参数θ:θk+1k+Δθkk-ηΔL(Δθk),  其中:Δθk=-ηΔL(Δθk)表示第k次迭代参数的更新量,η∈(0,1)为学习速率。

BP学习算法依据前馈网络的特点巧妙地使用链式求导法则给出一种从后向前分层更新参数的过程。首先通过前向过程计算得到训练样本在当前网络的输出,然后根据网络损失函数比较输出值与期望输出值,计算网络的错误;接着通过将网络错误从后向前逐层传播来更新网络参数,根据更新后的网络参数,不断重复上述过程,直到训练过程收敛。

 二、算法改进

经典的反向传播算法存在很多缺点,研究者已在学习速率、训练样本、损失函数、连接方式等方面提出了很多改进方法。

2.1、改进学习速率

改进学习速率是反向传播算法研究最多的内容,提高训练收敛速度,缩短训练时间。通过在训练过程中采样特定策略适当改变网络的学习速率η,使得训练过程可更快、更稳定地收敛。

2.1.1 增加动量项

前馈网络在训练过程中,损失函数经常会发生震荡,造成训练过程不收敛,为了减少该问题的影响,可以尝试用平滑损失函数的震荡曲线来加速训练过程,通过设计低通滤波器即可达到这种平滑效果。在更新网络参数时网络参数更新量的计算方式变为:Δθk=αΔθk-1-(1-α)ηΔL(Δθk),这里Δθk-1即为动量项,表示之前累积的参数调整惯性,α∈(0,1)为动量系数。

2.1.2 可变学习速率

前馈网络的训练误差曲面可能非常复杂,曲面形状随参数空间区域的不同而不同。为了加速前馈网络的训练过程,在学习过程中根据误差曲面的形状调整学习速度,提高收敛速度。

该方法的难点是何时改变学习速度和怎样改变学习速度,最简单的策略就是在训练开始时选用较大的学习速率,随着训练过程的进行不断地减小学习速率,该策略的基本假设就是训练开始阶段距离最优值比较远,训练后期距离最优值很接近。

2.1.3 加入陡度因子

前馈网络的训练误差曲面同样可能会存在平坦区,在平坦区计算得到的网络参数调整量非常小,网络训练过程很慢。观察神经元使用的非线性函数输入输出特性,不难发现,当输入值远离中心位置时,非线性函数进入饱和区域,即使输入值变化很大,输出值的变化都很小。这些饱和区域对应的输入值对应着前馈网络训练误差的平坦区,可以给这些非线性函数引入陡度因子,调整非线性函数的饱和区域,从而调整训练损失函数的形状,使参数调整脱离饱和区域。

对于sigmoid函数,该陡度因子(记为λ)可以设置如下:δs(x)=1/(1+exp(-x/λ))

2.1.4 使用数值优化技巧

为了提高神经网络训练的收敛速度和稳定性,同样可以使用数值优化算法替代BP算法中的梯度下降算法来训练前馈网络,如牛顿法、共轭梯度法、Levenberg-Marquardt算法等。

2.2 改进训练样本

训练样本对于机器学习算法非常重要,对于反向传播算法尤为重要。除了要确保收集的训练样本具有代表性和标定的准确性之外,由于前馈网络一般包含数目巨大的训练参数,所以为了训练得到一个可用的前馈网络,还需要与网络参数数目想匹配的训练样本。训练样本的数目至少需要10倍于网络参数的数目,并且训练样本的数目越多,越有益于训练处好的前馈网络模型。除了确保训练样本质量和数量,常见的改进训练样本的方法包括以下几种。

2.2.1 设计合适的训练样本

可使用原始收集数据,或提取合适特征作为新的训练样本。

2.2.2 适当规范化训练样本

确定样本维数、规范输入范围、设定合适的样本输出。

2.2.3 适当扰动训练样本

生成新的训练样本,增加样本数目,提高对噪声的鲁棒性。

2.2.4 改善使用顺序和数目

可采用批处理模式,一次使用所有训练样本;也可采用在线模式,每次只使用一个训练样本 ;或采用分块模式,每次使用部分样本,在块选取方式上引入适当随机性,可以提高模型训练的收敛速度和稳定性。

2.3 改进损失函数

模型训练误差的平方和是最简单的一种损失函数,存在很多潜在问题,如损失函数中没有对训练参数大小进行限制,当训练参数很大或者很小时,损失函数同样可以获得很小值,但是训练得到额模型就会非常不稳定。常见处理方法是在损失函数中加入对参数大小限制的正则化项,通过一个正则化因子控制正则化项在模型中的重要程度,加入正则化项后的训练误差平方和函数会训练得到更稳定的模型。

在实际应用中,可以根据具体问题设计合适的损失函数,只要损失函数相对于训练参数可导,就可以应用反向传播算法训练前馈网络。

除了改进前馈网络整体损失函数形式,还可以改进前馈网络神经元所选用的非线性函数形式,除了sigmoid和tanh函数,针对具体应用问题,尝试选用其他形式的非线性函数,能够获得更快的收敛速度和更好的模型性能。

2.4 改进连接方式

      全连接的前馈网络包含数量巨大的连接参数,训练这样的前馈网络不仅需要大量训练样本,而且非常难以训练,还要花费大量时间。在实际应用中需要改进前馈网络的连接方式,设计仅仅需要很少连接就能够描述输入输出之间复杂关系的网络模型,大大减少训练样本数量,降低模型复杂度以及训练难度。

2.4.1 局部连接策略

限制每一个神经元仅仅和自己临近的神经元相连,这种局部连接策略非常直观,因为只有临近节点才会对该节点产生较大影响。

2.4.2 权重共享策略

通过连接共享方法减少不同连接数目,限制不同的神经元选择相同的连接权重,权重共享策略可以进一步降低连接数目。

2.4.3 稀疏连接约束

限制每个神经元只和其他少数几个神经元相连接,稀疏连接约束在很多应用问题上展示非常优越的效果。

三、仿真实验

基于反向传播算法的学习前馈型神经网络的主要过程为:

算法1:反向传播算法

计算所有隐层和输出层的输入zl和输出al;

对于输出层需计算Δbnl-1和Δwnl-1

对于隐层l=nl-1,nl-2,...,2需计算Δb(l-1)和ΔW(l-1)

算法2:前馈型神经网络学习

训练样本和参数输入:训练样本集合{xn,tn}n=1N,前馈神经网络,学习速率η;

初始化:置所有层的连接权重和偏置为较小的随机值;

while   不收敛

从训练样本集合采样样本(xn,tn);

使用反向传播算法计算所有的

End While

输出网络参数{Wijl,bjl}.

为了使表述更简洁,算法中使用向量和矩阵表示计算过程,其中符号“·”表示向量间的点积运算符,即如果:a=b·c

那么:ai=bi·ci

非线性函数的定义被推广到向量输入,即:

在算法中,对于以sigmoid函数作为分段性函数,很容易推导得到:

为了将反向传播算法应用于学习前馈型神经网络,在实际训练过程中,需要在整个训练集上多次迭代应用反向传播算法,不断更新网络参数,直至收敛。

四、算法特点

BP学习算法是应用于前馈型神经网络训练的著名算法,在原理上依赖于最优化理论中成熟的梯度下降算法,BP学习算法结束多层网络没有训练算法的历史,具有较强的数学基础,在理论上能够模拟任何复杂函数,是非常重要的学习算法。

在具体实践中,反向传播算法存在很多缺点。

(1)局部最小值问题。由于前馈网络所表示的函数是非常复杂的非线性函数,反向传播算法作为优化这类复杂的非线性函数的算法,不可避免地存在局部最小值问题。由于优化过程所选取初始值的影响,优化过程很有可能收敛到一个局部最小值上。所要优化的非线性函数越复杂,存在的局部最小点就越多,优化算法就越有可能收敛到局部最小点。

(2)耗时大。反向传播算法用于训练包含多个隐层的前馈网络时,优化过程非常缓慢,需要迭代很多次。主要原因是由于反向传播算法的训练过程是将训练误差的梯度从后往前不断传播,当网络的隐层数目很多时,反向传播的梯度经过多层扩散就会变得很小,从而导致网络参数在一次迭代过程中的改变量很小,因而整个训练过程就需要花费大量时间。

(3)不稳定。反向传播算法训练前馈网络的过程存在不稳定性。由于训练时的初始值选取、学习步长设置、训练样本使用顺序和方式不同,使每次训练得到的网络性能差别可能很大,因而训练一个性能优异的神经网络往往需要尝试不同参数,为了使训练得到的网络能够再现,不仅需要记录各项参数,而且需要记录网络训练开始时随机生成的初始权重。另外,前馈网络的不稳定性还体现在实质上相同的网络,网络的连接权重可以有无数种不同的取值方式,如可以将前馈网络某层中的所有连接权重增大到两倍,把另一层中的所有连接权重减小两倍,得到的新网络相对于原网络实质上是同一个网络,但是它们各自的连接参数却相差很大。

(4)缺乏统一而完整的理论指导。反向传播算法适用的前馈网络在设计结构时也缺乏统一而完整的理论指导。包括神经元非线性函数的选择、隐层的层数、每层隐层的节点数目、权重的连接方式等,在实际应用中都需要进行不断尝试和选择,很多情况下都要经过大量实验进行经验性设定。

时间: 2024-08-05 07:07:53

视觉机器学习读书笔记--------BP学习的相关文章

视觉机器学习读书笔记--------SVM方法

SVM是一种有监督的统计学习方法,能够最小化经验误差和最大化几何边缘,被称为最大间隔分类器,可用于分类和回归分析. 一.基本原理 SVM是一个机器学习的过程,在高维空间中寻找一个分类超平面,将不同类别的数据样本点分开,使不同类别的点之间的间隔最大,该分类超平面即为最大间隔超平面,对应的分类器称为最大间隔分类器,对于二分类问题,下图可描述SVM的空间特征. 假设数据样本为x1,x2,...,xn,分类超平面可表示为:wTx-b=0.其中x为分类超平面上的点:w为垂直于分类超平面的向量:b为位移量,

机器学习读书笔记(开篇)

新近到手一本<机器学习实战>(Peter Harringtom),兴奋之余,本着好记性不如烂笔头的真理,打算将读书的过程记录下来,形成读书笔记,重点记录自己所理解的算法思想与应用示例.本人野生猿一枚,贻笑大方之处,敬请谅解. 机器学习可以揭示数据背后的真实含义,而数据以及基于数据做出的决策是非常重要的,机器学习的实现离不开数据挖掘算法,书中介绍了几个主要的算法,使用Python以及对应的科学计算包,如NumPy与SciPy等进行编程. 第一部分 分类 机器学习读书笔记01 机器学习基础 机器学

[读书笔记]C#学习笔记八:StringBuilder与String详解及参数传递问题剖析

前言 上次在公司开会时有同事分享windebug的知识, 拿的是string字符串Concat拼接 然后用while(true){}死循环的Demo来讲解.其中有提及string操作大量字符串效率低下的问题, 刚好自己之前也看过类似的问题, 于是便拿出来记录一下.本文内容: 参数传递问题剖析, string与stringbuilder详解 1,参数传递问题剖析 对于C#中的参数传递,根据参数的类型可以分为四类: 值类型参数的按值传递 引用类型参数的按值传递 值类型参数的按引用传递 引用类型参数的

机器学习读书笔记(一)

第1章 机器学习基础 1)学习分类 监督学习——是因为这类算法必须知道预测什么,即目标变量的分类信息. 无监督学习——数据没有类别信息,也不会给定目标值. 2)开发机器学习应用程序的步骤 收集数据——制作网络爬虫从网站上抽取数据.从RSS反馈或者API中得到信息.设备发送过来的实测数据(风速.血糖等).公开可用的数据源 准备输入数据——得到数据之后,还必须确保数据格式符合要求. 分析输入数据——人工分析以前得到的数据,确保数据集中没有垃圾数据. 训练算法——得到的式化数据输入到算法,从中抽取知识

[读书笔记]C#学习笔记一: .Net Framwork

前言: 一次偶然的机会  在园子里看到@Learning hard 出版的一本书: <<C#学习笔记>>, 然后买来 一直到现在读完, 感觉很不错, 适合入门, 书中内容是从C#1.0 到5.0. 很全面也很细致. 下面就来分享一下这本书中自己感觉需要记录的一些东西. 这里先贴上@Learning hard本人在博客园的主页: http://www.cnblogs.com/zhili/     以及本书中的一些知识点: http://www.cnblogs.com/zhili/ca

机器学习读书笔记01 机器学习基础

顾名思义,机器学习的目的就是让机器具有类似于人类的学习.认识.理解事物的能力.试想一下,如果计算机能够对大量的癌症治疗记录进行归纳和总结,并能够给医生提出适当的建议和意见,那对病人的康复来说,是多么的重要.除了医疗领域,金融股票.设备维护.自动驾驶.航空航天等领域也对机器学习表现出了越来越多的关注. 大量的经济活动都依赖于信息,我们不能在海量的数据中迷失,机器学习将有助于我们穿越数据雾霭,从中抽取出有用数据. 开发机器学习应用的步骤 收集数据 准备输入数据 分析输出数据 训练算法 测试算法 使用

[读书笔记]C#学习笔记二: 委托和事件的用法及不同.

前言:  C#委托是什么 c#中的委托可以理解为函数的一个包装, 它使得C#中的函数可以作为参数来被传递, 这在作用上相当于C++中的函数指针. C++用函数指针获取函数的入口地址, 然后通过这个指针来实现对函数的操作. 委托的定义和方法的定义类似, 只是在定义的前面多了一个delegate关键字. 正文: 委托可以被视为一个更高级的指针,它不仅仅能把地址传指向另一个函数,而且还能传递参数,返回值等多个信息. 系统还为委托对象自动生成了同步,异步的调用方式,开发人员使用BeginInvoke,E

机器学习读书笔记01

k-近邻算法 概述:k-近邻算法采用测量不同特征值之间的距离方法进行分类 优点:精度高.对于异常值不敏感,无数据输入假定 缺点:计算复杂度高,空间复杂度高,并且它没有办法各处基础数据的一些内部信息数据. 算法描述:存在一个准确的数据集合样本,称作训练样本集,样本集合中每个item都附带自己所属分类标签.当需要判断新数据的分类是,只需要计算特征数据和样本数据中最相似的分类标签,选择k个最相似的标签,k个标签中占比最多的即为目标标签. 具体分类算法 #-*- coding=utf-8 -*- fro

[读书笔记]C#学习笔记六: C#3.0Lambda表达式及Linq解析

前言 最早使用到Lambda表达式是因为一个需求:如果一个数组是:int[] s = new int[]{1,3,5,9,14,16,22};例如只想要这个数组中小于15的元素然后重新组装成一个数组或者直接让s返回一个新数组该怎么截取? 最开始的想法就是将这个s遍历一遍然后判断下再来重新组装成新的数组.好麻烦是不是? 于是便百度到了一个叫做Lambda的东西, 所以用了之后效果如下: 1 class Program 2 { 3 static void Main(string[] args) 4