线性回归的梯度下降性能差

我用C++实现了一个简单的线性回归(目前是单变量)示例,以帮助我理解这些概念。我非常确定关键算法是正确的,但我的性能非常差。

以下是实际执行梯度下降的方法:

void LinearRegression::BatchGradientDescent(std::vector<std::pair<int,int>> & data,float& theta1,float& theta2){    float weight = (1.0f/static_cast<float>(data.size()));    float theta1Res = 0.0f;    float theta2Res = 0.0f;    for(auto p: data)    {        float cost = Hypothesis(p.first,theta1,theta2) - p.second;        theta1Res += cost;        theta2Res += cost*p.first;    }       theta1 = theta1 - (m_LearningRate*weight* theta1Res);    theta2 = theta2 - (m_LearningRate*weight* theta2Res);}

其他关键函数如下所示:

float LinearRegression::Hypothesis(float x,float theta1,float theta2) const{    return theta1 + x*theta2;}float LinearRegression::CostFunction(std::vector<std::pair<int,int>> & data,                                     float theta1,                                     float theta2) const{     float error = 0.0f;    for(auto p: data)    {        float prediction = (Hypothesis(p.first,theta1,theta2) - p.second) ;        error += prediction*prediction;    }    error *= 1.0f/(data.size()*2.0f);    return error;}void LinearRegression::Regress(std::vector<std::pair<int,int>> & data){    for(unsigned int itr = 0; itr < MAX_ITERATIONS; ++itr)    {       BatchGradientDescent(data,m_Theta1,m_Theta2);       //一些可视化代码    }}

现在的问题是,如果学习率大于大约0.000001,梯度下降后的成本函数值会高于之前。也就是说,算法在反向工作。线很快就形成了通过原点的直线,但实际上需要数百万次迭代才能达到合理拟合的线。

当学习率为0.01时,经过六次迭代后的输出是:(其中difference是costAfter-costBefore)

Cost before 102901.945312, cost after 517539430400.000000, difference 517539332096.000000Cost before 517539430400.000000, cost after 3131945127824588800.000000, difference 3131944578068774912.000000Cost before 3131945127824588800.000000, cost after 18953312418560698826620928.000000, difference 18953308959796185006080000.000000Cost before 18953312418560698826620928.000000, cost after 114697949347691988409089177681920.000000, difference 114697930004878874575022382383104.000000Cost before 114697949347691988409089177681920.000000, cost after inf, difference infCost before inf, cost after inf, difference nan

在这个例子中,theta被设置为零,学习率设置为0.000001,迭代次数为800万次!可视化代码每10万次迭代后更新一次图表。

enter image description here

创建数据点的函数如下:

static void SetupRegressionData(std::vector<std::pair<int,int>> & data){    srand (time(NULL));    for(int x = 50; x < 750; x += 3)    {        data.push_back(std::pair<int,int>(x+(rand() % 100), 400 + (rand() % 100) ));    }}

简而言之,如果我的学习率过高,梯度下降算法实际上会反向运行并趋向于无穷大,而如果降低到它实际收敛到最小值的点,所需的迭代次数就高得不可接受。

我在核心算法中是否遗漏了什么或犯了错误?


回答:

看起来一切都在按预期运行,但您在选择合理的学习率方面遇到了问题。这并不是一个完全简单的问题,有许多方法,从预定义的逐步降低学习率的计划(例如参见这篇论文)到自适应方法,如AdaGrad或AdaDelta。

对于您使用固定学习率的普通实现,您应该通过在将数据输入梯度下降算法之前将其标准化为零均值和单位标准差来简化您的工作。这样您就可以更容易地推理学习率。然后您可以相应地重新调整您的预测。

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注