1

我正在尝试在 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。

python中的其他实现

更多关于算法

4

1 回答 1

0

这个链接给出了算法的全面视图;事实证明我采用了完全错误的方法。

以下代码无法正常工作(我没有进一步处理它的计划),但应该让遇到与我相同问题的任何人都走上正轨:

#include <vector>
#include <iostream>

typedef std::vector<double> vect;

std::vector<double> y, omega(2, 0), omega2(2, 0);;
std::vector<std::vector<double>> X;
int n = 10;

int main(void) {
    /* Initialize x so that each members contains (1, x_i) */
    /* Initialize x so that each members contains y_i */
    double alpha = 0.00001;
    display();
    for (int i = 1; i <= 8; i++) {
        gradientStep(alpha);
        display();
    }
    return 0;
}

double f_function(const std::vector<double> &x) {
    double c;
    for (unsigned int i = 0; i < omega.size(); i++) {
        c += omega[i] * x[i];
    }
    return c;
}

void gradientStep(double alpha) {
    for (int i = 0; i < n; i++) {
        for (unsigned int j = 0; j < X[0].size(); j++) {
            omega2[j] -= alpha/(double)n * (f_function(X[i]) - y[i]) * X[i][j];
        }
    }
    omega = omega2;
}

void display(void) {
    double res = 0, tmp = 0;
    for (int i = 0; i < n; i++) {
        tmp = y[i] - f_function(X[i]);
        res += tmp * tmp; // Loss functionn
    }

    std::cout << "omega = ";
    for (unsigned int i = 0; i < omega.size(); i++) {
        std::cout << "[" << omega[i] << "] ";
    }
    std::cout << "\tError : " << res * .5/(double)n << std::endl;
}
于 2016-02-15T20:44:30.690 回答