2

问题:我最近的任务是设计一个非线性求解器,但我的求解器没有收敛到正确的解决方案。

**预期**:'minimize(x)' 方法应该将我的参数向量 x 减少到最小值。

观察到:在我调用“minimize(x)”后,我得到一个状态返回,上面写着 RelativeErrorTooSmall。

问题:有人可以解释一下这个枚举值是什么意思吗?

文档:关于 Eigen Levenberg Marquardt 类的唯一可用文档基本上是它的 .h 文件。以下是枚举列表:

enum Status {
    NotStarted = -2,
    Running = -1,
    ImproperInputParameters = 0,
    RelativeReductionTooSmall = 1,
    RelativeErrorTooSmall = 2,
    RelativeErrorAndReductionTooSmall = 3,
    CosinusTooSmall = 4,
    TooManyFunctionEvaluation = 5,
    FtolTooSmall = 6,
    XtolTooSmall = 7,
    GtolTooSmall = 8,
    UserAsked = 9
};

这是头文件的链接: https ://eigen.tuxfamily.org/dox/unsupported/NonLinearOptimization_2LevenbergMarquardt_8h_source.html

这是之前的堆栈溢出问题,其中包含测试程序: 如何使用 Eigen 不受支持的 levenberg marquardt 实现?

4

1 回答 1

2

搜索 .h 文件可以发现,这个返回码意味着在某个步骤中算法无法声明成功,但在调整该步骤的参数方面进展甚微。

  if (delta <= parameters.xtol * xnorm)
        return LevenbergMarquardtSpace::RelativeErrorTooSmall;

术语xnorm由算法动态计算。它是对参数在某种绝对意义上趋于多大的估计。(将问题缩放到参数的绝对值趋向于统一是一种很好的做法。)Parameters.xtol是一个数字,用户可以将其设置为参数的“小”差异。一个典型值是机器效率的平方根。实际上,这是代码中的默认值。

假设库代码正确,收敛失败可能是由于以下任何原因:

  1. 对函数计算准确度的估计过于乐观。尝试将 Parameters.xtol 设置得更大一些。至少使用双精度。确保所有参数的比例大致相同。

  2. 这个问题不是很好的条件,这意味着 Hessian 在参数空间的某个方向上比其他方向大得多。确保您的参数缩放良好,并至少使用双精度。可能需要使用条件矩阵。太深了,这里就不展开了。

  3. 计算出的梯度不能很好地估计损失函数的梯度。如果问题条件良好,则梯度计算或损失函数计算都是错误的。针对梯度的有限差分估计对它们进行测试。

我拥有自己经过充分测试且超快速的求解器。我很想与您取得联系,但 SO 并不热衷于此。

于 2018-01-12T08:25:01.233 回答