lmfit最小化失败,返回ValueError:数组太大



我正在尝试使用"暴力"方法来最小化20个变量的函数。它失败了,出现了一个神秘的错误。这是完整的代码:

import random
import numpy as np
import lmfit
def progress_update(params, iter, resid, *args, **kws):
pass
#print(resid)
def score(params, data = None):
parvals = params.valuesdict()
M = data
X_params = []
Y_params = []
for i in range(M.shape[0]):
X_params.append(parvals['x'+str(i)])
for j in range(M.shape[1]):
Y_params.append(parvals['y'+str(i)])
return diff(M, X_params, Y_params)

def diff(M, X_params, Y_params):
total = 0
for i in range(M.shape[0]):
for j in range(M.shape[1]):
total += abs(M[i,j] - (X_params[i] - Y_params[j])**2)
return total
dim = 10
random.seed(0)
M = np.empty((dim, dim))
for i in range(M.shape[0]):
for j in range(M.shape[1]):
M[i,j] = i*random.random()+j**2
params = lmfit.Parameters()
for i in range(M.shape[0]):
params.add('x'+str(i), value=random.random()*10, min=0, max=10)
for j in range(M.shape[1]):
params.add('y'+str(j), value=random.random()*10, min=0, max=10)
result = lmfit.minimize(score, params, method='brute', kws={'data': M},  iter_cb=progress_update)

然而,这在以下情况下失败:

ValueError: array is too big; `arr.size * arr.dtype.itemsize` is larger than the maximum possible size.

是什么导致了这个问题?

"是什么导致了这个问题">

数学

你不能强行解决高维问题,因为强行方法需要指数运算(如果实现得很天真,需要时间和内存(。

更直接地说,lmfit在引擎盖下使用numpy(*(,它有一个可以分配多少数据的最大大小。您的初始数据结构不是太大(10x10(,它是导致问题的暴力所需的组合表。

如果你愿意破解实现,你可以切换到稀疏内存结构。但这并不能解决数学问题。

关于高维优化

尝试不同的最小化器,但要注意:在高维空间中进行全局最小化是非常困难的。像定点/梯度下降这样的"局部极小"方法可能更有效。

我不想悲观,但一般来说,高级优化是非常困难的,我担心这超出了SO问题的范围。这是一项调查。

实用替代方案

梯度下降在sklearn中得到了一点支持,但在机器学习中比一般优化更受支持;scipy实际上有相当好的优化覆盖范围和出色的文档。我会从那里开始。在那里也可以进行梯度下降,但不是必须的。

从scipy关于无约束最小化的文档中,您有很多选择:

方法Nelder Mead使用单纯形算法[],[]。此算法在许多应用中都是稳健的。但是,如果导数可以是可信的,使用第一和/或二阶导数信息可能更可取一般性能。

方法Powell是对Powell方法[]的修改,[]是共轭方向法。它执行顺序一维沿着方向集的每个向量的最小化(direc场选项和信息(,在main的每次迭代时更新最小化循环。函数不必是可微的取导数。

以及更多基于导数的方法可用。(一般来说,当你有衍生品信息可用时,你会做得更好。(


脚注/查看源代码

(*(实际错误是根据您的numpy实现抛出的。报价:

`if (npy_mul_with_overflow_intp(&nbytes, nbytes, dim)) {
PyErr_SetString(PyExc_ValueError,
"array is too big; `arr.size * arr.dtype.itemsize` "
"is larger than the maximum possible size.");
Py_DECREF(descr);
return NULL;`

相关内容

最新更新