牛顿-拉夫逊迭代法求解非线性优化问题


在《视觉slam十四讲》中提到的非线性优化问题,之前相关知识比较匮乏,在此记录一下。书中提到了高斯-牛顿法、马夸尔特-列文伯格法。这些非线性优化方法都是建立在牛顿法基础上的一个方法。牛顿法可以求方程的根以及求目标函数的极小值(优化问题)。

引1:牛顿法迭代求解方程

  • 首先我们引入牛顿法:
  • 例: 迭代法求函数

y = 3 x − 2 y=3^x-2 y=3x2
的根:
为了对比效果,先来画一下函数的图像。函数图像是这样的:
函数图像

  • 牛顿法的基本思路是:
  • 首先给定一个初值x0,然后在该处对函数进行一阶泰勒展开,用一阶泰勒展开式去拟合,即:

f ( x ) ≈ f ( x 0 ) + ( x − x 0 ) f ′ ( x 0 ) f(x)\approx f(x_{0})+(x-x_{0})f^{'}(x_{0}) f(x)f(x0)+(xx0)f(x0)
令:
f ( x ) = 0 f(x)=0 f(x)=0
即:
f ( x 0 ) + ( x − x 0 ) f ′ ( x 0 ) = 0 f(x_{0})+(x-x_{0})f^{'}(x_{0})=0 f(x0)+(xx0)f(x0)=0

  • 其中只有未知数x的一次项和0次项,是y=kx+b形式的方程,在几何上的表现为过x0点,函数的切线的方程。所以可以认为是用x0点处的切线方程拟合了非线性函数。将上述线性方程求解,得到:

x = x 0 − f ( x 0 ) f ′ ( x 0 ) x=x_{0}-\frac{f(x_{0})}{f^{'}(x_{0})} x=x0f(x0)f(x0)

  • 新得到的x要比x0更加接近方程的根,因此作为新的初值重复以上步骤n次,直到: f ( x n ) < ε f(x_{n})<\varepsilon f(xn)<ε这个值为容限误差(精度),就可以认为xn为该方程的解。

  • 在几何上的理解可能比较直观,过程为:
    1.过一点做切线
    2.根据切线找到与x轴的交点
    3.交点作为新的x0,找到该处的y0值,再在该点处做切线

  • python代码:

import matplotlib.pyplot as plt
import numpy as np
x=np.linspace(-5,5,1000)
y=[pow(3,i)-2 for i in x]

ax = plt.gca()  # get current axis 获得坐标轴对象
ax.spines['right'].set_color('none')  # 将右边 边沿线颜色设置为空 其实就相当于抹掉这条边
ax.spines['top'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.yaxis.set_ticks_position('left')
# 设置中心的为(0,0)的坐标轴
ax.spines['bottom'].set_position(('data', 0))  # 指定 data 设置的bottom(也就是指定的x轴)绑定到y轴的0这个点上
ax.spines['left'].set_position(('data', 0))
# plt.xticks(rotation=45)#x轴数值倾斜45度显示
plt.xlim(0, 4) #x轴数值设置
plt.ylim(0, 30)
#选初值x0=3
x0=3
#误差为0.01
ep=0.01
x0_list = []
fx0_list = []

for i in range(50):
    y0 = pow(3, x0)-2
    f_p = pow(3, x0)*np.log(3)
    x_solve = x0-y0/f_p
    plt.annotate('n='+str(i), xy=(x0+0.05, y0+0.05))
    #切点(x0,y0)
    x0_list.append(x0)
    fx0_list.append(y0)
    # 切线方程的解的点
    x0_list.append(x_solve)
    fx0_list.append(0)
    x0=x_solve

    plt.plot([x_solve, x_solve],[-10,15],color='blue',linestyle='--',linewidth=0.8)
    plt.plot(x0_list, fx0_list,'o')#画出(x0,f(x0),与解出来的(x,0))
    plt.plot(x0_list, fx0_list)#画切线(x0,f(x0),与解出来的(x,0))
    x0_list.clear()
    fx0_list.clear()
    print("第"+str(i)+"次迭代"+"f(x)="+str(y0)+"当前解为x="+str(x_solve))

    if(y0<ep and f_p>-ep):
        break
plt.plot(x,y,linewidth=1,color='black')
plt.show()

执行结果:
在这里插入图片描述
第0次迭代f(x)=25当前解为x=2.157185901271447
第1次迭代f(x)=8.696439617615772当前解为x=1.4171414794893509
第2次迭代f(x)=2.7440397665231444当前解为x=0.890642386345392
第3次迭代f(x)=0.6603845245503774当前解为x=0.6646946358018277
第4次迭代f(x)=0.07558220511108127当前解为x=0.6315483273792328
第5次迭代f(x)=0.001359607497144033当前解为x=0.6309299637068171
可见,当初值为3,时,算法迭代6次,算法就求出了方程的零点,x=0.6309

引2:牛顿法求解优化问题

  • 牛顿法同样可以用来求解优化问题,优化问题的任务是寻找目标函数的极值点。寻找极值点的方法就是求解一阶导数的极值点,即:

f ′ ( x ) = 0 f^{'}(x)=0 f(x)=0

  • 因此,我们只需要求导函数方程的零点,即为优化问题的解。
  • 类似地,我们将原函数在x0处进行泰勒展开,因为是求导函数(一阶)的零点,所以需要二阶泰勒展开:
    f ( x + Δ x ) = f ( x ) + f ′ ( x ) Δ x + 1 2 f ′ ′ ( x ) Δ x 2 f(x+\Delta x)=f(x)+f'(x)\Delta x+\frac{1}{2}f''(x)\Delta x^{2} f(x+Δx)=f(x)+f(x)Δx+21f(x)Δx2

    Δ x → 0 \Delta x\rightarrow 0 Δx0
    时:
    f ′ ′ ( x ) Δ x + f ′ ( x ) = 0 f''(x)\Delta x+f'(x)=0 f(x)Δx+f(x)=0
    可以求出迭代的增量为:
    Δ x = − f ′ ( x ) f ′ ′ ( x ) \Delta x=-\frac{f'(x)}{f''(x)} Δx=f(x)f(x)

牛顿法解多元函数最小二乘优化问题

在实际问题中,我们经常接触到的方程形式大多为多元方程。在一元函数中,函数的映射为:
f ( x ) → R f(x)\rightarrow R f(x)R
而在多元函数中,映射为:
f ( x → ) → R n f(\overrightarrow{x})\rightarrow R^{n} f(x )Rn

多元函数的二阶泰勒展开形式为:

在这里插入图片描述
多元函数的一阶导数为雅克比矩阵J,二阶导数为海森矩阵H。
当雅克比矩阵为0时,得到的迭代关系式为:
x k = x k − 1 − H ( x k − 1 ) − 1 ▽ f ( x k − 1 ) x_{k}=x_{k-1}-H(x_{k-1})^{-1}\triangledown f(x_{k-1}) xk=xk1H(xk1)1f(xk1)
这样就把一维的情形映射到高维空间中了。
matlab代码有空再补全吧~

  • 5
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值