Levenberg_Marquardt神经网络算法研究_董一芬
385 《商场现代化》2009 年 3 月(上旬刊)总第 568 期
=0.01,ξ=10。在采用Levenberg-Marquardt算法时,为使收敛 速度更快,需要增加学习率因子α,取α为 0.4。Levenberg-
(1) Marquardt算法的计算复杂度为
为网络权值数目,如果网
样本
定义网络的误差指标函数为:
5.若
则得到解 Xopt,转向 7(停止计
算); 否则转向 6。
6.F(X(k+1))< F(X(k)),则令
,k=k+1,
转向 2; 否则 = * ξ,转向 3。 7.停止计算 在实际操作中, 是一个试探性的参数,对于给定的 ,如
果求得的 h(k)能使误差函数 Ep(X)降低,则 被因子ξ除;若 误差函数 Ep(X)增加,则 乘以因子ξ。在仿真中,选取初始值
对 i=1,2,…,M 求得
3.解线性方程组 求出搜索梯度方向 h(k)。
4.直线搜索,
Jacobi 矩阵
其中λ 满足 k
参考文献: [1]徐嗣鑫 戴友元:前向神经网络的一种快速学习算法及其应 用.控制与决策, 1993, 8(4): 284~ 288 [2]王耀南 童调生 蔡自兴:基于神经元网络的智能 PID控制 及应用。信息与控制, 1994, 23(3): 185~189 [3]张星昌:前馈神经网络的新学习算法研究及其应用。控制与 决策, 1997, 12(3), 213~ 216
(2)
然后就可以按照各种学习算法开始对 X 进行训练, 得到最优 X , 使得
opt
二、Levenberg-Marquardt神经网络算法 1.给定初始点 X(0), 精度,σ,k=0。 2.对 i=1,2,…,M 求 f (X(k)),得向量
学术研讨
Levenberg-Marquardt 神经网络算法研究
董一芬 山东经贸职业学院
[摘 要] 前馈神经网络中的向后传播算法(Backpropagation (BP) Algorithm)算法存在固有的缺陷,Levenberg-Marquardt神经网 络算法可以有效地克服这一点 BP 算法的缺陷。本文给出了 Levenberg-Marquardt 算法。
参数难以调整,非线性神经网络学习算法Levenberg-Marqu陷。
一、前馈神经网络
前馈神经网络由输入层、隐层和输出层组成。令u=[u1,u2,Λ, um]T,y=[y1,y2,Λ,yn]T 络的输入、输出向量, 令 X=[x1,x2,Λ,xN]T 为网络的权及阈值的全体所组成的向量。给定 P 组输入输出训练
i
络中权值的数目很大。则计算量和存储量都非常大。因此,当 每次迭代效率显著提高时,其整体性能可以大为改善,特别是 在精度要求高的时候。
三、结论 前馈神经网络中,BP 算法存在收敛速度很慢,收敛于局部 极小点等缺陷,而Gauss-Newton的改进算法Levenberg-Marquardt 算法能有效克服 BP 算法的缺陷。
[关键词] 前馈神经网络 Levenberg-Marquardt 算法 BP 算法
前馈神经网络BP学习算法在理论上具有逼近任意非线性连续
映射的能力,在非线性系统的建模及控制领域里有着广泛的应用。
然而BP 算法存在一些不足, 主要是收敛速度很慢; 往往收敛于
局部极小点; 数值稳定性差, 学习率、动量项系数和初始权值等
Levenberg-Marquardt算法的建模及在水敏损害预测中应用
础 :g ) ( ( 一 ) :1 2 ,
m
计算到某一步产生 了更小的 F W), ( 则 在下一步
被 除 以 0, 样 算 法 就 接 近 于 牛 顿 法 。这 就 得 到 了 这
一
=
.
∑ 础 + : 1,, = , ,) c + = ,一 ( 2 1, ・ 2 …
于零 , 使 目标 函数 下 降缓 慢 ; 牛 顿 法 9 可在 最 优 致 而 { 《 值 附 近 产 生 一 个 理 想 的 搜 索 方 向 。鉴 于 此 , M 算 I 法 将 两 者结 合 , 这 种结 合 变成 程 序参 数 ,} 序 本 使 }程 身 随 着 当 前 形 态 的 改 变 而 趋 于梯 度 下 降 法 或 牛 顿 法 , 点是 在 极 小点 附近 有 较 快 的 收敛 速 度 , 而很 优 从
由于神经网络 由三部 分组成 , 输入层 、 隐藏层 、
输 出层 。例 如现 有 一 套 非线 性 样 本 数 据 得 到 , 输 组
收稿 日期 :0 9)42 修改 稿 ) 2 0 42 ( )
基 金 项 目 : I省教 育 厅 ( 湖: E B类 ) 目 项
第 4期
宋文广. eeb r— aq ad 算法 的建模 及在 水敏 损害预测中应用 Lvn egM rurt
法 开 始 时 取 值 较 小 , 某 步 不 能 减 少 E ) , 若 ( 值 则将 乘 上一 个 因子 0 0> 1 后 再 重 复 这 步 。若 ( )
对应隐藏单元 的输 出
, 预测结果单元 Y 的计 “
算公式如下 :
=
∑
+ + (= , …,) , 1 , 2
1 引 言
入、 出, 输 构造 其 模 型 见 式 ( ) 2。
基于Levenberg-Marquardt算法的串联协作机器人精度标定研究
第21卷第3期 2021年3月黑龙江工业学院学报JOURNAL OF HEILONGJIANG UNIVERSITY OF TECHNOLOGYVol.21 No. 3Mar. 2021文章编号:2096 -3874(2021)03-0112 -06基于 Levenberg- Marquardt算法的串联协作机器人精度标定研究李杨1,金小飞2,刘国锋1,吴明明1(1.安徽三联学院机械工程学院,安徽合肥230000;2.哈工大机器人(合肥)国际创新研究院,安徽合肥230000)摘要:目前研究的串联协作机器人精度标定方法标定误差较大,导致定位精度较低。
为 解决上述问题,基于Levenberg - M arquardt算法研究了一种新的串联协作机器人精度标定方法,参照空间坐标系转换原理和运动行为参数,将多个机器人的每个关节看作标杆,机器人通过思维规划完成需要执行的运行指令,并将指令拆分,转化为坐标的形式,通过共享模式与其他机器人行为互通,保证串联协作机器人精度标定行为的连贯性,根据Levenberg - M arquardt算法对协作机器人精度标定模型结果进行优化处理,将机器人在完成任务的基础上,需要移动的范围内固定好标定板,实现精度标定。
实验结果表明,基于Levenberg - M arquardt算法的串联协作机器人精度标定方法能够有效减少标定误差,提高定位精度。
关键词:Levenberg - M arquardt算法;串联协作机器人;标定原理;机器人行为中图分类号:TP242 文献标识码:A随着科技的发展,针对机器人的程序化和思 维单一的特点,在工作过程中会出现一定的偏差,因此机器人研究人员制定一系列的串联协作机器 人精度标定方法来制约机器人的行为[1<。
机器人的行为精度是评估机器人性能的重要 指标之一,串联协作机器人在完成一项任务中需 要两个或者两个以上的机器人共同完成,因此对 于机器人的行为精度要求更加严格,一旦任意一 个机器人出现错误操作,就会使任务执行失败。
求解非线性不适定算子方程的一种Landweber迭代法
求解非线性不适定算子方程的一种Landweber迭代法王美吉;潘状元【摘要】针对Landweber迭代方法在非线性不适定问题上进行研究.在非线性算子和右端数据皆为近似的前提条件下,基于Frozen Landweber迭代法,提出双扰动的双循环Landweber迭代格式.在一定的条件下,通过证明迭代格式的单调性和收敛性,得出该迭代格式是有效的.【期刊名称】《哈尔滨商业大学学报(自然科学版)》【年(卷),期】2013(029)005【总页数】4页(P588-591)【关键词】非线性不适定问题;Landweber迭代法;收敛性【作者】王美吉;潘状元【作者单位】哈尔滨理工大学应用科学学院,哈尔滨150080;哈尔滨理工大学应用科学学院,哈尔滨150080【正文语种】中文【中图分类】O2411 引言考虑非线性算子方程其中:F:D(F)⊂X→Y,X,Y为 Hilbert空间.F是Frechet可微.这里考虑算子方程的解不连续依赖于右端数据的情况.由于不稳定性并且在实际问题中只有近似数据yδ满足这里为测量误差δ>0的界.对于此类非线性问题的解法,一般通过正则化方法来得到其解的近似.由于非线性不适定问题在生活中的广泛应用,已经成为横跨应用数学和计算数学两个学科的真正的研究领域[1].其理论研究大致有以下几个方面如Tikhonov正则化方法,最大嫡方法,有限维逼近等[2-5].对于非线性问题人们对Landweber迭代法给予了很大关注,文献[5]证明了Frogen Landweber 迭代法的收敛性并进行了数值试验.由于在实际问题中,算子一般也是经测量而获得的近似值,或是由离散过程而得到的原算子的一个有限维的逼近,因此真正要求解的是式(1)的一个近似方程其中:h表示Fh逼近F的程度,假定满足因此,在考虑Landweber迭代时,也应考虑算子亦有扰动的情况.假定扰动算子Fh仍保持算子F的Frechet可微且F'h在D(F)上一致收敛于F'(当h→0),本文在前人研究成果基础上提出了非线性算子方程算子与右端皆有扰动的Landweber迭代法.迭代格式为按广义误差准则来确定迭代终止步k*,则迭代序列{xδh k*}收敛到不失一般性,假定其中:βρ(x0)为以x0为中心,ρ>0的开球.2 单调性分析对于上述迭代格式,本文以m=2为例,理论验证此迭代格式的收敛性.则此迭代带格式可以改写成引理1 [6]如果式(3)成立,x*是方程(1)在βρ(x0)中的一个解,那么任意解∈βρ(x0)满足,,反之亦然,N(·)表示算子的核空间.证明:由条件(3)可得满足对所有的x∈,此引理得证.引理 2[7-8]假设 x* 为式(1)在βρ(x0)中的一个解,对于扰动数据满足‖yδ-y‖≤δ,k*是按广义误差准则(4)所确定的迭代终止步.若条件(3)、(5)成立,则有当δ=h=0时证明:由引理2知,由式(4)和假设条件有证明方法见文献[5].3 收敛性分析定理2 如果在Bρ/2(x*)中满足式(3)、(5),算子方程(1)可解,则xk收敛到式(1)的一个解x*∈Bρ/2(x*).若x+是离x0最近的惟一解,且N(F'(x+))⊂(F'(x)),成立,则xk收敛到x+.证明:令ek:x*-xk由定理1知{‖ek‖}单调下降,下界为某ε≥0,下证{ek}是 Cauchy 列.对j≥k,取l(j≥l≥k)使成立由三角不等式,有下证明(el-ek,el)也收敛到零(当k→∞时)改写由引理 2 推知,当 k,l→∞ 时 xl,1 - xl,xk,1 - xk趋于零.令由此得{ek}为 Cauchy列,所以{xk}也为Cauchy列.设xk→x*,又因为F(xk)→y(k→∞),从而x*为式(1)的解.若式(1)有惟一的距x0最近的解,则x+满足对任何 k=0,1,2,…若,N(F'(x+))⊂N(F'(xk)),则有证毕.定理3 在定理2的前提条件下,方程(1)可解,取h=0,扰动终止于K*(δ).那么当δ→0时,收敛到式(1)的解.证明参见文献[5]中命题3.当h≠0时,设(δ,h)为由式(4)确定的迭代终止步,令K*=max{k*(δ),K'*(δ,h)}其中k*(δ)为定理3中的迭代终止步,则有因为)趋于零,易知(el-ek,el)趋于零.同理可证定理4 假设条件(3)(5)成立,方程(1)可解,则当h→0,δ→0 时,xδh k*收敛到(1)的解.证明用归纳法易证,上式第一项当h→0时趋于零,而由定理3,第二项当δ→0时也是趋于零的,从而4 结语针对非线性不适定问题的求解,本文首先从Frozen Landweber迭代法入手,提出非线性算子和右端数据皆有扰动的Landweber迭代法.并且对所提出的迭代格式给出了收敛性证明.从理论分析可以看出,Frozen Landweber迭代法确实是求解非线性不适定算子方程的一种简单而稳定的方法,适合于处理算子与右端数据皆有扰动的实际问题,并且避开了Tikhonov正则化方法正则参数选取困难以及传统的Langweber迭代法收敛太慢的问题.不足之处是没有对此迭代格式进行数值试验,这将是下一步进行的工作.参考文献:[1]DENG Y J,LIU Z H.New fast iteration for determining surface temperature and heat flux of general sideways parabolic equation[J].Nonlinear Anal.Real World Appl.,2011,12(1):156 -166.[2]ZHENG G H,WEI T.Two regularization methods for solving a Riesz-Feller space-frational backward diffusion problem[J].Inverse Problems,2010,26:1 -22.[3]JIN Q N.On a regularized Levenberg-Marquardt method for solving nonlinear inverse problems[J].Numer.Math.,2010.115:229-259.[4]YANGQQ,LIU F W,TURNER I.Numerical methods for fraction partial differential equations with Riesz space fractional derivatives[J].Appl Math Model.,2010,34:200 -218.[5]XU J,HAN B,LI L.Frozen Landweber Iteration for Nonlinear Ill-Posed problems[J].Acta Mathematicae Applicatae Sinica,2007,23(2):329 -336.[6]HANKE M.Accelerated Landweber Iterations for the Solution of Ill-Posed Equations[J].Numer.Math,1991,60(1):341 -373.[7]韩波,刘家琦,后步风.非线性不适定算子方程算子与右端项皆有扰动的Land weber迭代法[J].计算数学,2002,24(4):479-486.[8]皮丽敏,潘状元.一族求解非线性方程的高阶迭代方法[J].哈尔滨商业大学学报:自然科学版,2012,28(6):751-753,768.。
基于LMBP神经网络的声纳图像识别
3 声纳图像识别系统的特征提取
由于目前预成多波束高频声纳及高分辨率成像声纳的发展, 使得用于水下目标自动识别 系统的目标特征信息提取技术得以发展。 由于声纳图像中含有丰富的纹理信息, 因此提取图 像中的纹理特征做为识别依据是声纳图像识别的有效手段之一。
-4-
m m
(13)
-3-
S m −1 j =1
n =
m i
∑ω
m i, j
−1 am + bim j
(14)
定义Marquardt信号项为:
s im ,h =
其中: h = ( q − 1) S
M
∂ ek ,q ∂ vh = m ∂ ni ,q ∂ nim ,q
如果
(6)
式中:比例系数 µ 为常数, I 是单位矩阵。从该式可看出,如果 µ = 0 ,则为高斯牛顿法;
µ 取值很大,则L-M算法接近梯度下降法,每迭代成功一步,则 µ 减小一些,这样在
接近误差目标的时候,逐渐与高斯牛顿法相似。实践证明,采用L-M算法可以比原来的梯度 下降法速度提高几十甚至上百倍[2]。
(9)
x T = [ x1 x 2 L x n ]
1 1 1 1 1 2 M = [ w1 ,1 w1, 2 L wS 1 , R b1 L bS 1 w1,1 L bS M ]
(10)
雅可比矩阵的每一项可通过BP算法的一种简单改进形式来计算,即:
1 ∂E ( x) ∂ eq eq = ∂xl 2∂xl
⎧− f m (nim (i = k ) ,k ) =⎨ ⎩0 (i ≠ k )
LMBP算法反向传播的初始化计算式为:
m m sq ) = − F m (nq
第六章 Levenberg-Marquardt方法
T
f ( xk )
(7)
T
从而:
x
k 1
x A x
A x
k 1
k
T
A x
T
k
k I
1
A xk f (xk ) .
由于 A x A x I 正定(适当调整 ), 从而(7)产生的方向
如果
A x
k T
A x k f ( x k ) hk ,则 k 0 ;否则 k 0 .
S ( x ) f ( x ) A ( x x ) A d f ( x ) k
k k k
k k T k k [ A d f ( x ) ] [ A d f ( x ) ] , k k
k k 其中: d x x 。
2 k
2 k
k k T k k 记 ( x ) [ A d f ( x ) ] [ A d f ( x ) ] , 则可 min ( x ) k k
非线性最小二乘法
• 1.改进的Gauss-Newton法 • 2.Levenberg-Marquardt方法 • 3.信赖域(Biblioteka -M)方法一、非线性最小二乘法
1.一般形式:
min S ( x ) f ( x ) f ( x ) f ( x )
T 2
T 其中: f ( x ) ( f ( x ), f ( x ),..., f ( x )) 1 2 m T x ( x , x ,..., x ) 1 2 n ;
Step 2 : 若 S ( x z ) S ( x ), 则令 : 并返回 Step 1 。
Levenberg—Marquardt算法在T—S型模糊RBF神经网络训练中的应用
XU F n - o , H e gY u Z ANG XioGa g( p r n f lc ia a dIfr t nE gn eig H n n a - n De at t et c l n omai n ier , u a me o E r n o n
Unv ri , h n sa4 8 , hn) iesy C a gh 0 2 C ia t 1 0
t se h o g n e p rm e t e t dtr u h a x e i n. ; e e b r — r u r tag rt m h b i e r i gag rt h K e w o ds T S fz ym o e ; y r : - u z d lRBF lv n e g ma q a d l o ih ; y rdla n n lo i m
的前提下 ,可以使 用神经 网络 的 自学习能 力优化 T S — 模糊模型的参 数。T S型模糊 R F — B 神经 网络 即是 T S — 型模 糊神经网络 中的一种 ,因其训练 便捷 易行、收敛 速 度快 ,而且容易避免局部极小点 ,所 以表现 出极 大 的魅力。虽然如此 ,找 到一种 简单且实用的 T S型模 — 糊 R F神经网络的训练算 法并不容 易 ,文献【 6 B I 3】 — 在这
Ab t a t sr c :
To mp o t e f ce  ̄ i r ve h e in i
o tanig h T S fz y f r i n t e - u z mo e b s d d l a e RBF e r l ewo k t e n u a n t r , h
1 引言
1 8 年 T k g和 S g n 5 9 a a i u e o提出 了一种分段 线性 模糊模型, T k g- u e oT S模型【 I因为 它能 即 a a iS g n ( — ) 1 】 够使 用较少 的模 糊规 则 为一 个复 杂的 非线性 对 象建 模 ,所 以得到 的数学模 型比一般模糊模型更为简洁 , 因而更加有利于数学分析 ,所 q adtag rt m o h ri i g o e T- u z d lb s d RBF ne r ln t r r v n e g M r u r lo i h f rt e tan n ft S f z y mo e a e h u a e wo k a e
1. Levenberg-Marquardt方法
A x k k I
正定(适当调整 ), 从而(7)产生的方向
z 是下降方向.
这种方法是由 Levenberg(1944)和 Marqurdt(1963)提出的, 称为 Levenberg-Marqurdt method. 简称 L-M 方法.
1. Gauss Newton法的迭代中,当B AT ( x ) A( x )为奇异或 条件数 ( B 1 B )接近于1时,迭代无法继续!
当 足够大时,总可以保证 A x A x I 是正定的,从
T
而保证其可逆. 算法的每次迭代都对 进行自适应调整. 权值调整类似于高斯-牛顿法, 当接近解时, 逐渐减小, 利用类似于二阶导数的信息,可以快速收敛到最优解. 权重调整又类似于梯度下降法, 当远离解时, 逐渐增大, 可以进行全局搜索.所以 LM 算法同时具备了牛顿法和梯度 法的优点,但计算 A x 要占用较多的内存.
所以
d k H k1 S ( x k ) x k 1 x k H k1 S ( x k )
( 5) ( 6)
(6) 式称为Gauss Newton公式,
(5)式称为Gauss Newton方向。
S ( x k ) T 令 gk AT ( x k ) f ( x k ) Ak f ( x k )。 2
Step4 : 令 x k 1 x k t k d k , 其中t k : min f ( x k td k )。
t
Step5 : 若 || Ak f ( x k ) || , 则x * x k 1 , 算法结束; 否则,
T
k : k 1, 转Step2。
Gauss-Newton 法的优缺点: 优点: (1) 对于零残量问题(即 f ( x ) 0 ),有局部二阶收敛速度. (2) 对于小残量问题 ( 即 f ( x) 较小 , 或者接近于线性 ), 有快的 局部收敛速度. (3) 对于线性最小二乘问题, 一步达到极小点. 缺点: (1) 对于不是很严重的大残量问题, 有较慢的收敛速度. (2) 对于残量很大的问题或者 f ( x) 的非线性程度很大的问 题,不收敛. (3) 如果 A( x ) 不满秩, 方法没有定义. (4) 不一定总体收敛.
神经网络的Levenberg-Marquardt算法研究
神经网络的Levenberg-Marquardt算法研究摘要:本文主要介绍LM(Levenberg-Marquardt)神经网络算法,LM算法是梯度下降法和高斯—牛顿法的结合,这种神经网络算法综合了这两种方法的优点,在一定程度上克服了基本的BP网络收敛速度慢和容易陷入局部最小点等问题。
对LM算法的计算步骤作了简要的阐述。
最后介绍了LM神经网络算法再监督控制上的应用。
关键词:神经网络;LM算法;计算步骤;监督控制0 引言神经网络BP学习算法在理论上具有逼近任意非线性连续映射的能力,在非线性系统的建模及控制领域里有着广泛的应用。
然而BP 算法存在一些不足,主要是收敛速度很慢;往往收敛于局部极小点;数值稳定性差,学习率、动量项系数和初始权值等参数难以调整,非线性神经网络学习算法LM可以有效地克服BP算法所存在的这些缺陷[1]。
LM算法是高斯—牛顿法和最速下降法的结合,具有高斯—牛顿法的局部收敛性和梯度下降法的全局特性。
它通过自适应调整阻尼因子来达到收敛特性,具有更高的迭代收敛速度,在很多非线性优化问题中得到了稳定可靠解。
在LM算法的计算过程中,初值是一个很重要的因素。
若选择的初值X0接近真值时,收敛速度很快且能够得到全局最优解,但如果初值远离真解时,优化结果往往过早的陷入局部最优解从而得到的结果完全背离真解。
要解决该问题,一是通过得到大量的原始信息来对真值有一个较准确的估计,但这在实际问题中往往不太可能达到;另外就是选择一种合理的全局最优化算法与其相结合,消除LM算法对初值的依赖且具有很快的收敛速度[2]。
1 神经网络神经网络具有高度的自学习、自组织和自适应能力,能通过学习和训练获取网络的权值和结构。
多层前向神经网络具有理论上可逼近任意非线性连续映射的能力,因而非常适合于非线性系统的建模及控制,是目前使用较多的一种神经网络模型[3]。
BP网络(Back Propagation Network)称为误差反向传播神经网络,它是一种能朝着满足给定的输入/输出关系方向进行自组织的神经网络,其典型的结构图如图1所示,由三部分组成:输入层、隐含层、输出层,三部分之间通过各层节点之间的连接权依次前向连接。
基于神经网络的短期土壤墒情预测模型研究
土 壤 墒 情 是 指 土 壤 的 湿 度 ,即 土 壤 的 水 分 状
况。土壤失墒和过墒都会严重影响农作物生长[1]。
比如春旱失墒会使小麦春生分蘖减少、单位面积总
1 数据来源与数据处理
1.1 数据来源
穗数减少,从而影响产量;夏涝足墒或排水迟缓会
研究区域为天津市,
该地区主要气候特征是四季
使玉米等农作物长时间浸泡,致使根腐败,作物死
96. 64%。研究认为,Elman 神经网络具有稳定性好、精度高的特点;理论认为,含天气预报的模型精度比不含天气
预报的模型精度高,BP 神经网络表现出这一相关性,而 Elman 神经网络并没有表现出这一相关性。
关键词:土壤墒情;BP 神经网络;Elman 神经网络;短期预测
中图分类号:S24
文献标志码:A
性[6]。Elman 神经网络的拓扑结构如图 2 所示[7]。
(t
)
o
1
输出层
(t
)
o
q
(t
)
j
h
本研究模型训练应用的是 Matlab 神经网络工
(t
)
L
h
h
1
时
间
延
迟
L
ωi,j
ωj,k
1
L
1
时
间
延
迟
(t
)
u
i
(t
)
uL
(t
)
c
1
(t
)
c
k
比例分为训练集、验证集和测试集进行模型训练。
各模型的隐藏层节点数量和步长均通过试算确定,
L
wj,q
隐含层
算法,但由于训练数据量大,该算法占用内存高,导
基于Levenberg-Marquardt训练算法的BP网络Python实现
基于Levenberg-Marquardt训练算法的BP⽹络Python实现经过⼀个多⽉的努⼒,终于完成了BP⽹络,参考的资料为:1、Training feed-forward networks with the Marquardt algorithm2、The Levenberg-Marquardt method for nonlinear least squares curve-fitting problems3、Neural Network Design4、/wiki/index.php/UFLDL%E6%95%99%E7%A8%8B 中介绍的神经⽹络部分以下给出Python脚本:import numpy as npfrom math import exp, powfrom mpl_toolkits.mplot3d import Axes3Dimport matplotlib.pyplot as pltimport sysimport copyfrom scipy.linalg import norm, pinvclass Layer:def __init__(self,w, b, neure_number, transfer_function, layer_index):self.transfer_function = transfer_functionself.neure_number = neure_numberyer_index = layer_indexself.w = wself.b = bclass NetStruct:def __init__(self, x, y, hidden_layers, activ_fun_list, performance_function = 'mse'):if len(hidden_layers) == len(activ_fun_list):activ_fun_list.append('line')self.active_fun_list = activ_fun_listself.performance_function = performance_functionx = np.array(x)y = np.array(y)if(x.shape[1] != y.shape[1]):print 'The dimension of x and y are not same.'sys.exit()self.x = xself.y = yinput_eles = self.x.shape[0]output_eles = self.y.shape[0]tmp = []tmp.append(input_eles)tmp.extend(hidden_layers)tmp.append(output_eles)self.hidden_layers = np.array(tmp)yer_num = len(self.hidden_layers)yers = []for i in range(0, len(self.hidden_layers)):if i == 0:yers.append(Layer([],[],\self.hidden_layers[i], 'none', i))continuef = self.hidden_layers[i - 1]s = self.hidden_layers[i]yers.append(Layer(np.random.randn(s, f),np.random.randn(s, 1),\self.hidden_layers[i], activ_fun_list[i-1], i))class Train:def __init__(self, net_struct, mu = 1e-3, beta = 10, iteration = 100, tol = 0.1):_struct = net_structself.mu = muself.beta = betaself.iteration = iterationself.tol = toldef train(self, method = 'lm'):if(method == 'lm'):self.lm()def sim(self, x):_struct.x = xself.forward()layer_num = len(_yers)predict = _yers[layer_num - 1].output_valreturn predictdef actFun(self, z, activ_type = 'sigm'):if activ_type == 'sigm':f = 1.0 / (1.0 + np.exp(-z))elif activ_type == 'tanh':f = (np.exp(z) + np.exp(-z)) / (np.exp(z) + np.exp(-z))elif activ_type == 'radb':f = np.exp(-z * z)elif activ_type == 'line':f = zreturn fdef actFunGrad(self, z, activ_type = 'sigm'):if activ_type == 'sigm':grad = self.actFun(z, activ_type) * (1.0 - self.actFun(z, activ_type))elif activ_type == 'tanh':grad = 1.0 - self.actFun(z, activ_type) * self.actFun(z, activ_type)elif activ_type == 'radb':grad = -2.0 * z * self.actFun(z, activ_type)elif activ_type == 'line':m = z.shape[0]n = z.shape[1]grad = np.ones((m, n))return graddef forward(self):layer_num = len(_yers)for i in range(0, layer_num):if i == 0:curr_layer = _yers[i]curr_layer.input_val = _struct.xcurr_layer.output_val = _struct.xcontinuebefore_layer = _yers[i - 1]curr_layer = _yers[i]curr_layer.input_val = curr_layer.w.dot(before_layer.output_val) + curr_layer.bcurr_layer.output_val = self.actFun(curr_layer.input_val,_struct.active_fun_list[i - 1])def backward(self):layer_num = len(_yers)last_layer = _yers[layer_num - 1]last_layer.error = -self.actFunGrad(last_layer.input_val,_struct.active_fun_list[layer_num - 2])layer_index = range(1, layer_num - 1)layer_index.reverse()for i in layer_index:curr_layer = _yers[i]curr_layer.error = (last_layer.w.transpose().dot(last_layer.error)) \* self.actFunGrad(curr_layer.input_val,_struct.active_fun_list[i - 1])last_layer = curr_layerdef parDeriv(self):layer_num = len(_yers)for i in range(1, layer_num):befor_layer = _yers[i - 1]befor_input_val = befor_layer.output_val.transpose()curr_layer = _yers[i]curr_error = curr_layer.errorcurr_error = curr_error.reshape(curr_error.shape[0]*curr_error.shape[1], 1, order='F')row = curr_error.shape[0]col = befor_input_val.shape[1]a = np.zeros((row, col))num = befor_input_val.shape[0]neure_number = curr_layer.neure_numberfor i in range(0, num):a[neure_number*i:neure_number*i + neure_number,:] = \np.repeat([befor_input_val[i,:]],neure_number,axis = 0)tmp_w_par_deriv = curr_error * acurr_layer.w_par_deriv = np.zeros((num, befor_layer.neure_number * curr_layer.neure_number)) for i in range(0, num):tmp = tmp_w_par_deriv[neure_number*i:neure_number*i + neure_number,:]tmp = tmp.reshape(tmp.shape[0] * tmp.shape[1], order='C')curr_layer.w_par_deriv[i, :] = tmpcurr_layer.b_par_deriv = curr_layer.error.transpose()def jacobian(self):layers = _struct.hidden_layersrow = _struct.x.shape[1]col = 0for i in range(0, len(layers) - 1):col = col + layers[i] * layers[i + 1] + layers[i + 1]j = np.zeros((row, col))layer_num = len(_yers)index = 0for i in range(1, layer_num):curr_layer = _yers[i]w_col = curr_layer.w_par_deriv.shape[1]b_col = curr_layer.b_par_deriv.shape[1]j[:, index : index + w_col] = curr_layer.w_par_derivindex = index + w_colj[:, index : index + b_col] = curr_layer.b_par_derivindex = index + b_colreturn jdef gradCheck(self):W1 = _yers[1].wb1 = _yers[1].bn = _yers[1].neure_numberW2 = _yers[2].wb2 = _yers[2].bx = _struct.xp = []p.extend(W1.reshape(1,W1.shape[0]*W1.shape[1],order = 'C')[0])p.extend(b1.reshape(1,b1.shape[0]*b1.shape[1],order = 'C')[0])p.extend(W2.reshape(1,W2.shape[0]*W2.shape[1],order = 'C')[0])p.extend(b2.reshape(1,b2.shape[0]*b2.shape[1],order = 'C')[0])old_p = pjac = []for i in range(0, x.shape[1]):xi = np.array([x[:,i]])xi = xi.transpose()ji = []for j in range(0, len(p)):W1 = np.array(p[0:2*n]).reshape(n,2,order='C')b1 = np.array(p[2*n:2*n+n]).reshape(n,1,order='C')W2 = np.array(p[3*n:4*n]).reshape(1,n,order='C')b2 = np.array(p[4*n:4*n+1]).reshape(1,1,order='C')z2 = W1.dot(xi) + b1a2 = self.actFun(z2)z3 = W2.dot(a2) + b2h1 = self.actFun(z3)p[j] = p[j] + 0.00001W1 = np.array(p[0:2*n]).reshape(n,2,order='C')b1 = np.array(p[2*n:2*n+n]).reshape(n,1,order='C')W2 = np.array(p[3*n:4*n]).reshape(1,n,order='C')b2 = np.array(p[4*n:4*n+1]).reshape(1,1,order='C')z2 = W1.dot(xi) + b1a2 = self.actFun(z2)z3 = W2.dot(a2) + b2h = self.actFun(z3)g = (h[0][0]-h1[0][0])/0.00001ji.append(g)jac.append(ji)p = old_preturn jacdef jjje(self):layer_number = _yer_nume = _struct.y - \_yers[layer_number - 1].output_vale = e.transpose()j = self.jacobian()#check gradient#j1 = -np.array(self.gradCheck())#jk = j.reshape(1,j.shape[0]*j.shape[1])#jk1 = j1.reshape(1,j1.shape[0]*j1.shape[1])#plt.plot(jk[0])#plt.plot(jk1[0],'.')#plt.show()jj = j.transpose().dot(j)je = -j.transpose().dot(e)return[jj, je]def lm(self):mu = self.mubeta = self.betaiteration = self.iterationtol = self.toly = _struct.yself.forward()pred = _yers[_yer_num - 1].output_val pref = self.perfermance(y, pred)for i in range(0, iteration):print 'iter:',i, 'error:', pref#1) step 1:if(pref < tol):break#2) step 2:self.backward()self.parDeriv()[jj, je] = self.jjje()while(1):#3) step 3:A = jj + mu * np.diag(np.ones(jj.shape[0]))delta_w_b = pinv(A).dot(je)#4) step 4:old_net_struct = copy.deepcopy(_struct)self.updataNetStruct(delta_w_b)self.forward()pred1 = _yers[_yer_num - 1].output_valpref1 = self.perfermance(y, pred1)if (pref1 < pref):mu = mu / betapref = pref1breakmu = mu * beta_struct = copy.deepcopy(old_net_struct)def updataNetStruct(self, delta_w_b):layer_number = _yer_numindex = 0for i in range(1, layer_number):before_layer = _yers[i - 1]curr_layer = _yers[i]w_num = before_layer.neure_number * curr_layer.neure_numberb_num = curr_layer.neure_numberw = delta_w_b[index : index + w_num]w = w.reshape(curr_layer.neure_number, before_layer.neure_number, order='C') index = index + w_numb = delta_w_b[index : index + b_num]index = index + b_numcurr_layer.w += wcurr_layer.b += bdef perfermance(self, y, pred):error = y - predreturn norm(error) / len(y)def plotSamples(self, n = 40):x = np.array([np.linspace(0, 3, n)])x = x.repeat(n, axis = 0)y = x.transpose()z = np.zeros((n, n))for i in range(0, x.shape[0]):for j in range(0, x.shape[1]):z[i][j] = self.sampleFun(x[i][j], y[i][j])fig = plt.figure()ax = fig.gca(projection='3d')surf = ax.plot_surface(x, y, z, cmap='autumn', cstride=2, rstride=2)ax.set_xlabel("X-Label")ax.set_ylabel("Y-Label")ax.set_zlabel("Z-Label")plt.show()def sinSamples(n):x = np.array([np.linspace(-0.5, 0.5, n)])#x = x.repeat(n, axis = 0)y = x + 0.2z = np.zeros((n, 1))for i in range(0, x.shape[1]):z[i] = np.sin(x[0][i] * y[0][i])X = np.zeros((n, 2))n = 0for xi, yi in zip(x.transpose(), y.transpose()):X[n][0] = xiX[n][1] = yin = n + 1return X,zdef peaksSamples(n):x = np.array([np.linspace(-3, 3, n)])x = x.repeat(n, axis = 0)y = x.transpose()z = np.zeros((n, n))for i in range(0, x.shape[0]):for j in range(0, x.shape[1]):z[i][j] = sampleFun(x[i][j], y[i][j])X = np.zeros((n*n, 2))x_list = x.reshape(n*n,1 )y_list = y.reshape(n*n,1)z_list = z.reshape(n*n,1)n = 0for xi, yi in zip(x_list, y_list):X[n][0] = xiX[n][1] = yin = n + 1return X,z_list.transpose()def sampleFun(x, y):z = 3*pow((1-x),2) * exp(-(pow(x,2)) - pow((y+1),2)) \- 10*(x/5 - pow(x, 3) - pow(y, 5)) * exp(-pow(x, 2) - pow(y, 2)) \- 1/3*exp(-pow((x+1), 2) - pow(y, 2))return zif __name__ == '__main__':hidden_layers = [10,10] #设置⽹络层数,共两层,每层10个神经元activ_fun_list = ['sigm','sigm']#设置隐层的激活函数类型,可以设置为tanh,radb,tanh,line类型,如果不显式的设置最后⼀层为line[X, z] = peaksSamples(20) #产⽣训练数据点X = X.transpose()bp = NetStruct(X, z, hidden_layers, activ_fun_list) #初始化⽹络信息tr = Train(bp) #初始化训练⽹络的类tr.train() #训练[XX, z0] = peaksSamples(40) #产⽣测试数据XX = XX.transpose()z1 = tr.sim(XX) #⽤训练好的神经⽹络预测数据,z1为预测结果fig = plt.figure()ax = fig.add_subplot(111)ax.plot(z0[0]) #真值ax.plot(z1[0],'r.') #预测值plt.legend((r'real data', r'predict data'))plt.show()以上代码计算的结果如下图,由于初始值等原因的影响偶尔收敛效果会变差,不过⼤多数时候都可以收敛到下图的结果,以后再改进,欢迎指正。
