迭代求解最优化问题——梯度下降、牛顿法

最优化问题

最优化问题的一般表述是
min ⁡ x f ( x ) \min\limits_x f(x) xminf(x)
其中f(x)称为损失函数。如前面所提到的,对于最优化问题,我们往往需要通过迭代的方法来进行求解。

迭代求解最优化问题一般包括5个步骤:

  1. 确定损失函数f(x)
  2. 确定初值 x 0 x_0 x0
  3. 确定每次迭代的增量 d d d
  4. 进行一次迭代 x k + 1 = x k + α d x_{k+1} = x_k + \alpha d xk+1=xk+αd,其中 α \alpha α控制迭代速率
  5. 判断是否收敛或达到最大迭代次数,若没有,返回第二步。

常用的迭代方法有梯度下降法,牛顿法,和它们的变种高斯牛顿法、L-M算法。

梯度下降法

在这里插入图片描述

梯度下降法直观的表述如图。图中心代表最低点。梯度下降法的主要思想就是每次朝着与当前梯度相反的方向前进一段距离。

它的迭代过程可以表示为 x k + 1 = x k − α ∇ f ( x k ) x_{k+1} = x_k-\alpha\nabla f(x_k) xk+1=xkαf(xk)

牛顿法

牛顿法在梯度下降法的基础上考虑了函数的二阶导数,从而更容易收敛。

牛顿法一开始是用来求函数零点的,对函数f(x)做泰勒展开,有
f ( x ) = f ( x 0 ) + f ′ ( x 0 ) ( x − x 0 ) f(x) = f(x_0)+f'(x_0)(x-x_0) f(x)=f(x0)+f(x0)(xx0)

令f(x) = 0,有 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 k + 1 = x k − f ( x k ) f ′ ( x k ) x_{k+1} = x_k - \frac{f(x_k)}{f'(x_k)} xk+1=xkf(xk)f(xk)我们可以向函数零点迭代。

事实上使用牛顿法迭代求解极值也是一个求函数零点的过程,只不过是求函数导数的零点,即对
f ( x ) = f ( x 0 ) + f ′ ( x 0 ) ( x − x 0 ) + 1 2 f ′ ′ ( x 0 ) ( x − x 0 ) 2 f(x) = f(x_0) + f'(x_0)(x-x_0)+\frac{1}{2}f''(x_0)(x-x_0)^2 f(x)=f(x0)+f(x0)(xx0)+21f(x0)(xx0)2
求导得到
f ′ ( x ) = f ′ ( x 0 ) + f ′ ′ ( x 0 ) ( x − x 0 ) f'(x) = f'(x_0)+f''(x_0)(x-x_0) f(x)=f(x0)+f(x0)(xx0)
令它等于0有
x = x 0 − f ′ ( x 0 ) f ′ ′ ( x 0 ) x=x_0-\frac{f'(x_0)}{f''(x_0)} x=x0f(x0)f(x0)

d = − f ′ ( x k ) f ′ ′ ( x k ) d = -\frac{f'(x_k)}{f''(x_k)} d=f(xk)f(xk)我们可以迭代求解函数最小值

对于多元函数使用同样的过程我们可以得到

d = − H f − 1 ∇ f d= -H_f^{-1}\nabla f d=Hf1f,其中 H f H_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;
}

  • 6
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
最优化是指在一定的约束条件下,寻找一个使目标函数取得最大值或最小值的过程。梯度下降法和牛顿法都是最优化问题中常用的方法。梯度下降法是一种迭代优化算法,通过计算目标函数的梯度来不断更新参数的值,直到达到某个停止条件。梯度下降法的思想是沿着目标函数梯度的反方向进行参数调整,以逐步接近最优解。它适用于凸函数和可微函数,并且可以用于求解无约束优化问题和约束优化问题的局部最优解。 牛顿法也是一种迭代优化算法,它利用函数的二阶导数信息(Hessian矩阵)来逼近函数的局部性质,从而更快地收敛到最优解。牛顿法求解方程根或函数的最小值时非常有效。它经常被用于数学建模、机器学习、数据分析等领域中的参数优化问题,比如最小二乘法、逻辑回归、神经网络等模型的参数优化。 需要注意的是,梯度下降法和牛顿法在不同情况下的效果可能会有所不同。梯度下降法在参数空间中沿着梯度方向逐步搜索最优解,对于大规模数据集和高维参数空间比较适用。而牛顿法利用了更多的二阶导数信息,对于曲率较大的函数,在局部区域更容易找到最优解。但是牛顿法在计算复杂度和存储空间上可能会有一定的挑战。因此,在实际应用中,我们需要根据具体问题的特点选择合适的优化方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值