机器学习入门-浅谈神经网路_第1页
机器学习入门-浅谈神经网路_第2页
机器学习入门-浅谈神经网路_第3页
机器学习入门-浅谈神经网路_第4页
机器学习入门-浅谈神经网路_第5页
已阅读5页,还剩31页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

机器学习入门——浅谈神经网路〔摘自百度贴吧〕先从回归(Regression)问题说起。我在本吧已经看到不少人提到如果想实现强AI,就必须让机器学会观察并总结规律的言论。具体地说,要让机器观察什么是圆的,什么是方的,区分各种颜色和形状,然后根据这些特征对某种事物进行分类或预测。其实这就是回归问题。如何解决回归问题?我们用眼睛看到某样东西,可以一下子看出它的一些根本特征。可是计算机呢?它看到的只是一堆数字而已,因此要让机器从事物的特征中找到规律,其实是一个如何在数字中找规律的问题。例:假设有一串数字,前六个是1、3、5、7,9,11,请问第七个是几?你一眼能看出来,是13。对,这串数字之间有明显的数学规律,都是奇数,而且是按顺序排列的。那么这个呢?前六个是0.14、0.57、1.29、2.29、3.57、5.14,请问第七个是几?这个就不那么容易看出来了吧!我们把这几个数字在坐标轴上标识一下,可以看到如下列图形:用曲线连接这几个点,延着曲线的走势,可以推算出第七个数字——7。由此可见,回归问题其实是个曲线拟合(CurveFitting)问题。那么究竟该如何拟合?机器不可能像你一样,凭感觉随手画一下就拟合了,它必须要通过某种算法才行。假设有一堆按一定规律分布的样本点,下面我以拟合直线为例,说说这种算法的原理。其实很简单,先随意画一条直线,然后不断旋转它。每转一下,就分别计算一下每个样本点和直线上对应点的距离(误差),求出所有点的误差之和。这样不断旋转,当误差之和到达最小时,停止旋转。说得再复杂点,在旋转的过程中,还要不断平移这条直线,这样不断调整,直到误差最小时为止。这种方法就是著名的梯度下降法(GradientDescent)。为什么是梯度下降呢?在旋转的过程中,当误差越来越小时,旋转或移动的量也跟着逐渐变小,当误差小于某个很小的数,例如0.0001时,我们就可以收工(收敛,Converge)了。啰嗦一句,如果随便转,转过头了再往回转,那就不是梯度下降法。我们知道,直线的公式是y=kx+b,k代表斜率,b代表偏移值(y轴上的截距)。也就是说,k可以控制直线的旋转角度,b可以控制直线的移动。强调一下,梯度下降法的实质是不断的修改k、b这两个参数值,使最终的误差到达最小。求误差时使用累加(直线点-样本点)^2,这样比直接求差距累加(直线点-样本点)的效果要好。这种利用最小化误差的平方和来解决回归问题的方法叫最小二乘法(LeastSquareMethod)。问题到此使似乎就已经解决了,可是我们需要一种适应于各种曲线拟合的方法,所以还需要继续深入研究。我们根据拟合直线不断旋转的角度(斜率)和拟合的误差画一条函数曲线,如图:从图中可以看出,误差的函数曲线是个二次曲线,凸函数(下凸,Convex),像个碗的形状,最小值位于碗的最下端。如果在曲线的最底端画一条切线,那么这条切线一定是水平的,在图中可以把横坐标轴看成是这条切线。如果能求出曲线上每个点的切线,就能得到切线位于水平状态时,即切线斜率等于0时的坐标值,这个坐标值就是我们要求的误差最小值和最终的拟合直线的最终斜率。这样,梯度下降的问题集中到了切线的旋转上。切线旋转至水平时,切线斜率=0,误差降至最小值。切线每次旋转的幅度叫做学习率(LearningRate),加大学习率会加快拟合速度,但是如果调得太大会导致切线旋转过度而无法收敛。注意:对于凹凸不平的误差函数曲线,梯度下降时有可能陷入局部最优解。下列图的曲线中有两个坑,切线有可能在第一个坑的最底部趋于水平。微分就是专门求曲线切线的工具,求出的切线斜率叫做导数(Derivative),用dy/dx或f'(x)表示。扩展到多变量的应用,如果要同时求多个曲线的切线,那么其中某个切线的斜率就叫偏导数(PartialDerivative),用∂y/∂x表示,∂读“偏(partial)”。由于实际应用中,我们一般都是对多变量进行处理,我在后面提到的导数也都是指偏导数。以上是线性回归(LinearRegression)的根本内容,以此方法为根底,把直线公式改为曲线公式,还可以扩展出二次回归、三次回归、多项式回归等多种曲线回归。下列图是Excel的回归分析功能。在多数情况下,曲线回归会比直线回归更精确,但它也增加了拟合的复杂程度。直线方程y=kx+b改为二次曲线方程y=ax^2+bx+c时,参数(Parameter)由2个(分别是k、b)变为3个(分别是a、b、c),特征(Feature)由1个(x)变为2个(x^2和x)。三次曲线和复杂的多项式回归会增加更多的参数和特征。前面讲的是总结一串数字的规律,现实生活中我们往往要根据多个特征(多串数字)来分析一件事情,每个原始特征我们都看作是一个维度(Dimension)。例如一个学生的学习成绩好坏要根据语文、数学、英语等多门课程的分数来综合判断,这里每门课程都是一个维度。当使用二次曲线和多变量(多维)拟合的情况下,特征的数量会剧增,特征数=维度^2/2这个公式可以大概计算出特征增加的情况,例如一个100维的数据,二次多项式拟合后,特征会增加到100*100/2=5000个。下面是一张50*50像素的灰度图片,如果用二次多项式拟合的话,它有多少个特征呢?——大约有3百万!它的维度是50*50=2500,特征数=2500*2500/2=3,125,000。如果是彩色图片,维度会增加到原来的3倍,那么特征数将增加到接近3千万了!这么小的一张图片,就有这么巨大的特征量,可以想像一下我们的数码相机拍下来的照片会有多大的特征量!而我们要做的是从十万乃至亿万张这样的图片中找规律,这可能吗?很显然,前面的那些回归方法已经不够用了,我们急需找到一种数学模型,能够在此根底上不断减少特征,降低维度。于是,“人工神经网络(ANN,ArtificialNeuralNetwork)”就在这样苛刻的条件下粉墨〔闪亮〕登场了,神经科学的研究成果为机器学习领域开辟了广阔的道路。考前须知:如果是a,b,c三个原始特征,那么转换为2次多项式为a^2+a*b+a*c+b^2+b*c+c^2,一共6项(6个特征);如果是a,b,c,d四个原始特征,那么转换为a^2+a*b+a*c+a*d+b^2+b*c+b*d+c^2+b*c+d^2,共10个特征,当原始特征数越来越大时,转换的特征数会趋于"原始特征数的平方/2"。,可以用O(n^2)来表示。神经元有一种假说:“智能来源于单一的算法(OneLearningAlgorithm)”。如果这一假说成立,那么利用单一的算法(神经网络)处理世界上千变万化的问题就成为可能。我们不必对万事万物进行编程,只需采用以不变应万变的策略即可。有越来越多的证据证明这种假说,例如人类大脑发育初期,每一局部的职责分工是不确定的,也就是说,人脑中负责处理声音的局部其实也可以处理视觉影像。下列图是单个神经元(Neuron),或者说一个脑细胞的生理结构:下面是单个神经元的数学模型,可以看出它是生理结构的简化版,模仿的还挺像:解释一下:+1代表偏移值(偏置项,BiasUnits);X1,X2,X2代表初始特征;w0,w1,w2,w3代表权重(Weight),即参数,是特征的缩放倍数;特征经过缩放和偏移后全部累加起来,此后还要经过一次激活运算然后再输出。激活函数有很多种,后面将会详细说明。举例说明:55/5=11X1*w1+X2*w2+...+Xn*wn这种计算方法称为加权求和(WeightedSum)法,此方法在线性代数里极为常用。加权求和的标准数学符号是,不过为了简化,我在教程里使用女巫布莱尔的符号表示,刚好是一个加号和一个乘号的组合。这个数学模型有什么意义呢?下面我对照前面那个y=kx+b直线拟合的例子来说明一下。这时我们把激活函数改为Purelin(45度直线),Purelin就是y=x,代表保持原来的值不变。这样输出值就成了Y直线点=b+X直线点*k,即y=kx+b。看到了吧,只是换了个马甲而已,还认的出来吗?下一步,对于每个点都进行这种运算,利用Y直线点和Y样本点计算误差,把误差累加起来,不断地更新b、k的值,由此不断地移动和旋转直线,直到误差变得很小时停住(收敛)。这个过程完全就是前面讲过的梯度下降的线性回归。一般直线拟合的精确度要比曲线差很多,那么使用神经网络我们将如何使用曲线拟合?答案是使用非线性的激活函数即可,最常见的激活函数是Sigmoid(S形曲线),Sigmoid有时也称为逻辑回归(LogisticRegression),简称logsig。logsig曲线的公式如下:还有一种S形曲线也很常见到,叫双曲正切函数(tanh),或称tansig,可以替代logsig。下面是它们的函数图形,从图中可以看出logsig的数值范围是0~1,而tansig的数值范围是-1~1。自然常数e公式中的e叫自然常数,也叫欧拉数,e=2.71828...。e是个很神秘的数字,它是“自然律”的精髓,其中暗藏着自然增长的奥秘,它的图形表达是旋涡形的螺线。融入了e的螺旋线,在不断循环缩放的过程中,可以完全保持它原有的弯曲度不变,就像一个无底的黑洞,吸进再多的东西也可以保持原来的形状。这一点至关重要!它可以让我们的数据在经历了多重的Sigmoid变换后仍维持原先的比例关系。e是怎么来的?e=1+1/1!+1/2!+1/3!+1/4!+1/5!+1/6!+1/7!+...=1+1+1/2+1/6+1/24+1/120+...≈2.71828(!代表阶乘,3!=1*2*3=6)再举个通俗点的例子:从前有个财主,他特别贪财,喜欢放债。放出去的债年利率为100%,也就是说借1块钱,一年后要还给他2块钱。有一天,他想了个坏主意,要一年算两次利息,上半年50%,下半年50%,这样上半年就有1块5了,下半年按1块5的50%来算,就有1.5/2=0.75元,加起来一年是:上半年1.5+下半年0.75=2.25元。用公式描述,就是(1+50%)(1+50%)=(1+1/2)^2=2.25元。可是他又想,如果按季度算,一年算4次,那岂不是更赚?那就是(1+1/4)^4=2.44141,果然更多了。他很快乐,于是又想,那干脆每天都算吧,这样一年下来就是(1+1/365)^365=2.71457。然后他还想每秒都算,结果他的管家把他拉住了,说要再算下去别人都会疯掉了。不过财主还是不死心,算了很多年终于算出来了,当x趋于无限大的时候,e=(1+1/x)^x≈2.71828,结果他成了数学家。e在微积分领域非常重要,e^x的导数依然是e^x,自己的导数恰好是它自己,这种巧合在实数范围内绝无仅有。一些不同的称呼:e^x和e^-x的图形是对称的;ln(x)是e^x的逆函数,它们呈45度对称。神经网络好了,前面花了不少篇幅来介绍激活函数中那个暗藏玄机的e,下面可以正式介绍神经元的网络形式了。下列图是几种比拟常见的网络形式:-左边蓝色的圆圈叫“输入层”,中间橙色的不管有多少层都叫“隐藏层”,右边绿色的是“输出层”。-每个圆圈,都代表一个神经元,也叫节点(Node)。-输出层可以有多个节点,多节点输出常常用于分类问题。-理论证明,任何多层网络可以用三层网络近似地表示。-一般凭经验来确定隐藏层到底应该有多少个节点,在测试的过程中也可以不断调整节点数以取得最正确效果。计算方法:-虽然图中未标识,但必须注意每一个箭头指向的连线上,都要有一个权重(缩放)值。-输入层的每个节点,都要与的隐藏层每个节点做点对点的计算,计算的方法是加权求和+激活,前面已经介绍过了。(图中的红色箭头指示出某个节点的运算关系)-利用隐藏层计算出的每个值,再用相同的方法,和输出层进行计算。-隐藏层用都是用Sigmoid作激活函数,而输出层用的是Purelin。这是因为Purelin可以保持之前任意范围的数值缩放,便于和样本值作比拟,而Sigmoid的数值范围只能在0~1之间。-起初输入层的数值通过网络计算分别传播到隐藏层,再以相同的方式传播到输出层,最终的输出值和样本值作比拟,计算出误差,这个过程叫前向传播(ForwardPropagation)。前面讲过,使用梯度下降的方法,要不断的修改k、b两个参数值,使最终的误差到达最小。神经网络可不只k、b两个参数,事实上,网络的每条连接线上都有一个权重参数,如何有效的修改这些参数,使误差最小化,成为一个很棘手的问题。从人工神经网络诞生的60年代,人们就一直在不断尝试各种方法来解决这个问题。直到80年代,误差反向传播算法(BP算法)的提出,才提供了真正有效的解决方案,使神经网络的研究绝处逢生。BP算法是一种计算偏导数的有效方法,它的根本原理是:利用前向传播最后输出的结果来计算误差的偏导数,再用这个偏导数和前面的隐藏层进行加权求和,如此一层一层的向后传下去,直到输入层(不计算输入层),最后利用每个节点求出的偏导数来更新权重。为了便于理解,后面我一律用“残差(errorterm)”这个词来表示误差的偏导数。输出层→隐藏层:残差=-(输出值-样本值)*激活函数的导数隐藏层→隐藏层:残差=(右层每个节点的残差加权求和)*激活函数的导数如果输出层用Purelin作激活函数,Purelin的导数是1,输出层→隐藏层:残差=-(输出值-样本值)如果用Sigmoid(logsig)作激活函数,那么:Sigmoid导数=Sigmoid*(1-Sigmoid)输出层→隐藏层:残差=-(Sigmoid输出值-样本值)*Sigmoid*(1-Sigmoid)=-(输出值-样本值)*输出值*(1-输出值)隐藏层→隐藏层:残差=(右层每个节点的残差加权求和)*当前节点的Sigmoid*(1-当前节点的Sigmoid)如果用tansig作激活函数,那么:tansig导数=1-tansig^2残差全部计算好后,就可以更新权重了:输入层:权重增加=输入值*右层对应节点的残差*学习率隐藏层:权重增加=当前节点的Sigmoid*右层对应节点的残差*学习率偏移值的权重增加=右层对应节点的残差*学习率学习率前面介绍过,学习率是一个预先设置好的参数,用于控制每次更新的幅度。此后,对全部数据都反复进行这样的计算,直到输出的误差到达一个很小的值为止。以上介绍的是目前最常见的神经网络类型,称为前馈神经网络(FeedForwardNeuralNetwork),由于它一般是要向后传递误差的,所以也叫BP神经网络(BackPropagationNeuralNetwork)。BP神经网络的特点和局限:-BP神经网络可以用作分类、聚类、预测等。需要有一定量的历史数据,通过历史数据的训练,网络可以学习到数据中隐含的知识。在你的问题中,首先要找到某些问题的一些特征,以及对应的评价数据,用这些数据来训练神经网络。-BP神经网络主要是在实践的根底上逐步完善起来的系统,并不完全是建立在仿生学上的。从这个角度讲,实用性>生理相似性。-BP神经网络中的某些算法,例如如何选择初始值、如何确定隐藏层的节点个数、使用何种激活函数等问题,并没有确凿的理论依据,只有一些根据实践经验总结出的有效方法或经验公式。-BP神经网络虽然是一种非常有效的计算方法,但它也以计算超复杂、计算速度超慢、容易陷入局部最优解等多项弱点著称,因此人们提出了大量有效的改良方案,一些新的神经网络形式也层出不穷。文字的公式看上去有点绕,下面我发一个详细的计算过程图。参考这个:我做了整理这里介绍的是计算完一条记录,就马上更新权重,以后每计算完一条都即时更新权重。实际上批量更新的效果会更好,方法是在不更新权重的情况下,把记录集的每条记录都算过一遍,把要更新的增值全部累加起来求平均值,然后利用这个平均值来更新一次权重,然后利用更新后的权重进行下一轮的计算,这种方法叫批量梯度下降(BatchGradientDescent)。推荐的入门级学习资源:AndrewNg的《机器学习》公开课:Coursera公开课笔记中文版〔神经网络的表示〕:://52opencourse/139/coursera公开课笔记-斯坦福大学机器学习第八课-神经网络的表示-neural-networks-representationCoursera公开课视频〔神经网络的学习〕:://52opencourse/289/coursera公开课视频-斯坦福大学机器学习第九课-神经网络的学习-neural-networks-learning斯坦福深度学习中文版:教程关于Matlab的入门教程,参看这个帖子:例1:我们都知道,面积=长*宽,假设我们有一组数测量据如下:我们利用这组数据来训练神经网络。〔在Matlab中输入以下的代码,按回车即可执行〕p=[25;36;122;16;92;812;47;79]';%特征数据X1,X2t=[101824618962863];%样本值net=newff(p,t,20);%创立一个BP神经网络ff=FeedForwardnet=train(net,p,t);%用p,t数据来训练这个网络出现如下的信息,根据蓝线的显示,可以看出最后收敛时,误差已小于10^-20。你也许会问,计算机难道这样就能学会乘法规那么吗?不用背乘法口诀表了?先随便选几个数字,试试看:s=[37;69;45;57]';%准备一组新的数据用于测试y=sim(net,s)%模拟一下,看看效果%结果是:25.102961.588229.584837.5879看到了吧,预测结果和实际结果还是有差距的。不过从中也能看出,预测的数据不是瞎蒙的,至少还是有那么一点靠谱。如果训练集中的数据再多一些的话,预测的准确率还会大幅度提高。你测试的结果也许和我的不同,这是因为初始化的权重参数是随机的,可能会陷入局部最优解,所以有时预测的结果会很不理想。例2:下面测试一下拟合正弦曲线,这次我们随机生成一些点来做样本。p=rand(1,50)*7%生成1行50个0~7之间的随机数t=sin(p)%计算正弦曲线s=[0:0.1:7];%生成0~7的一组数据,间隔0.1,用于模拟测试plot(p,t,'x')%画散点图net=newff(p,t,20);%创立神经网络net=train(net,p,t);%开始训练y=sim(net,s);%模拟plot(s,y,'x')%画散点图从图中看出,这次的预测结果显然是不理想的,我们需要设置一些参数来调整。下面的设置是一种标准的批量梯度下降法的配置。%创立3层神经网络[隐藏层10个节点->logsig,输出层1个节点->purelin]traingd代表梯度下降法net=newff(p,t,10,{'logsig''purelin'},'traingd');%10不能写成[101]%设置训练参数net.trainparam.show=50;%显示训练结果(训练50次显示一次)net.trainparam.epochs=500;%总训练次数net.trainparam.goal=0.01;%训练目标:误差<0.01net.trainParam.lr=0.01;%学习率(learningrate)net=train(net,p,t);%开始训练注意:newff的第三个参数10不能写成[101],否那么就是4层网络,两个隐藏层,分别是10个和1个节点。这个很容易弄错。〔输出层的节点数程序会自动根据t的维度自动判断,所以不用指定〕y=sim(net,s);%模拟plot(s,y,'x')%画散点图这时的效果显然更差了。把精度调高一点看看。训练次数加到9999,误差<0.001;学习率调到0.06,希望能加快点速度。%创立2层神经网络[隐藏层10个节点->logsig,输出层1个节点->purelin]traingd代表梯度下降法net=newff(p,t,10,{'logsig''purelin'},'traingd');%设置训练参数net.trainparam.show=50;%每间隔50次显示一次训练结果net.trainparam.epochs=9999;%总训练次数net.trainparam.goal=0.001;%训练目标:误差<0.001net.trainParam.lr=0.06;%学习率(learningrate)net=train(net,p,t);%开始训练标准的批量梯度下降法的速度确实够慢,这次计算花了一分多钟。y=sim(net,s);%模拟plot(s,y,'x')%画散点图效果比上次稍好一点。不过这条曲线显得坑坑洼洼的很难看,这是一种过拟合(Overfitting)现象,与之相反的是欠拟合(Underfitting)。先来解决速度问题,把traingd改为trainlm即可。trainlm使用LM算法,是介于牛顿法和梯度下降法之间的一种非线性优化方法,不但会加快训练速度,还会减小陷入局部最小值的可能性,是Matlab的默认值。net=newff(p,t,10,{'logsig''purelin'},'trainlm');...后面的代码不变这个速度比拟惊叹了,1秒钟之内完成,只做了6轮计算,效果也好了一些。不过,LM算法也有弱点,它占用的内存非常大,所以没把其它算法给淘汰掉。下面解决过拟合问题,把隐藏层的节点数目设少一点就行了。net=newff(p,t,3,{'logsig''purelin'},'trainlm');...后面的代码不变这回终于到达满意的效果了。(有时会出现局部最优解,可以多试几次)如果节点数目太少,会出现欠拟合的情况。关于隐藏层的节点个数,一般是要凭感觉去调的。如果训练集的维数比拟多,调节起来比拟耗时间,这时可以根据经验公式上下浮动地去调整。下面给出几个经验公式供参考:如果把输出层改为logsig激活会是什么样子呢?net=newff(p,t,3,{'logsig''logsig'});%创立神经网络net=train(net,p,t);%开始训练y=sim(net,s);%模拟plot(s,y,'x')%画散点图可以看出,-1~0范围之间的点都变为0了。使用logsig输出时要想得到完整数值范围的效果,必须先对数据进行归一化才行。归一化(Normalization),也叫标准化,就是把一堆数字按比例缩放到0~1或-1~1的范围。虽然用Purelin输出可以不必归一化,但归一化能在一定程度上加快收敛速度,因此被许多教程定为训练前的必须步骤。公式为:归一值=(当前值x-最小值min)/(最大值max-最小值min)如果限定了范围,公式为:y=(ymax-ymin)*(x-xmin)/(xmax-xmin)+ymin;0.1~0.9的范围:(0.9-0.1)*(x-min)/(max-min)*(0.9-0.1)+0.1把5,2,6,3这四个数归一化:Matlab的归一化命令为:mapminmax注:网上的不少教程里用premnmx命令来归一化,要注意Matlab版本R2007b和R2008b,premnmx在处理单列数据时有bug,Matlab已给出了警告,R2009a版才修正。因此推荐使用mapminmax。mapminmax的输入输出值和premnmx是行列颠倒的,使用时要注意代码中是否添加转置符号。a=[5,2,6,3];b=mapminmax(a,0,1)%归一化到0~1之间%b=0.750001.00000.2500可以用下面的代码归一化到〔0,1〕a=[5,2,6,3];b=mapminmax(a)+1/2c=mapminmax(a)%归一化到-1~1之间%c=0.5000-1.00001.0000-0.5000反归一化(Denormalization)就是按归一化时的比例复原数值。a=[5,2,6,3];[c,PS]=mapminmax(a);%PS记录归一化时的比例mapminmax('reverse',c,PS)%利用PS反归一化%ans=5263神经网络的归一化(0~1范围)代码:p=rand(1,50)*7;%特征数据t=sin(p);%样本值s=[0:0.1:7];%测试数据[pn,ps]=mapminmax(p,0,1);%特征数据归一化[tn,ts]=mapminmax(t,0,1);%样本值归一化sn=mapminmax('apply',s,ps);%测试数据,按ps比例缩放net=newff(pn,tn,[51],{'logsig''logsig'});%创立神经网络net=train(net,pn,tn);%开始训练yn=sim(net,sn);%模拟y=mapminmax('reverse',yn,ts);%按ps的比例复原plot(s,y,'x')%画散点图神经网络工具箱还有一个UI图形操作界面,执行nntool就可以翻开。我觉得不如写代码方便,所以不怎么用。我提供一个相关的教程链接,有兴趣的可以看一下:matlab神经网络工具箱创立神经网络:://blog.sina/s/blog_8684880b0100vxtv.html〔新浪替换成sina〕logsigSigmoid函数(S形函数,LogisticFunction)是受统计学模型的启发而产生的激活函数。基于生物学的神经元激活函数是这样的:参看:实践证明了基于统计学的Sigmoid函数激活效果要比基于生物学的模型好,而且计算起来很方便,所以说不能以机器和人的相似度为标准来判断AI算法的好坏。Sigmoid函数原先是个描述人口增长的数学模型,1838提出,给出的是导数形式(概率密度)。人口增长规律:起初阶段大致是指数增长;然后逐渐开始变得饱和,增长变慢;到达成熟时几乎停止增长;整个过程形如一条S型曲线。导数的形式知道了,那么它的原函数是什么样子呢?导数求原函数,用统计学的话来讲,即根据概率密度函数(PDF)求累积分布函数(CDF),不定积分(IndefiniteIntegral)就是专门用来做这个的工具。根据不定积分的知识可知,由于常数项是可变的,所以存在无数个原函数的可能。让我们先用图解法看一下:既然导数是函数曲线的斜率,那么可以把一定数值范围内的斜率,都画成一根根的短斜线,组成斜率场(SlopeFields,DirectionFields),然后根据这些斜线的走势,画出积分曲线。Matlab可以用quiver命令来画斜率场。从上图中可以看出,在y轴的0~1之间是个分水岭,0和1处的方向趋于水平。下面放大0~1的范围看看是什么样子的。看到了吧,我们要的LogisticSigmoid就在这里呢。下面给出符号求解的过程:tansig双曲正切函数(双极S形函数,tanh,HyperbolicTangent),读tanch,18世纪就已经出现了。它的定义是:tanh(x)=sinh(x)/cosh(x),可以由著名的欧拉公式(Euler'sformula)推导出来。用tanh作激活函数,收敛比拟快,效果比Logistic函数还要好。欧拉公式:i是虚数(ImaginaryNumber)单位,它的定义是:(即i^2=-1)题外话:根据上面的公式变换,可以得出史上最美的数学公式:,数学中最神秘的5个符号e、i、π、1和0,全包含在里面了。求tanh的导数:logsig和tansig的关系:matlab神经网络工具箱创立神经网络为了看懂师兄的文章中使用的方法,研究了一下神经网络昨天花了一天的时间查怎么写程序,但是费了半天劲,不能运行,百度知道里倒是有一个,可以运行的,先贴着做标本%生成训练样本集clearall;clc;P=[1100.8072400.21511821.5;1102.8652400.11521212;1102.592400.11242411.5;2200.62400.31231821;22032400.32532111.5;1101.5622400.31531811.5;1100.5472400.3151921.5];01.3183000.11521812];T=[54248162787168380314797;28614639586963782898;86002402710644415328084;230802445102362823335913;602571278927675373541;346159353280762110049;56783172907164548144040];@907117437120368130179];m=max(max(P));n=max(max(T));P=P'/m;T=T'/n;%-------------------------------------------------------------------------%pr(1:9,1)=0;%输入矢量的取值范围矩阵pr(1:9,2)=1;bpnet=newff(pr,[124],{'logsig','logsig'},'traingdx','learngdm');%建立BP神经网络,12个隐层神经元,4个输出神经元%tranferFcn属性'logsig'隐层采用Sigmoid传输函数%tranferFcn属性'logsig'输出层采用Sigmoid传输函数%trainFcn属性'traingdx'自适应调整学习速率附加动量因子梯度下降反向传播算法训练函数%learn属性'learngdm'附加动量因子的梯度下降学习函数

