java 二分搜索获得大于目标数的第一位_线搜索(一):步长的选取

从本文开始,我们来深入研究线搜索方法的具体细节,第一篇谈一谈步长的选取。

为什么谈步长呢?因为线搜索只有两步,确定方向、确定步长。确定方向的方法在上一篇文章略有提及,无非是最速下降法、牛顿法、拟牛顿法,但没有提到如何确定步长。所以本文先讲如何确定步长,至于上述几种方法的更多细节,我们后面再说。

步长的约束条件

确定步长最简单的方法,就是挨个试。从0开始,每隔一定距离计算一下目标函数的值,找出其中最小的那个,对应的步长就是我们要的结果。

显然,这种方法太过暴力,试的次数太多,很影响效率。我们可以试着排除一些明显不可能存在极小值的区域,请看下图

8699e4141369a8d8e08e9505869c4934.png

图中横轴为步长

,纵轴为对应步长的函数值
。虚线
是略微向下倾斜的直线,其斜率与初始位置的导数值成正比。显然,目标函数高于虚线的部分是不可能存在极小值的,以此将步长分为“可接受(acceptable)”的区域和“不可接受”的区域。用公式表示如下

其中,

是虚线斜率的放缩比例,一般取
,这意味着虚线
的下降速度远慢于目标函数初始阶段的下降速度,因而该约束限制的区域足以保证目标函数获得充分的下降,因此称为充分下降条件(sufficient decrease condition),又称Armijo condition。

Armijo condition这个约束太简单了,以至于任意小的步长

都可以满足该条件。为了保证每次迭代有充分的下降,我们可以考虑对目标函数的导数添加一项约束,请看下图

38951c7ee06fcfa65b30010add226512.png

此时的可接受区域排除掉了起始的一小段距离,因为这部分的导数比较大,目标函数处于快速下降的阶段,在这里停止就错失了快速收敛的机会。当目标函数趋于平缓后,出现极小值的概率增大,此时才是选取步长的最佳时机。用公式表示如下

其中,

是虚线desired slope斜率的放缩比例,一般取0.9(对于牛顿法和拟牛顿法)或0.1(对于非线性共轭梯度法)。该约束与曲线斜率有关,因此称为曲率条件(curvature condition)。

如果我们把两个条件结合起来用,把可接受区域取个交集,就得到了Wolfe conditions,如下图所示

45ee9d79a946a23fe324acd0b3e1b443.png

Wolfe conditions具有尺度不变性,当目标函数存在尺度缩放时,这些约束条件也会跟随函数值和梯度值的变化而变化,可接受区域的计算结果保持不变。

看起来似乎不错,但计算Wolfe conditions依赖于各个点的导数值,有些麻烦。能不能只靠目标函数值达到类似的效果呢?下面看看Goldstein conditions,这次先给出公式

其中

。这是两个不等式,左右分别对应斜率不同的直线,将可接受区域约束在这两条直线之间,如下图所示

82b6d71a117cbb223ea17ab1e2022de2.png

从图中可以发现,Goldstein conditions似乎不是那么靠谱,它竟然巧妙地避开了所有极小值点。不过不必担心,优化不在于这一次两次的得失,朝着下降的方向收敛即可。

步长搜索策略——回溯法

在满足以上约束条件的情况下,具体如何搜索呢?

先来介绍一个简单有效的方法,回溯法(backtracking)。回溯法既不采用Goldstein conditions,也不采用Wolfe conditions,而是只考虑充分下降条件。从步长为1开始,测试是否满足充分下降条件,如果满足则停止,否则将步长缩小,再次测试,直到满足充分下降条件为止。这种方法之所以可行,是因为充分下降条件在步长足够小时一定能够成立。实际使用中,大部分情况都可以在步长为1或者少量的迭代后停止,从而获得较大的函数值下降。

不过,事情总有例外,如果我们总是从步长为1开始,一定可以回溯到极小值吗?答案是否定的,在下一篇文章中,我们会发现牛顿法和拟牛顿法可以保证在步长为1时就能够收敛。而对于最速下降法和以后将会提到的共轭梯度法来说,步长为1是不行的,需要更复杂的策略来保证它们的收敛性。

步长搜索算法之完全版

现在,我们看看完整的步长搜索算法应该如何设计。回顾Wolfe conditions那张图,可以想象,无论什么样的目标函数,可接受的步长一定落在某个区间内,我们可以先确定一个足够大的区间,然后逐渐缩小它,直到找到可接受的步长。

如何确定一个足够大的区间,其实并不那么简单。实际上,如果我们知道充分下降条件代表的那条直线与目标函数的交点,该点就可以作为区间的右端点。但我们不知道,也没办法求,只能迭代尝试。最简单的迭代方法就是先从一个小的

