矩阵没有对齐错误:Python SciPy fmin_bfgs

时间:2012-01-06 01:06:17

标签: python-3.x scipy linear-algebra linear-regression

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

  

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

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

配置: Windows Vista Python 3.2.2 SciPy 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行和scaplar搜索中由scipy包提供。

值得注意的是,如果我使用 scipy.optimize.fmin fmin 函数将运行完成。

确切错误:

  

文件   “d:\用户\香\程序\ Eclipse的\工作区\ 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)

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

ADDENDUM: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 type = and scipy.optimize.optimizegfk = [[-12.00921659] [-11.26284221]] gfk type = 注意:根据我的测试,通过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

2 个答案:

答案 0 :(得分:17)

如果有其他人遇到这个问题......

1)错误1:如评论中所述,我错误地将渐变中的值作为多维数组(m,n)或(m,1)返回。 fmin_bfgs似乎需要渐变的1d数组输出(也就是说,你必须返回一个(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

答案 1 :(得分:0)

从目前的scipy版本开始,你不需要传递fprime参数。它将为您计算梯度而不会出现任何问题。您还可以使用'最小化' fn和传递方法作为' bfgs'而不提供渐变作为参数。