net.trainParam.epochs=1000;%允许最大训练步数2000步net.trainParam.goal=0.001;%训练目标最小误差0.001net.trainParam.show=10;%每间隔100步显示一次训练结果net.trainParam.lr=0.05;%学习速率0.05bpnet=train(bpnet,P,T);%-------------------------------------------------------------------------p=[1101.3183000.11521812];p=p'/m;r=sim(bpnet,p);R=r'*n;display(R);运行的结果是出现这样的界面点击performance,trainingstate,以及regression分别出现下面的界面再搜索,发现可以通过神经网络工具箱来创立神经网络,比拟友好的GUI界面,在输入命令里面输入nntool,就可以开始了。点击import之后就出现下面的具体的设置神经网络参数的对话界面,

这是输入输出数据的对话窗

首先是训练数据的输入

然后点击new,创立一个新的神经网络network1,并设置其输入输出数据,包括名称,神经网络的类型以及隐含层的层数和节点数,还有隐含层及输出层的训练函数等

点击view,可以看到这是神经网络的可视化直观表达

创立好了一个network之后,点击open,可以看到一个神经网络训练,优化等的对话框,选择了输入输出数据后,点击train,神经网络开始训练,如右下方的图,可以显示动态结果

下面三个图形那么是点击performance,trainingstate以及regression而出现的

