迭代求解最优化问题——梯度下降、牛顿法
2017-10-17 03:45
441 查看
最优化问题
最优化问题的一般表述是minxf(x)
其中f(x)称为损失函数。如前面所提到的,对于最优化问题,我们往往需要通过迭代的方法来进行求解。
迭代求解最优化问题一般包括5个步骤:
确定损失函数f(x)
确定初值x0
确定每次迭代的增量d
进行一次迭代xk+1=xk+αd,其中α控制迭代速率
判断是否收敛或达到最大迭代次数,若没有,返回第二步。
常用的迭代方法有梯度下降法,牛顿法,和它们的变种高斯牛顿法、L-M算法。
梯度下降法
梯度下降法直观的表述如图。图中心代表最低点。梯度下降法的主要思想就是每次朝着与当前梯度相反的方向前进一段距离。
它的迭代过程可以表示为xk+1=xk−α∇f(xk)
牛顿法
牛顿法在梯度下降法的基础上考虑了函数的二阶导数,从而更容易收敛。牛顿法一开始是用来求函数零点的,对函数f(x)做泰勒展开,有
f(x)=f(x0)+f′(x0)(x−x0)
令f(x) = 0,有x=x0−f(x0)f′(x0)
于是通过xk+1=xk−f(x0)f′(x0)我们可以向函数零点迭代。
事实上使用牛顿法迭代求解极值也是一个求函数零点的过程,只不过是求函数导数的零点,即对
f(x)=f(x0)+f′(x0)(x−x0)+12f″(x0)(x−x0)2
求导得到
f′(x)=f′(x0)+f″(x0)(x−x0)
令它等于0有
x=x0−f′(x0)f″(x0)
令d=−f′(x0)f″(x0)我们可以迭代求解函数最小值
对于多元函数使用同样的过程我们可以得到
d=−H−1f∇f,其中Hf为f(x)的hessian矩阵
附录:迭代求解的一个例子
#include <iostream> #include <math.h> #include <functional> using namespace std; double NumbericDerivate(std::function<double(double)> f,double x) { const double d = 1e-5; return (f(x+d)-f(x-d))/(2*d); } double Numberic2ndDerivate(std::function<double(double)> f,double x) { const double d = 1e-5; return (f(x+d)-2*f(x)+f(x-d))/(d*d); } double NewtonMethod(function<double(double)> f,double therold) { double x = 0; const int maxiter = 50; for(int i=0;i<maxiter;i++) { auto fx = f(x); auto fx1 = NumbericDerivate(f,x); auto delta = -fx/fx1; x = x + delta; if(fabs(delta)<therold) break; } return x; } double NewtonIter(function<double(double)> f,double therold) { double x = 0; const int maxiter = 40; for(int i=0;i<maxiter;i++) { auto fx = f(x); auto fx1 = NumbericDerivate(f,x); auto fx2 = Numberic2ndDerivate(f,x); auto delta = -fx1/fx2; x = x + delta; if(fabs(delta)<therold) break; } return x; } double GradDecent(function<double(double)> f,double therold,double lr = 0.1) { double x = 0; const int maxiter = 100; for(int i=0;i<maxiter;i++) { auto fx = f(x); auto fx1 = NumbericDerivate(f,x); auto delta = -fx1; x = x + lr * delta; if(fabs(delta)<therold) break; } return x; } int main() { //say we'll derivate function f(x) = x^2+sinx; auto result = NumbericDerivate([](double x){return x*x*sin(x)+sin(x);},3.14); cout<<result<<endl; result = NewtonMethod([](double x){return x*x*x+sin(x)+0.1;},0.01); cout<<result<<endl; result = Numberic2ndDerivate([](double x){return x*x*x;},1); cout<<result<<endl; result = NewtonIter([](double x){return x*(x+2)+3*x+1+exp(x);},0.001); cout<<result<<endl; result = GradDecent([](double x){return x*(x+2)+3*x+1+exp(x);},0.001); cout<<result<<endl; return 0; }
相关文章推荐
- 最优化问题中,牛顿法为什么比梯度下降法求解需要的迭代次数更少?
- 使用梯度下降与牛顿法求解最小平方和问题
- 常见的几种最优化方法(梯度下降法、牛顿法、拟牛顿法、共轭梯度法等)
- 最优化计算中:梯度下降法和牛顿法,共轭梯度法的基础分析
- 机器学习通俗入门-使用梯度下降法求解二分问题
- 梯度下降法求解线性回归问题
- 梯度下降法 求解回归问题
- 迭代求解最优化问题——Levenberg-Marquardt算法
- 迭代求解最优化问题——步长确定
- Proximal Gradient Descent for L1 Regularization(近端梯度下降求解L1正则化问题)
- 迭代求解最优化问题——信赖域方法
- 【机器学习详解】解无约束优化问题:梯度下降、牛顿法、拟牛顿法
- 最优化问题-梯度下降(Gradient Descent)算法&样例代码以及相关扩展
- 梯度下降法和牛顿法原理
- 梯度下降、牛顿法、拟牛顿法比较
- 梯度下降求解逻辑回归
- [最优化算法] 梯度下降
- 约束最优化问题求解:拉格朗日乘子法和KKT条件
- 最优化 梯度下降
- 机器学习实战——梯度下降求解逻辑回归(1理论基础)