使用 Eigen 的 Levenberg-Marquardt 的参数边界
Parameter boundaries using Eigen's Levenberg-Marquardt
我正在使用 Eigen 的 Levenberg-Marquardt 实现,想知道如何在应该优化的参数上设置一些边界。
当我将一些 GNU octave 程序迁移到 Eigen 时,我预计可能会有一些边界可以很容易地作为参数提供给模块。
我的实现布局与 this example 中的几乎相同。
我没有提供 df() 实现,而是使用 Eigen::NumericalDiff 来近似它。
那么如何对提供给 minimize() 的参数强制执行一些边界?
当离开我的预期范围时,我考虑过将 operator() 中的错误(fvec)设置为一些高值,但在一些小测试中,这导致了奇怪的结果。
我找到了一个至少对我有用的解决方案。
我们的想法是一旦参数离开它们的健全边界就增加误差向量。
这可以通过以下函数实现:
penalize(x1, x2) = 1 + (exp(x1-x1max)*b1) + exp((x1min-x1)*b1) + exp((x2-x2max)*b2) + exp((x2min-x2)*b2)
b1/b2/... 必须根据边界进行选择。在我的例子中,我从 b1=0.1 开始,范围为 1600...3200。
函数可以方便的扩展到参数的使用量。
像这样使用函数:
int operator(x, fvec) const
{
fvec(i) = ... * penalize(x(1), x(2))
}
我正在使用 Eigen 的 Levenberg-Marquardt 实现,想知道如何在应该优化的参数上设置一些边界。
当我将一些 GNU octave 程序迁移到 Eigen 时,我预计可能会有一些边界可以很容易地作为参数提供给模块。
我的实现布局与 this example 中的几乎相同。 我没有提供 df() 实现,而是使用 Eigen::NumericalDiff 来近似它。
那么如何对提供给 minimize() 的参数强制执行一些边界? 当离开我的预期范围时,我考虑过将 operator() 中的错误(fvec)设置为一些高值,但在一些小测试中,这导致了奇怪的结果。
我找到了一个至少对我有用的解决方案。
我们的想法是一旦参数离开它们的健全边界就增加误差向量。
这可以通过以下函数实现:
penalize(x1, x2) = 1 + (exp(x1-x1max)*b1) + exp((x1min-x1)*b1) + exp((x2-x2max)*b2) + exp((x2min-x2)*b2)
b1/b2/... 必须根据边界进行选择。在我的例子中,我从 b1=0.1 开始,范围为 1600...3200。 函数可以方便的扩展到参数的使用量。
像这样使用函数:
int operator(x, fvec) const
{
fvec(i) = ... * penalize(x(1), x(2))
}