线性搜索方法 (Line search method)

线性搜索方法(line search method)是数值优化里面最基础的一个内容,也是比较经典的方法,这里和大家分享一下一些基本的东西,至于原理部分,推荐大家看一下这篇文章里面的关于descent direction的推导:

https://www.jianshu.com/p/a239a39d06f7

  • 基本概念

对于一个无约束的最小值问题:

                                                                   x=min_{x \in R^n} f(x), f: R^n \rightarrow R

假定函数f是一个连续一阶可导的函数。

那么如果想要求这个函数的最小数值解,我们可以使用线性搜索算法达到目标。

 

给定一个初始值x0

计算梯度向量(方向)

其次,确定一个合适的步长\alpha >0 使得:

                                                                        f(x_k+\alpha p_k)<f(x_k)

对于步长的选取,可以采用定值,但是在复杂问题里面,常常是采用自适应的方法来调整步长的取值。

 

通用的线性搜索方法的更新表达式如下:

                                                               x_{k+1}:=x_k+\alpha_k p_k=x_k-\alpha_k \bigtriangledown f(x_k)

 

 

  • 实验仿真   

 

这里是线性搜索方法的比较合适的结果,我们可以看到最后,搜索是不断在收敛的,最后也找到了函数的最小值点,经过不断地迭代更新

 

线性搜索方法 (Line search method)_第1张图片

 主函数:

clc;clear


%% Use line search for findind the minimum of f

f=@(x)(x.^2-2.*x+0.28);

x_init=-150;
step=0.9;
iter=400;

[x_best,f_best,x_ind]=line_search(step,x_init,iter);


figure(1)
t=-200:1e-2:200;
plot(t,f(t))

hold on
scatter(x_init,f(x_init),'r','filled')

hold on
plot(x_ind,f(x_ind),'r')

hold on
scatter(x_best,f_best,'g','filled')

legend('objecitve function','start ponit','line search path','minimizer')
hold off
title('Funcion f')
xlabel('x')
ylabel('f')
print('line search path','-djpeg')

%% use a big stepsize for optimization

x_init=0;
step=1.1;
iter=27;
[x_best,f_best,x_ind]=line_search(step,x_init,iter);

figure(2)

t=-200:1e-2:200;
plot(t,f(t))

hold on
scatter(x_init,f(x_init),'k','filled')

hold on
plot(x_ind,f(x_ind),'r')

hold on
scatter(x_best,f_best,'g','filled')

legend('objecitve function','start point','line search path','minimizer')

hold off
title('Funcion f')
xlabel('x')
ylabel('f')
print('line search path with big step','-djpeg')

%% use differnet stepsize and check the convergece rate

step=[1e-1,1e-3,1e-5,1e-7];
x_init=-250;
epsilon=1e-20;

figure(3)
t=-300:0.1:200;
for i=1:size(step,2)
    
    [time,x_ind]=line_search_converge(step(i),x_init,epsilon);
    subplot(2,2,i)
    scatter(x_init,f(x_init),'k','filled');
    hold on
    plot(t,f(t),'b')
    hold on
    plot(x_ind,f(x_ind),'g')
    legend('start point','objecitve function','search path')
    title(['time: ',num2str(time),'s stepsize: ',num2str(step(i))])
    xlabel('x')
    ylabel('f')
    hold off
       
    
end





 

线性搜索算法:

function [x_best,f_best,x_ind]=line_search(step,x_init,iter)

f=@(x)(x.^2-2.*x+0.28);
step_size=step;
x0=x_init;
maxiter=iter;
grad_f=@(m)(2.*m-2);
x=x0;
x_ind=[];
x_ind=[x_ind;x0];

for i=1:maxiter
    
  
    grad=grad_f(x);
    x=x-step_size.*grad;
    x_ind=[x_ind;x];
end

fprintf('the minimizer is obtained at %.2f and the min value of f is %.2f \n',x,f(x))

fprintf('the analytic minimizer is at 1.00 and the min value of f is %.2f \n',f(1))

x_best=x;
f_best=f(x_best);

end

在选取步长时,如果选择地比较大的话,容易导致搜索的发散,导致我们无法找到最优解,但是如果步长选择的太小,那么也存在问题,我们搜索所花费的时间将会比较多,这里仿真的时间看起来步长,主要是因为这是一个简单任务,在实际生活中,我们涉及的很多问题,都很复杂,步长如果太小,所花费的时间将是昂贵的。下面展示了步长过大和步长取小的结果。

步长过大 

线性搜索方法 (Line search method)_第2张图片

选取不同步长,收敛所需要的时间比较:

线性搜索方法 (Line search method)_第3张图片

function [time,x_ind]=line_search_converge(step,x_init,epsilon)

f=@(x)(x.^2-2.*x+0.28);
step_size=step;
x0=x_init;

grad_f=@(m)(2.*m-2);

x=x0;
x_ind=[];
x_ind=[x_ind;x0];
tic;
for i=1:100000
    
    x1=x;
    grad=grad_f(x);
    x=x-step_size.*grad;
    x_ind=[x_ind;x];
    if abs(x1-x)

 

  •  总结

在使用线性搜索算法的时候,需要考虑的主要问题时步长的选取,初始值的初始化,以及更新公式的正确性,在涉及到较复杂的线性甚至时非线性问题时,后面会介绍一些自适应和高阶的方法。

你可能感兴趣的:(数值优化,Numerical,Optimization,机器学习,深度学习,算法,线性代数,pytorch)