问题简介:当试图使用scipy.optimize.fmin_bfgs最小化(优化)函数时,该函数会抛出
derphi0=np.dot(gfk,pk)ValueError:矩阵未对齐
错误。根据我的错误检查,这发生在通过fmin_bfgs的第一次迭代的最后——就在返回任何值或调用回调之前。
配置:Windows VistaPython 3.2.2SciPy 0.10IDE=带有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_wolve1函数和scipy包提供的标量搜索。
值得注意的是,如果我使用scipy.moptimite.fmin,fmin函数将运行完成。
精确错误:
文件"D:\Users\Shannon\Programing\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\poptimity\py",第行533,格式为fmin_bfgs old_fval,old_old_fval)
文件"C:\Python32x32\lib\site packages\scipy\optimity\linesearch.py",第行76,在line_search_wolve1中derphi0=np.dot(gfk,pk)ValueError:矩阵未对齐
我调用优化函数时使用:optcost=scipy.moptimit.fmin_bfgs(self-cost_arr,initialttheta,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.moptimize pk=[[12.00921659][11.26284221]]pk类型=和scipy.optimize.optimize gfk=[[-12.0921659][-11.26284221]gfk类型=注意:根据我的测试,错误是在fmin_bfgs的第一次迭代中抛出的(即,fmin_bfg甚至从未完成过一次迭代或更新)。
我感谢任何指导或见解。
下面的我的代码(日志记录,文档已删除):假设θ=2x1 ndarray(实际:θ信息大小=(2,1)类型=)假设X=100x2 ndarray(实际:X信息大小=(2100)类型=)假设y=100x1 ndarray(实际:y信息大小=(100,1)类型=)
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
如果其他人遇到这个问题。。。。
1) 错误1:如注释中所述,我错误地将梯度中的值返回为多维数组(m,n)或(m,1)。fmin_bfgs似乎需要从渐变输出1d数组(也就是说,必须返回(m,)数组,而不是(m,1)数组。如果您不确定返回值,请使用scipy.shape(myarray)检查尺寸。
修复包括添加:
grad = numpy.ndarray.flatten(grad)
就在从梯度函数返回梯度之前。这将数组从(m,1)"展平"到(m,)。fminbfgs可以将此作为输入。
2) 错误2:记住,fmin_bfgs似乎适用于非线性函数。在我的例子中,我最初使用的样本是一个线性函数。这似乎可以解释一些异常结果,即使在上述平坦固定之后也是如此。对于LINERAL函数,fmin而不是fmin_bfgs可能工作得更好。
QED
从当前的scipy版本开始,您不需要传递fprime参数。它将为您计算梯度,而不会出现任何问题。您也可以使用"最小化"fn并将方法作为"bfgs"传递,而不提供梯度作为参数。