我正在尝试在 C++ 中实现梯度下降算法。这是我到目前为止的代码:
#include <iostream>
double X[] {163,169,158,158,161,172,156,161,154,145};
double Y[] {52, 68, 49, 73, 71, 99, 50, 82, 56, 46 };
double m, p;
int n = sizeof(X)/sizeof(X[0]);
int main(void) {
double alpha = 0.00004; // 0.00007;
m = (Y[1] - Y[0]) / (X[1] - X[0]);
p = Y[0] - m * X[0];
for (int i = 1; i <= 8; i++) {
gradientStep(alpha);
}
return 0;
}
double Loss_function(void) {
double res = 0;
double tmp;
for (int i = 0; i < n; i++) {
tmp = Y[i] - m * X[i] - p;
res += tmp * tmp;
}
return res / 2.0 / (double)n;
}
void gradientStep(double alpha) {
double pg = 0, mg = 0;
for (int i = 0; i < n; i++) {
pg += Y[i] - m * X[i] - p;
mg += X[i] * (Y[i] - m * X[i] - p);
}
p += alpha * pg / n;
m += alpha * mg / n;
}
此代码收敛于 m = 2.79822,p = -382.666,误差为 102.88。但是如果我用我的计算器找出正确的线性回归模型,我发现m和p的正确值应该分别是1.601和-191.1。
我还注意到,对于 alpha > 0.00007,该算法不会收敛,这似乎非常低,并且 p 的值在 8 次迭代期间几乎没有变化(甚至在 2000 次迭代之后)。
我的代码有什么问题?
这是我尝试实现的算法的一个很好的概述。theta0 和 theta1 的值在我的程序中称为 p 和 m。