问题概要: 在尝试使用 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:矩阵未对齐。根据来源审查,确切的错误发生在
# Minpack 的 Wolfe 行和标量搜索中的 def line_search_wolfe1 函数,由 scipy 包提供。
值得注意的是,如果我改用scipy.optimize.fmin,fmin函数会运行完成。
确切的错误:
文件“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 type = 和 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