目标识别与跟踪基础知识(一)

梯度下降法(Gradient descent)

1.梯度下降理解

直观些理解
可以用山的高度来解释,假设有一个人站在山上的某一点,他通过观察发现了一条“最陡”的路,那么这条路的方向就是梯度所指的方向。梯度是一个矢量,方向导数是一个标量,梯度所指向的方向是方向导数最大的方向,且梯度的模和方向导数的最大值相等。求梯度的方法很简单,对每一个自变量求偏导数,然后将其偏导数作为自变量方向的坐标即可。梯度的符号为∇,则函数f(x,y)的梯度为:
这里写图片描述
梯度下降法是一个最优化算法,通常也称为最速下降法。最速下降法是用负梯度方向为搜索方向的,最速下降法越接近目标值,步长越小,前进越慢,梯度下降法的计算过程就是沿梯度下降的方向求解极小值。

2.如何使用梯度下降法

以函数f(x)为例,先选择一个初始点,计算该点的梯度,然后按照梯度的方向更新自变量。若第k次迭代值为x(k),则
这里写图片描述
其中α称作步长或者学习率,表示自变量每次迭代变化的大小。一直按照上式更新自变量,直到当函数值变化非常小(如3%以内)或者达到最大迭代次数时停止,此时认为自变量更新到函数的极小值点。

3.梯度下降法求极值点示范

eg.求解下列函数在(0,0)(-1,-1)(-1,-2)(-2,-1)点对应的区域极值点,并输出函数值:
f=sin(y)*exp((1-cos(x))^2)+cos(x)*exp((1-sin(y))^2)+(x-y)^2;

1.matlab实现
gradient.m

clc;
syms x y;
f=func(x,y);
ezmesh(x,y,f,[-5,0],[-5,0]);
hold on;

step=0.001;
x0=0;y0=0;
i = 0;

while i<100000 && x0>-5 && x0<=0 && y0<=0 && y0>-5
   x0 = x0 - step*dfx(x0,y0);
   y0 = y0 - step*dfy(x0,y0);
   f = func(x0,y0);
   plot3(x0,y0,f,'.r');
   if dfx(x0,y0)<0.1&&dfy(x0,y0)<0.1
       break;
   end
   i = i+1;
end
function [ f ] = func( x,y )

f=sin(y).*exp((1-cos(x)).^2)+cos(x).*exp((1-sin(y)).^2)+(x-y).^2;

end
function [ dfx ] = dfx( x1,y1 )
syms x y;
f=func(x,y);
dfx=diff(f,x);
dfx=subs(dfx,x,x1);
dfx=subs(dfx,y,y1);
dfx=eval(dfx);
end
function [ dfy ] = dfy( x1,y1 )
syms x y;
f=func(x,y);
dfy=diff(f,y);
dfy=subs(dfy,x,x1);
dfy=subs(dfy,y,y1);
dfy=eval(dfy);
end

示意结果图
这里写图片描述
2.c/c++实现

#include<stdio.h>
#include<math.h>


double Func(double x, double y)
{
    double cosx = cos(x), siny = sin(y);
    double a = 1 - cosx, b = 1 - siny, c = x - y;
    return siny*exp(a*a) + cosx*exp(b*b) + c*c;
}


double Dfx(double x, double y)
{
    double dfx;
    dfx = 2*x - 2*y - exp((sin(y) - 1)*(sin(y) - 1))*sin(x) - 2*exp((cos(x) - 1)*(cos(x) - 1))*sin(x)*sin(y)*(cos(x) - 1);
    return dfx;
}

double Dfy(double x, double y)
{
    double dfy;
    dfy = 2*y - 2*x + exp((cos(x) - 1)*(cos(x) - 1))*cos(y) + 2*exp((sin(y) - 1)*(sin(y) - 1))*cos(x)*cos(y)*(sin(y) - 1);
    return dfy;
}

void main()
{   

    double x,y,f,i,step=0.001;
    double dfx, dfy;
    printf("请输入x y\n");
    scanf_s("%lf %lf", &x, &y);
    printf("x=%.3lf ,y=%.3lf \n",x,y);


    for (i = 0;i < 10000;i++)
    {
        dfx = Dfx(x, y);
        dfy = Dfy(x, y);
        if ((x > 0 || x < -5) && (y > 0 || y < -5))
            break;
        else if (dfx < 0.001&&dfy < 0.001)
            break;
        x = x - step*Dfx(x, y);
        y = y - step*Dfy(x, y);
        f = Func(x, y);


    }
    printf("i=%lf\n", i);
    printf("x=%.3lf y=%.3lf f=%.3lf\n",x,y,f);
}

运行
这里写图片描述


第一次写博客不足之处敬请谅解,期待您的建议与问题。

  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值