LBFGS永远不会在pytorch中大规模收敛

时间:2018-05-31 10:09:37

标签: python tensorflow pytorch nonlinear-optimization

我正在使用Wolfram细胞自动机的规则110。给定零和一行,您可以使用以下规则计算下一行:

enter image description here

最后以00000000 .... 1开头,你得到这个序列:

enter image description here

出于好奇,我决定用多项式来近似这些规则,这样细胞不仅可以是0和1,而且还可以是灰色:

def triangle(x,y,z,v0):
    v=(y + y * y + y * y * y - 3. * (1. + x) * y * z + z * (1. + z + z * z)) / 3.
    return (v-v0)*(v-v0)

所以如果x,y,z和v0与表中的任何一个规则匹配,它将返回0,否则返回正非零值。

接下来,我已将所有可能的4个邻居组添加到单个总和中,整数解决方案将为零:

def eval():
    s = 0.
    for i in range(W - 1):
        for j in range(1, W + 1):
            xx = x[i, (j - 1) % W]
            yy = x[i, j % W]
            zz = x[i, (j + 1) % W]
            r = x[i + 1, j % W]
            s += triangle(xx, yy, zz, r)
    for j in range(W - 1): s += x[0, j] * x[0, j]
    s += (1 - x[0, W - 1]) * (1 - x[0, W - 1])
    return torch.sqrt(s)

同样在这个函数的底部,我为第一行添加了普通条件,因此除了最后一个元素之外,所有元素都是0,这是1.最后,我决定在W * W矩阵上最小化这个平方和与pytorch:

x = Variable(torch.DoubleTensor(W,W).zero_(), requires_grad=True)
opt = torch.optim.LBFGS([x],lr=.1)
for i in range(15500):
    def closure():
        opt.zero_grad()
        s=eval()
        s.backward()
        return s
    opt.step(closure)

这是full code,您可以自己尝试一下。问题是,对于10 * 10,它会在~20步中收敛到正确的解决方案:

enter image description here

但如果我拿15 * 15板,它永远不会完成收敛:

enter image description here

右边的图表显示了每次下一次迭代时平方和的变化情况,你可以看到它永远不会达到零。我的问题是为什么会发生这种情况,如何解决这个问题。尝试了不同的pytorch优化器,但它们都比LBFGS表现更差。尝试了不同的学习率。任何想法为什么会发生以及如何在优化过程中达到最终点?

UPD:改进了收敛图,SOS日志:

enter image description here

UPD2:我也尝试用dlib在C ++中做同样的事情,我在那里没有任何收敛问题,它在更短的时间内更深入:

enter image description here

我在C ++中使用此代码进行优化:

find_min_using_approximate_derivatives(bfgs_search_strategy(),
        objective_delta_stop_strategy(1e-87),
        s, x, -1)

1 个答案:

答案 0 :(得分:1)

你在这里尝试做的是非凸优化,这是一个众所周知的难题。一旦你考虑它,它就有意义,因为几乎任何实际的数学问题都可以被表述为优化问题。

<强> 1。前奏
因此,在向您提供有关在何处找到特定问题的解决方案的提示之前,我想说明为什么某些优化问题很容易解决。

我将首先讨论凸问题。即使在受约束的情况下,这些也很容易解决,其原因在于,当你计算渐变时,你实际上得到了很多关于最小值不可能的信息(凸函数的泰勒展开,f,总是一个低估f),另外只有一个最小值,没有悲伤点。如果您有兴趣了解有关凸优化的更多信息,我建议您在YouTube

上查看Stephen Boyd的凸优化课程

现在,如果非凸优化如此困难,我们怎么能够在深度学习中解决它?答案就是我们在深度学习中最小化的非凸函数,如Henaff et al所证明的那样非常好。

因此,机器学习从业者必须意识到深度学习中使用的操作程序很可能不会产生良好的最小值,如果它们首先收敛到最小值,则会出现其他非凸问题。

<强> 2。回答你的问题
现在回答你的问题,你可能不会找到并快速解决,因为非凸优化是NP完成的。但不用担心,SciPy有一些全局优化算法可供选择。 Here是另一个堆栈溢出线程的链接,可以很好地回答您的问题。

第3。故事的道德
最后,我想提醒一下,收敛保证很重要,忘了它导致了oil rig collapsing

PS。请原谅错别字,我用我的手机

更新:至于为什么BFGS与dlib一起工作,可能有两个原因,第一,BFGS比L-BFGS更好地使用曲率信息,其次它使用线搜索来查找最佳步长。我建议检查PyTorch是否允许行搜索,如果不允许,请设置递减步长(或者只是非常低的步长)。