我正在学习Coursera上的Andrew Ng的机器学习课程,并选择用Python而不是MATLAB来实现所有代码。
在编程练习3中,我以向量化的形式实现了我的正则化逻辑回归成本函数:
def compute_cost_regularized(theta, X, y, lda): reg =lda/(2*len(y)) * np.sum(theta**2) return 1/len(y) * np.sum(-y @ np.log(sigmoid(X@theta)) - (1-y) @ np.log(1-sigmoid(X@theta))) + reg
在以下测试输入下:
theta_test = np.array([-2,-1,1,2])X_test = np.concatenate((np.ones((5,1)), np.fromiter((x/10 for x in range(1,16)), float).reshape((3,5)).T), axis = 1)y_test = np.array([1,0,1,0,1])lambda_test = 3
上述成本函数输出3.734819396109744
。然而,根据我们提供的MATLAB框架代码,正确的输出应该是2.534819
。我很困惑,因为我找不到我的成本函数有什么问题,但我认为它有bug。事实上,我也在编程练习2中实现了它,在二元分类的情况下它运行良好,实现了它,并给出了接近预期值的结果。
我认为一个可能的原因是我错误地解释了提供的MATLAB框架代码,从而错误地构建了我的*_test
输入数组,这些代码是:
theta_t = [-2; -1; 1; 2];X_t = [ones(5,1) reshape(1:15,5,3)/10];y_t = ([1;0;1;0;1] >= 0.5);lambda_t = 3;
然而,我通过Octave解释器运行它们以查看它们实际是什么,并确保我能在Python中完全匹配它们。
此外,基于这些输入计算梯度,使用我自己的向量化和正则化梯度函数也是正确的。最后,我决定继续进行计算并检查预测结果。我的预测准确率远低于预期的准确率,因此更有理由怀疑我的成本函数有问题,导致其他一切都出错。
请帮助我!谢谢你。
回答:
如果你还记得正则化的话,你不对偏置系数进行正则化。不仅在进行梯度下降时将梯度设为零,而且在成本函数中也不包括它。你犯了一个小错误,你将它包含在求和中(请查看你链接的笔记本中的单元格#18 – 求和应该从j = 1
开始,但你设置为j = 0
)。因此,你需要从theta
的第二个元素开始到最后进行求和,而不是从第一个元素开始。你可以在你的Github仓库中看到的ex2.pdf
PDF作业的第9页上验证这一点。这解释了成本增加的原因,因为你将偏置单元包括在正则化中。
因此,在计算reg
中的正则化时,索引theta
从第二个元素开始到最后:
def compute_cost_regularized(theta, X, y, lda): reg =lda/(2*len(y)) * np.sum(theta[1:]**2) # 此处更改 return 1/len(y) * np.sum(-y @ np.log(sigmoid(X@theta)) - (1-y) @ np.log(1-sigmoid(X@theta))) + reg
一旦我这样做,定义你的测试值以及定义你的sigmoid
函数,我得到了你期望的正确答案:
In [8]: def compute_cost_regularized(theta, X, y, lda): ...: reg =lda/(2*len(y)) * np.sum(theta[1:]**2) ...: return 1/len(y) * np.sum(-y @ np.log(sigmoid(X@theta)) ...: - (1-y) @ np.log(1-sigmoid(X@theta))) + reg ...:In [9]: def sigmoid(z): ...: return 1 / (1 + np.exp(-z)) ...:In [10]: theta_test = np.array([-2,-1,1,2]) ...: X_test = np.concatenate((np.ones((5,1)), ...: np.fromiter((x/10 for x in range(1,16)), float).reshape((3,5)).T), axis = 1) ...: y_test = np.array([1,0,1,0,1]) ...: lambda_test = 3 ...:In [11]: compute_cost_regularized(theta_test, X_test, y_test, lambda_test)Out[11]: 2.5348193961097438