下面就是simulate,输入的数据是用来检验这个网络的数据,output改一个名字,这样就把输出数据和误差都存放起来了

在主界面上点击export就能将得到的out结果输入到matlab中并查看

下列图就是输出的两个outputs结果

关于神经网络〔matlab〕归一化的整理BP神经网络matlab实现实例经过最近一段时间的神经网络学习,终于能初步使用matlab实现BP网络仿真试验。这里特别感谢研友sistor2004的帖子《自己编的BP算法〔工具:matlab〕》和研友wangleisxcc的帖子《用C++,Matlab,Fortran实现的BP算法》前者帮助我对BP算法有了更明确的认识,后者让我对matlab下BP函数的使用有了初步了解。因为他们发的帖子都没有加注释,对我等新手阅读时有一定困难,所以我把sistor2004发的程序稍加修改后加注了详细解释,方便新手阅读。%严格按照BP网络计算公式来设计的一个matlab程序,对BP网络进行了优化设计%yyy,即在o(k)计算公式时,当网络进入平坦区时(<0.0001)学习率加大,

出来后学习率又复原%v(i,j)=v(i,j)+deltv(i,j)+a*dv(i,j);动量项clearallclcinputNums=3;

%输入层节点outputNums=3;

%输出层节点hideNums=10;

