【问题标题】:How to properly stop iteration in minimization in Python?如何在 Python 中正确停止迭代最小化?
【发布时间】:2014-10-08 03:53:14
【问题描述】:

我发布这个问题是因为,我的代码没有在正确的位置停止迭代。谁能帮我确定是什么问题?

一切正常(我一直认为这是现实中的错误..)

问题:

1) 在每次迭代中,我都在最小化不幸的是,它没有正确地最小化(结果很差)。我是否在最小化过程中正确停止迭代?有什么建议吗?

只需运行以下代码:

import numpy as np
from scipy.stats import stats
def run_iter():
    # Initial guess
    x_new = x0
    # just to pretend we have huge error
    phi0 = 1e20
    for i in range(iter_num):
         # first solution
         x_next = x_new

         # FIRST WAY
         # First assumption to stop the iteration...

         # SECOND WAY
         '''
         # Second assumption to stop the iteration
         '''
    return x_new

def example_run():

if __name__ == '__main__':
    print example_run()

【问题讨论】:

    标签: least-squares


    【解决方案1】:

    我认为您的问题有两个主要方面需要评论。

    1) 两种方法的收敛性。

    您的第一种方法是收敛的,但没有您设置的那样高的容差。使用 L1-supnorm,np.max(np.abs(x_new1 - x_new)),将之前的迭代值与当前的迭代值进行比较表明,您的第一个更新机制收敛于略高于 1e-14 的容差(您可以计算对应的收敛水平 phi )。您的第二种方法可能根本不会收敛。该例程被您的最大迭代界限切断,但即使有 1000 次迭代,第二种方法下的 L1-supnorm 也永远不会低于 0.009,迭代步数通常比第一个例程小得多。此外,增加迭代界限会降低其性能。因此,我将第二种方法的准确性更多地归因于您的初始猜测而不是算法性能。

    2) 如何提高性能

    我会立即给出两个建议。首先,想想你是如何产生你最初的猜测的。牛顿型优化方法对初始条件非常敏感。我不确定您当前的猜测是否有任何理论基础(现在,您似乎只是选择了一个随机值并为所有参数重复),但如果没有,请考虑一些方法来更好地告知它(也许是一个简化的解决方案方法 - OLS 有时用于初始值,但您可能不得不考虑其他方法,因为您的系统不确定)。其次,您处理负参数值 (x_new1[x_new1<0] = 0.001) 的方法非常临时,对您的算法没有帮助。如果参数应该是非负的,那么您实际上是在解决一个受约束的优化问题,并且应该在您的算法中考虑到这一点,尤其是在梯度中。有关牛顿型算法和约束优化算法的初始猜测敏感性的理论细节,任何关于非线性优化/编程的优秀教科书都应该有所帮助。 Boyd 和 Vandenberghe 的 凸优化 是一个不错的选择,Boyd 从他的网站 here 免费提供。对于实现/代码,很难击败Numerical Recipes。根据您查看的版本,它会为您提供 C++、C 或 Fortran 代码。但是,您应该能够相当轻松地将他们的算法转换为 Python/NumPy。

    关于您关于np.linalg.norm 的最后一个问题,我不确定您指的是代码的哪一部分。

    编辑

    话虽如此,我不确定你为什么要这样做。您尝试使用的论文包含几乎可以在 Python 中完全复制的代码。在论文中,作者使用了双共轭梯度法,他在(4.1.3)和(4.1.4)中使用了Matlab中的bicg函数。与其尝试编写自己的优化例程,不如使用 Python 模块 scipy 中包含的相应 bicg 方法。可以用from scipy.sparse.linalg import bicg导入。

    作为优化例程的一般说明:如果您不必自己编写它们,请不要。在大多数情况下,已经有人花费了大部分时间来开发您需要的方法的有效实现。通常,尤其是对于 Python,这些都是免费提供的(专有求解器除外)。所以,除非数值方法是你的事,否则你最好花时间找出使用这些预先编写的例程的最有效方法。在这个例子中,这将包括理解你的论文作者在方程(4.1.2)中定义的稀疏结构。没有这个,论文就变成了用方程 (3.2.3) 计算解的问题,你可能会用np.linalg.solve 做(尽管效率低,因为你没有使用稀疏结构)。或者,由于您有一个不确定的系统,您可以使用scipy.optimize.nnls,它还具有保持您的值非负数的好处。有一个很好的例子来说明它的用法here

    【讨论】:

    • 感谢您的参考。我已经编辑了我的答案以解决论文中的注意事项。
    • 好吧,如果您真的想使用自己的算法,我认为您的 Math StackExchange 问题没有任何问题。我认为您最好的选择是考虑我在第 (2) 部分中的建议。我还在关于如何使用nnls 优化欠定系统的答案中添加了两句话。您可以直接将其与导致 (3.2.3) 的等式一起使用,并避免编写自己的优化算法。
    • 这似乎是合理的。抱歉,但这听起来更像是一个领域级的概念问题,而不是编程问题。我仍然认为我关于在算法中包含您的界限的建议应该会有所帮助,但至于诸如 x0 的知识,您可能需要考虑另一个论坛。
    • 关于它的编程方面,您认为我的回答涵盖了本论坛可以解决的要点吗?如果是,接受吗?
    【解决方案2】:

    对于第一个停止标准,只需使用比1e20 更低的错误边界。如果您在每次迭代时打印phi,您将看到该设置

    phi0 = 1e10
    

    将在i == 1 处停止迭代,结果非常相似(甚至略低)。

    此外,如果您需要更多帮助,您应该详细说明您尝试解决的优化问题类型、您使用的方法以及停止标准背后的想法。

    【讨论】:

      猜你喜欢
      • 2015-12-15
      • 1970-01-01
      • 2018-03-24
      • 2017-05-13
      • 1970-01-01
      • 2020-08-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多