我正在用python实现Andrew ng的机器学习课程。在编程练习2中,在第一个问题上,我得到了成本函数和梯度的答案,但是当计算优化了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,我明白了。 预期的毕业成绩也与实际答案完全相同。 但是我得到的最优化的theta是array([4.42735730e-05,5.31690927e-03,4.98646266e-03],这给了我大约60的新成本(而不是0.203)
答案 0 :(得分:0)
问题是您正在与div
一起调用np.sum
而不是使用例如np.multiply
,这些操作通常并不等效。
np.dot
操作计算元素乘积,而np.multiply
计算适当的矩阵乘积,请参见Anuj Gautam的this answer on SO:
np.dot
是两个矩阵的dot product。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|
做element-wise multiplication 两种矩阵。np.multiply
要计算交叉熵损失,需要矩阵相乘。
将费用函数更改为
|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])
函数的自变量x
和y
的情况是错误的,因为您使用大写版本cost_compute
和X
在函数内部。
答案 1 :(得分:0)
我做了一些测试,方法是更改数组的形状,将其展平,重塑形状,但无济于事。
由于我们通过展平theta在fmin_tnc中输入一个一维theta,所以我想到了更改梯度函数,假设它将接收一个一维theta而不是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
现在可以了!