%隐层节点数maxcount=20000;

%最大迭代次数samplenum=3;

%一个计数器,无意义precision=0.001;

%预设精度yyy=1.3;

%yyy是帮助网络加速走出平坦区

alpha=0.01;

%学习率设定值a=0.5;

%BP优化算法的一个设定值,对上组训练的调整值按比例修改error=zeros(1,maxcount+1);%error数组初始化;目的是预分配内存空间errorp=zeros(1,samplenum);%同上v=rand(inputNums,hideNums);

%3*10;v初始化为一个3*10的随机归一矩阵;v表输入层到隐层的权值deltv=zeros(inputNums,hideNums);%3*10;内存空间预分配dv=zeros(inputNums,hideNums);%3*10;

w=rand(hideNums,outputNums);

*3;同Vdeltw=zeros(hideNums,outputNums);*3dw=zeros(hideNums,outputNums);*3samplelist=[0.1323,0.323,-0.132;0.321,0.2434,0.456;-0.6546,-0.3242,0.3255];

%3*3;指定输入值3*3(实为3个向量)expectlist=[0.5435,0.422,-0.642;0.1,0.562,0.5675;-0.6464,-0.756,0.11];

%3*3;期望输出值3*3(实为3个向量),有导师的监督学习count=1;while(count<=maxcount)