开始,如果满足充分下降条件,就令
,其中
是大于1的常数,直到找到一个不满足充分下降条件的

接下来,我们需要逐渐缩小

这个区间。最简单的方法就是二分,直接取中值。但问题马上来了,二分之后,我们保留哪半边?换句话说,我们如何保证
内部存在一个满足Wolfe conditions的子区间?

让我们再直观地感受一下Wolfe conditions,它实际上规定了两件事情,一是函数值必须下降,二是只接受导数较平缓的区域。既然和导数大小有关,那么我们可以试着考虑二分点的导数值。如果二分点的导数值很小,直接满足Wolfe conditions,那就找到了可接受的步长。如果二分点的导数值很大,那么我们就选择与该点导数符号相反的那个端点,重新组成一个子区间。之所以选择符号相反的那个端点,是因为对于连续光滑的函数来说,两个斜率相反的点之间一定存在极值点,也就存在导数值很小的一段区域。按照这种策略,逐步缩小区间范围,直到某个二分点满足Wolfe conditions为止。

以上就是步长搜索算法的基本思想,但理论和实际总是有一些差距,这套流程实现起来还是比较复杂的,需要考虑很多情况。为了进一步加深大家的理解,下面给出算法主体部分的代码,并做进一步解释。

std

这段代码共有5个函数,前两个用来检查当前的步长是否满足充分下降条件和曲率条件,第三个函数用来从给定区间中选择一个步长,也就是我们在前面提到的二分操作(当然实际中可以使用更好的选择策略,在本文的最后会略有提及)。后两个函数则是步长搜索的核心策略。先看line_search,我们来解释一下while循环中的三个判断。第一个if表明找到了不满足充分下降条件的步长,因此该步长可以作为右边界,将找到的区间传递给zoom函数进行收缩。如果第一个if不成立,说明当前的步长已经满足充分下降条件,于是用第二个if判断是否满足曲率条件,如果也满足,那么就找到了可接受的步长,返回即可。如果第二个if也不成立,说明当前步长落在了斜率较大的区域,此时有两种可能,如果是接近初始点的区域,这一区域不是我们想要的,需要进一步放大步长。如果是远离初始点的区域,那么在初始点和当前点之间一定存在可接受的区域,直接调用zoom即可。因此,第3个if通过判断当前点的斜率,从而得知当前点处在初始点附近还是远离初始点。

zoom函数接受两个步长,分别是区间的两个端点。在line_search函数中,调用zoom时精心调整了两个参数的顺序,保证第一个参数满足充分下降条件且具有比第二个参数更小的函数值。在zoom中,每次循环都始终维持着alpha_low满足该条件,比如,在第一个if中,如果中间的步长alpha_j不满足充分下降条件或没有取得相对于alpha_low的下降,则alpha_low保持不变,把alpha_high更新为alpha_j。反之,如果满足充分下降条件且取得了相对于alpha_low的下降,则判断是否满足曲率条件,满足则结束,如果不满足,则要进一步缩小区间。此时,alpha_j已经成为了更好的步长,所以需要将alpha_low更新为alpha_j,同时考虑我们在前面提到的导数符号的一致性,保留alpha_low和alpha_high中导数符号与alpha_j不同的那个,将其作为新的alpha_high。如此下去,直到找到可接受的步长。

Choose from interval?

上面那段代码留了一个TODO,即choose_from函数。我们在两个地方用到了这一函数,一个是line_search中用来扩大步长,另一个是zoom中用来缩小区间范围。

前面提到过,最简单的实现方法是取区间的中值,相当于二分查找,这样做的效果应该不会太坏,但没有利用到更多的信息。一种更好的方法是插值,或者说拟合。当我们知道区间的两个端点和它们各自的函数值时,如果再知道其中一个端点的导数值,就可以拟合一条二次曲线,取该二次曲线的极小值点,作为新的步长,可能会比二分查找更好一些。如果再考虑上另一个端点的导数值,就可以拟合一条三次曲线,取该三次曲线的极小值点,作为新的步长,应该也不错。利用到的函数和导数信息越多,拟合的曲线就越接近原函数,但高于三次的曲线我们就不会求极值了,所以一般拟合二次或三次曲线即可。

结语

本文是线搜索方法的上篇,介绍了步长的约束条件以及两种步长搜索策略。在下篇文章中,我们转而关注不同的搜索方向,以最速下降法、牛顿法、拟牛顿法为代表,看看这些方法在收敛性和收敛速度方面的特点和差异。

上一篇:线搜索与信赖域
下一篇:线搜索(二):收敛性和收敛速度
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值