矩阵未对齐错误:Python SciPy fmin_bfgs

Posted

技术标签:

【中文标题】矩阵未对齐错误:Python SciPy fmin_bfgs【英文标题】:matrices are not aligned Error: Python SciPy fmin_bfgs 【发布时间】:2012-02-03 20:21:10 【问题描述】:

问题概要: 尝试使用 scipy.optimize.fmin_bfgs 最小化(优化)函数时,该函数会抛出一个

derphi0 = np.dot(gfk, pk) ValueError: 矩阵未对齐

错误。根据我的错误检查,这发生在通过 fmin_bfgs 的第一次迭代的最后——就在返回任何值或任何回调调用之前。

配置: 视窗 Python 3.2.2 科学派 0.10 IDE = 带有 PyDev 的 Eclipse

详细说明: 我正在使用 scipy.optimize.fmin_bfgs 来最小化简单逻辑回归实现的成本(从 Octave 转换为 Python/SciPy)。基本上,代价函数被命名为cost_arr函数,梯度下降在gradient_descent_arr函数中。

我已经手动测试并完全验证了 *cost_arr* 和 *gradient_descent_arr* 可以正常工作并正确返回所有值。我还进行了测试以验证是否将正确的参数传递给 *fmin_bfgs* 函数。然而,在运行时,我得到了 ValueError:矩阵未对齐。根据来源审查,确切的错误发生在

def line_search_wolfe1 # Minpack 的 Wolfe 行和标量搜索中的函数,由 scipy 包提供。

值得注意的是,如果我改用 scipy.optimize.fminfmin 函数会运行完成。

确切错误:

文件 "D:\Users\Shannon\Programming\Eclipse\workspace\SBML\sbml\LogisticRegression.py", 第 395 行,在 fminunc_opt 中

optcost = scipy.optimize.fmin_bfgs(self.cost_arr, initialtheta, fprime=self.gradient_descent_arr, args=myargs, maxiter=maxnumit, callback=self.callback_fmin_bfgs, retall=True)   

文件 “C:\Python32x32\lib\site-packages\scipy\optimize\optimize.py”,行 533, 在 fmin_bfgs old_fval,old_old_fval) 文件“C:\Python32x32\lib\site-packages\scipy\optimize\linesearch.py​​”,行 76,在 line_search_wolfe1 derphi0 = np.dot(gfk, pk) ValueError:矩阵未对齐

我调用优化函数: optcost = scipy.optimize.fmin_bfgs(self.cost_arr, initialtheta, fprime=self.gradient_descent_arr, args=myargs, maxiter=maxnumit, callback=self.callback_fmin_bfgs, retall=True)

我花了几天时间尝试解决此问题,但似乎无法确定导致 矩阵未对齐 错误的原因。

附录:2012-01-08 我对此进行了更多的工作,并且似乎缩小了问题的范围(但对如何解决它们感到困惑)。首先,fmin(仅使用 fmin)使用这些函数——成本、梯度。其次,在手动实现(不使用 fmin_bfgs)的单次迭代中测试时,成本和梯度函数都准确地返回预期值。第三,我在optimize.linsearch中添加了错误代码,错误似乎是在def line_search_wolfe1中抛出的:derphi0 = np.dot(gfk, pk)。 在这里,根据我的测试, scipy.optimize.optimize pk = [[ 12.00921659] [11.26284221]]pk 类型 = 和 scipy.optimize.optimizegfk = [[-12.00921659] [-11.26284221]]gfk 类型 = 注意:根据我的测试,错误是在 fmin_bfgs 的第一次迭代中引发的(即 fmin_bfgs 甚至从未完成一次迭代或更新)。

感谢任何指导或见解。

我的代码如下(记录,文档已删除): 假设 theta = 2x1 ndarray(实际:theta Info Size=(2, 1) Type = ) 假设 X = 100x2 ndarray(实际:X Info Size=(2, 100) Type = ) 假设 y = 100x1 ndarray (实际:y Info Size=(100, 1) Type = )

