以前牛顿法的印象就是Hessen矩阵,二阶导,今天忽然发现好像求平方根大家玩得是一阶导,后来仔细推导了一下发现一阶导 二阶导都是牛顿法,从泰勒展开说起
f(x)=f(xn)+f′(xn)(x−xn)+12f′′(xn)(x−xn)2
f(x)=f(x_n)+f'(x_n)(x-x_n)+\frac{1}{2}f''(x_n)(x-x_n)^2
f(x)=f(xn)+f′(xn)(x−xn)+21f′′(xn)(x−xn)2
如果忽略二阶导,令f(x)=0f(x)=0f(x)=0,这里f(x)=0f(x)=0f(x)=0表示切线不断和x轴相交,可以得到
x=xn−f(xn)f′(xn)(公式1)
x=x_n-\frac{f(x_n)}{f'(x_n)} (公式1)
x=xn−f′(xn)f(xn)(公式1)
如果不忽略二阶导,对两边求导,可以得到
f′(x)=f′(xn)+f′′(xn)(x−xn)
f'(x)=f'(x_n)+f''(x_n)(x-x_n)
f′(x)=f′(xn)+f′′(xn)(x−xn)
极值的位置f′(x)=0f'(x)=0f′(x)=0,所以可以得到
x=xn−f′(xn)f′′(xn)(公式2)
x=x_n-\frac{f'(x_n)}{f''(x_n)} (公式2)
x=xn−f′′(xn)f′(xn)(公式2)
公式1和公式2从xnx_nxn到xn+1x_{n+1}xn+1的时候都可以算牛顿法,公式1的典型应用就是求平方根或者其他数值计算,公式1在几何上的解释就是求切线,切线和x轴的交点再迭代。
例如求a\sqrt aa,令f(x)=x2−af(x)=x^2-af(x)=x2−a,那么迭代公式就是
xn+1=12(xn+axn)
x_{n+1}=\frac{1}{2}(x_n+\frac{a}{x_n})
xn+1=21(xn+xna)
写成code就是
// c++ code
double ans=1, pre=0;
while(abs(ans-pre)>1e-6){
pre=ans;
ans=(ans+x/ans)/2;
}
对于公式2,一般更关心它的高阶形式,也就是Hession矩阵上场
xn+1=xn−H−1g
x_{n+1}=x_n-H^{-1}g
xn+1=xn−H−1g
H−1H^{-1}H−1是Hession矩阵的逆,g是一阶导,这次就是玩二阶了
实际中的问题是Hession矩阵的逆比较难求,所以有Broyden,Fletcher,Goldfarb和Shanno四个人以自己首字母弄了一个BFGS算法,来近似的求H−1H^{-1}H−1,这种算法实用价值较大,因此又有人搞出了L-BFGS算法(Low内存版)