参数空间受约束时如何运行梯度下降算法?

时间:2010-06-29 02:23:36

标签: optimization math function gradient

我想用一个参数最大化功能

所以我运行渐变下降(或者,实际上升):我从一个初始参数开始并继续添加渐变(一些学习速率因子变得越来越小),在给定新参数的情况下重新评估渐变,以及等等直到收敛。

但是有一个问题:我的参数必须保持正面,因此它不应该变为< = 0,因为我的函数将是未定义的。我的渐变搜索有时会进入这样的区域(当它是正的时,渐变告诉它要低一些,并且它超过了)。

更糟糕的是,这一点的渐变可能是负面的,从而推动搜索更加负面的参数值。 (原因是目标函数包含日志,但梯度不包含。)

处理这种约束优化问题的一些好(简单)算法是什么?我希望只是对我的算法进行简单的修复。或者可以忽略渐变并进行某种线搜索以获得最佳参数?

7 个答案:

答案 0 :(得分:9)

  1. 每次更新参数时,请检查它是否为负数,如果是,则将其钳制为零。
  2. 如果无法接受钳制到零,请尝试添加“log-barrier”(Google it)。基本上,它为您的目标函数添加了一个平滑的“柔和”墙(并修改了渐变),使其远离您不希望它去的区域。然后,通过强化墙壁使其更加无限垂直,重复运行优化,但从先前找到的解决方案开始。在极限情况下(实际上只需要几次迭代),您解决的问题与硬约束的原始问题相同。

答案 1 :(得分:3)

在不了解您的问题的情况下,很难提出具体的建议。您的渐变上升算法可能不是特别适合您的函数空间。但是,鉴于这就是你所拥有的,这里有一个有用的调整。

您遵循的是您认为的升序渐变。但是当你向渐变方向前进时,你会发现你陷入了负值的陷阱。这意味着附近有一个局部最大值,但也有一个非常尖锐的负梯度悬崖。显而易见的解决方法是回溯到您之前的位置,并采取较小的步骤(例如一半大小)。如果你仍然堕入,重复一个更小的步骤。这将迭代,直到你找到悬崖边缘的局部最大值。

问题是,无法保证您的本地最大值实际上是全局的(除非您了解有关您的功能的更多信息而不是您所共享的)。这是天真梯度上升的主要限制 - 它始终固定在第一个局部最大值并收敛到它。如果您不想切换到更强大的算法,可以帮助的一个简单方法是运行代码的 n 迭代,每次从函数空间中的随机位置开始,并保持总体上找到的最大值。这种蒙特卡罗方法增加了您在全局最大值上绊倒的几率,但代价是将运行时间增加一个因子 n 。这有多高将取决于你的目标函数的“颠簸”。

答案 2 :(得分:3)

将参数限制为正的一个简单技巧是根据对数重新参数化问题(确保适当地更改梯度)。当然,这种转换可能会使最佳值变为非常大,并且搜索不会收敛。

答案 3 :(得分:2)

在每个步骤中,将参数约束为正数。这是(简而言之)您可能想要谷歌的投影渐变方法

答案 4 :(得分:2)

我有三个建议,按照你想做多少思考和工作。

首先,在渐变下降/上升中,每次按渐变时间移动一些因子,您将其称为“学习速率因子”。如果你正如你所描述的那样,这个移动导致x变为负数,那么有两种自然的解释:梯度太大,或者学习率因子太大。由于无法控制渐变,请采用第二种解释。检查您的移动是否会导致x变为负数,如果是,则将学习率因子减半,然后重试。

其次,要详细说明Aniko的答案,让x为你的参数,f(x)为你的函数。然后定义一个新函数g(x)= f(e ^ x),并注意虽然f的域是(0,无穷大),但g的域是(-infinity,infinity)。所以g不能忍受遭受的问题。使用梯度下降来找到最大化g的值x_0。然后e ^(x_0),即正,最大化f。要在g上应用梯度下降,您需要其衍生物,即链规则为f'(e ^ x)* e ^ x。

第三,听起来你正在尝试最大化一个函数,而不是编写一般的最大化例程。你可以考虑搁置梯度下降,并剪裁 对特定功能的特性进行优化的方法。我们必须更多地了解f的预期行为,以帮助您做到这一点。

答案 5 :(得分:1)

只需使用Brent's method for minimization即可。它是稳定和快速的,如果你只有一个参数,它是正确的事情。这是R函数optimize使用的内容。该链接还包含一个简单的C ++实现。是的,你可以给它MIN和MAX参数值限制。

答案 6 :(得分:0)

你在这里得到了很好的答案。重新参数化是我推荐的。另外,您考虑过其他搜索方法,例如Metropolis-Hastings吗?一旦你克服了可怕的数学运算,它实际上非常简单,它给你标准的错误和最佳。