def cost_arr(self, theta, X, y):

    theta = scipy.resize(theta,(2,1))         

    m = scipy.shape(X)

    m = 1 / m[1] # Use m[1] because this is the length of X
    logging.info(__name__ + "cost_arr reports m = " + str(m))         

    z = scipy.dot(theta.T, X) # Must transpose the vector theta               

    hypthetax = self.sigmoid(z)

    yones = scipy.ones(scipy.shape(y))

    hypthetaxones = scipy.ones(scipy.shape(hypthetax))

    costright = scipy.dot((yones - y).T, ((scipy.log(hypthetaxones - hypthetax)).T))

    costleft = scipy.dot((-1 * y).T, ((scipy.log(hypthetax)).T))


def gradient_descent_arr(self, theta, X, y):

    theta = scipy.resize(theta,(2,1)) 

    m = scipy.shape(X)

    m = 1 / m[1] # Use m[1] because this is the length of X

    x = scipy.dot(theta.T, X) # Must transpose the vector theta

    sig = self.sigmoid(x)

    sig = sig.T - y

    grad = scipy.dot(X,sig)

    grad = m * grad

    return grad

def fminunc_opt_bfgs(self, initialtheta, X, y, maxnumit):
    myargs= (X,y)

    optcost = scipy.optimize.fmin_bfgs(self.cost_arr, initialtheta, fprime=self.gradient_descent_arr, args=myargs, maxiter=maxnumit, retall=True, full_output=True)

    return optcost

【问题讨论】:

您能否发布一个其他人可以运行的简单、简洁的案例来重现该错误?您提供的参数可能格式不正确,但如果不了解您的代码是做什么的,就无法提供帮助。 def gradient_descent_arr(self, theta, X, y): theta = scipy.resize(theta,(2,1)) # Gives the Octave size of the matrix m = scipy.shape(X) m = 1 / m[1] # Use m[1] because this is the length of X x = scipy.dot(theta.T, X) # Must transpose the vector theta sig = self.sigmoid(x) sig = sig.T - y grad = scipy.dot(X,sig) grad = m * grad return grad talonmies--谢谢。我在原始帖子中添加了代码。任何见解将不胜感激。 您的渐变是否返回列数组形状 (k,1) 而不是一维数组 (k,)?只是一个猜测,我没有尝试过。 【参考方案1】:

万一其他人遇到这个问题......

1) 错误 1:如 cmets 中所述,我错误地将梯度中的值作为多维数组 (m,n) 或 (m,1) 返回。 fmin_bfgs 似乎需要从梯度输出一维数组(也就是说,您必须返回一个 (m,) 数组而不是 (m,1) 数组。如果您不确定,请使用 scipy.shape(myarray) 检查尺寸返回值。

修复涉及添加:

grad = numpy.ndarray.flatten(grad)

就在从渐变函数返回渐变之前。这将数组从(m,1)“展平”到(m,)。 fmin_bfgs 可以将此作为输入。

2) 错误 2:请记住,fmin_bfgs 似乎适用于非线性函数。就我而言,我最初使用的示例是一个 LINEAR 函数。即使在上面提到的扁平化修复之后,这似乎也解释了一些异常结果。对于 LINEAR 函数,使用 fmin 而不是 fmin_bfgs 可能会更好。

QED

【讨论】:

看来fmin_ncg也需要flattened渐变返回,(m,1)需要改成(m,)【参考方案2】:

从当前的 scipy 版本开始,您不需要传递 fprime 参数。它将毫无问题地为您计算梯度。您也可以使用 'minimize' fn 并将方法作为 'bfgs' 传递,而不提供渐变作为参数。

【讨论】:

以上是关于矩阵未对齐错误:Python SciPy fmin_bfgs的主要内容,如果未能解决你的问题,请参考以下文章

使用scipy.optimize.fmin的常见问题

为啥我从 scipy.optimize.fmin 得到不正确的结果?

Scipy优化算法--scipy.optimize.fmin_tnc()/minimize()

python setup.py安装错误LNK2019:函数致命错误LNK1120中引用的无法解析的外部符号fmin:

Python中的约束最小二乘估计

python中scipy学习——随机稀疏矩阵及操作