我正在尝试实现Logistic回归,我正在使用Scipy的Optimize模块来查找优化的theta值。使用fmin函数时,我能够获得正确的值。但是我想在使用需要渐变的fmin_bfgs函数时这样做。
以下是代码段:
#Returns Cost of current theta values and gradient of cost w.r.t theta.
def costFunction(theta, X, y, _lambda):
#Initializes useful variables
m = len(y)
grad = np.zeros((np.shape(theta)))
#Solves for Hypothesis for input X.
h_x = Sigmoid(np.dot(X,theta))
#Reshaped because numpy kept returning row vector, not column.
h_x = h_x.reshape((m,1))
#Cost is broken up into terms for simplicity.
term1 = -y*np.log(h_x)
term2 = (1-y)*np.log((1-h_x))
#Regularized Cost FUnction
J = (1/m) * sum(term1-term2) + (_lambda/(2*m)) * sum(np.square(theta[1:][:]))
#Gradient for Theta1
grad_reg = (_lambda/m)*theta[1:]
#Combines gradient for Theta1 and onward.
grad = (1/m)* (np.dot(np.transpose(X),(h_x-y))) + np.vstack(([0],grad_reg))
return J,grad
#Finds Optimal Value for theta
cost, grad = costFunction(initial_theta, X,y, _lambda)
opt_theta = fmin_bfgs(cost,x0=initial_theta,fprime=grad, args = (X,y,_lambda))
我得到的错误是'numpy.ndarray' object is not callable
,它来自优化模块中的function_wrapper
函数。我甚至尝试在两个不同的函数中返回渐变和成本,但是得到了某种vstack
错误(如果这很重要/有帮助)。
据我所知,我已经提供了优化功能所要求的内容。
编辑/更新:我意识到我得到的错误是因为我正在传递成本,并且当它期望函数返回这些参数时,会将数字numpy数组作为参数。我意识到我可以创建一个包装函数?在不使用两个单独的函数的情况下获取这两个值,但出于临时目的,我更改了costFunction,因此它只返回成本,并创建了一个全新的函数Grad()
,(尽管代码相同)只返回毕业。这再次给了我all the input array dimensions except for the concatenation axis must match exactly
vstack错误。
答案 0 :(得分:1)
如果没有最小的可重复示例,很难调试。
我调试它的方式,我从一些简单的事情开始,以确保我得到正确的基本语法。有几种方法可以使用显式渐变来实现bfgs最小化。首先,没有梯度信息:
In [1]: import numpy as np
In [2]: from scipy.optimize import minimize
In [3]: def f(x):
...: return np.sum((x-2.)**2)
...:
In [4]: x0 = np.ones(3)
In [5]: minimize(f, x0, method='bfgs')
Out[5]:
status: 0
success: True
njev: 4
nfev: 20
fun: 1.6656677750444977e-16
x: array([ 1.99999999, 1.99999999, 1.99999999])
<snip>
现在,使用渐变,你可以有一个callable,它返回函数和渐变:
In [6]: def f_and_jac(x):
...: val = np.sum((x-2.)**2)
...: grad = 2.*(x-2.)
...: return val, grad
...:
In [7]: minimize(f_and_jac, x0, method='bfgs', jac=True) # notice the 'jac' parameter
Out[7]:
status: 0
success: True
njev: 4
nfev: 4
fun: 0.0
x: array([ 2., 2., 2.])
或者,您可以将jac
设置为callable,该callable应与cost函数具有相同的签名并返回渐变:
In [8]: def jac(x):
...: return 2.*(x-2.)
...:
In [9]: minimize(f, x0, method='bfgs', jac=jac)
Out[9]:
status: 0
success: True
njev: 4
nfev: 4
fun: 0.0
x: array([ 2., 2., 2.])