问题简介: 当尝试使用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
答案 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'而不提供渐变作为参数。