%结束条件1迭代20000次c=1;while(c<=samplenum)fork=1d(k)=expectlist(c,k);%获得期望输出的向量,d(1:3)表示一个期望向量内的值endfori=1:inputNumsx(i)=samplelist(c,i);%获得输入的向量〔数据〕,x(1:3)表一个训练向量end%Forward();forj=1:hideNumsnet=0.0;fori=1:inputNumsnet=net+x(i)*v(i,j);%输入层到隐层的加权和∑X(i)V(i)

endy(j)=1/(1+exp(-net));

%输出层处理f(x)=1/(1+exp(-x))单极性sigmiod函数endfork=1net=0.0;forj=1:hideNumsnet=net+y(j)*w(j,k);endifcount>=2&&error(count)-error(count+1)<=0.0001o(k)=1/(1+exp(-net)/yyy);

%平坦区加大学习率elseo(k)=1/(1+exp(-net));

%同上endend%BpError(c)反应/修改;errortmp=0.0;fork=1errortmp=errortmp+(d(k)-o(k))^2;%第一组训练后的误差计算enderrorp(c)=0.5*errortmp;%误差E=∑(d(k)-o(k))^2*1/2%end�ckward();fork=1【转】BP神经网络matlab实现实例utputNumsyitao(k)=(d(k)-o(k))*o(k)*(1-o(k));%输入层误差偏导endforj=1:hideNumstem=0.0;fork=1【转】BP神经网络matlab实现实例utputNumstem=tem+yitao(k)*w(j,k);%为了求隐层偏导,而计算的∑endyitay(j)=tem*y(j)*(1-y(j));%隐层偏导end%调整各层权值forj=1:hideNumsfork=1【转】BP神经网络matlab实现实例utputNumsdeltw(j,k)=alpha*yitao(k)*y(j);%权值w的调整量deltw(已乘学习率)w(j,k)=w(j,k)+deltw(j,k)+a*dw(j,k);%权值调整,这里的dw=dletw(t-1),实际是对BP算法的一个dw(j,k)=deltw(j,k);%改良措施--增加动量工程的是提高训练速度endendfori=1:inputNumsforj=1:hideNumsdeltv(i,j)=alpha*yitay(j)*x(i);%同上deltwv(i,j)=v(i,j)+deltv(i,j)+a*dv(i,j);dv(i,j)=deltv(i,j);endendc=c+1;end%第二个while结束;表示一次BP训练结束doubletmp;tmp=0.0;fori=1:samplenumtmp=tmp+errorp(i)*errorp(i);%误差求和endtmp=tmp/c;error(count)=sqrt(tmp);%误差求均方根,即精度if(error(count)<precision)%另一个结束条件break;endcount=count+1;%训练次数加1end%第一个while结束error(maxcount+1)=error(maxcount);p=1:count;pp=p/50;plot(pp,error(p),'-');%显示误差制作双纵坐标excel图常看到双纵坐标轴的图,但是一直也没要用,所以没有深究。今天要用,才发现不会,百度了一番之后试验成功,为防止我这脑袋忘记了,还是记下来,很简单。下表是我需要制作的两个地方的面积,想做一个每个月份两个地区面积的比拟图。如果之间插入散点图,可以看到如下列图,由于数据相差比拟大,造成低值的那个地区几乎值都在最底下,看不出高地变化。鼠标点击红色区域,就是我们觉得要编辑的数据,右键,如下列图,点击设置数据系列格式在系列选项中,可以看到系列选项,选择次坐标

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论