optimize.fmin_tnc在scipy.optimize中没有给出正确的答案?

时间:2019-06-13 11:56:26

标签: python-3.x numpy machine-learning optimization scipy

我正在用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)

2 个答案:

答案 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]) 函数的自变量xy的情况是错误的,因为您使用大写版本cost_computeX在函数内部。

答案 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

现在可以了!