Levenberg_Marquardt神经网络算法研究_董一芬
- 格式:pdf
- 大小:111.02 KB
- 文档页数:1
第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迭代方法在非线性不适定问题上进行研究.在非线性算子和右端数据皆为近似的前提条件下,基于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.。
神经网络的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所示,由三部分组成:输入层、隐含层、输出层,三部分之间通过各层节点之间的连接权依次前向连接。
基于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()以上代码计算的结果如下图,由于初始值等原因的影响偶尔收敛效果会变差,不过⼤多数时候都可以收敛到下图的结果,以后再改进,欢迎指正。