Python 3.x optimize.fmin_tnc在scipy.optimize中没有给出正确答案?
我正在用python实现Andrew ng的机器学习课程。在编程练习2中,关于第一个问题,我得到了成本函数和梯度的书面答案,但当计算优化θ时,我得到了一个灾难性的答案 我已经尽力了,但没能找到错误Python 3.x optimize.fmin_tnc在scipy.optimize中没有给出正确答案?,python-3.x,numpy,machine-learning,optimization,scipy,Python 3.x,Numpy,Machine Learning,Optimization,Scipy,我正在用python实现Andrew ng的机器学习课程。在编程练习2中,关于第一个问题,我得到了成本函数和梯度的书面答案,但当计算优化θ时,我得到了一个灾难性的答案 我已经尽力了,但没能找到错误 def sigmoid(x): return 1 / (1 + np.exp(-x)) def cost_compute( theta,x, y): J = (-1/m) * np.sum(np.multiply(Y, np.log(sigmoid(X @ theta)))
def sigmoid(x):
return 1 / (1 + np.exp(-x))
def cost_compute( theta,x, y):
J = (-1/m) * np.sum(np.multiply(Y, np.log(sigmoid(X @ theta)))
+ np.multiply((1-Y), np.log(1 - sigmoid(X @ theta))))
return J
[m, n] = X.shape
X = np.hstack( (np.ones((m,1)) , X) )
Y = Y[:, np.newaxis]
theta = np.zeros((n+1,1))
def grad( theta, X, Y):
temp = (1/m) * X.T @ (sigmoid(X @ theta) - Y)
return temp
temp = opt.fmin_tnc(func = cost_compute, x0 = theta.flatten() , fprime = grad , args = (X, Y.flatten()))
print(temp)
预期成本是0.693,我正在得到它。
预期的梯度也与实际答案完全相同。
但是我得到的优化θ是数组([4.42735730e-05,5.31690927e-03,4.98646266e-03],给了我大约60!(而不是0.203)问题是你调用
np.sum
和np.multiply
而不是使用例如np.dot
,这些操作通常是不等价的
np.multiply
运算计算元素积,而np.dot
计算适当的矩阵积,参见Anuj Gautam:
np.dot
是两个矩阵的组合
|A B| . |E F| = |A*E+B*G A*F+B*H|
|C D| |G H| |C*E+D*G C*F+D*H|
|A B| ⊙ |E F| = |A*E B*F|
|C D| |G H| |C*G D*H|
然而,np.multiply
由两个矩阵组成
|A B| . |E F| = |A*E+B*G A*F+B*H|
|C D| |G H| |C*E+D*G C*F+D*H|
|A B| ⊙ |E F| = |A*E B*F|
|C D| |G H| |C*G D*H|
为了计算交叉熵损失,需要矩阵乘法
将成本函数更改为
def cost_compute( theta, X, Y):
J = (-1/m) * (np.dot(Y.T, np.log(sigmoid(X @ theta)))
+ np.dot((1-Y).T, np.log(1 - sigmoid(X @ theta))))
return J
结果为我提供了所需的结果:
>> cost_compute(temp[0], X, Y)
array([0.2034977])
此外,
cost\u compute
函数的参数x
和y
的情况是错误的,因为在函数中使用了大写版本x
和y
。我做了一些测试,改变了数组的形状,展平了数组,重塑了数组,但没有任何效果
因为我们通过展平θ在fmin_tnc中输入一维θ,所以我考虑改变梯度函数,假设它将接收一个一维θ,而不是3*1
早些时候是这样的
def grad( theta, X, Y):
temp = (1/m) * X.T @ (sigmoid(X @ theta) - Y)
return temp
现在是了
def grad( theta, X, Y):
temp = (1/m) * (X.T @ (sigmoid(X @ theta[:,np.newaxis]) - Y))
return temp
现在它开始工作了!谢谢你指出了大写错误。但是在这个特定的例子中,使用求和和和乘法并没有错,因为Y和S形有m*1的形状,所以如果我要使用点积,那么我就必须这样做``Y.t@np.log(S形(X@theta))```