You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言逻辑回归截距梯度计算异常:printf影响结果

C语言逻辑回归截距梯度计算异常:printf语句影响结果的原因与修复

问题现象

用C语言实现逻辑回归时,计算截距(b)的梯度出现诡异问题:在gradient_i()函数的循环中,不添加printf("h_%d, %lf\n", j, y_hat_j);语句时,截距梯度结果为错误的0.1176;添加该语句后,结果变为正确的0.86。原以为sigmoid_j()和log_odds_pred()函数运行正常,实际问题藏在后者中。

根本原因

问题出在log_odds_pred()函数里的未初始化变量:

double log_odds_pred(double *theta, double *b, float x[2][2], int ex_number){
    double result; // 这里未初始化,值是随机垃圾值
    for(int i=0; i<n;i++){
        result += (*(theta+i)) * (x[i][ex_number]);
    }
    result += *b;
    return result;
}

result声明后没有赋值初始值,它会持有栈内存里的随机垃圾值。当你不添加printf时,这个随机值会参与后续的累加计算,导致y_hat_j完全错误,最终梯度结果异常;而添加printf后,栈内存的布局被改变,result恰好被覆盖为0(或其他不影响正确计算的值),所以得到了正确结果。这种行为属于未定义行为,完全依赖编译器和运行时的内存状态。

修复方案

给log_odds_pred()里的result初始化一个初始值0即可:

double log_odds_pred(double *theta, double *b, float x[2][2], int ex_number){
    double result = 0; // 初始化result为0
    for(int i=0; i<n;i++){
        result += (*(theta+i)) * (x[i][ex_number]);
    }
    result += *b;
    return result;
}

修复后,无论是否添加printf语句,log_odds_pred()都会正确计算对数几率,y_hat_j的值稳定,最终截距梯度会固定为正确的0.86。

额外建议

  • 养成变量声明时立即初始化的习惯,尤其是局部变量,避免未定义行为。
  • 调试此类问题时,可以用编译器的警告功能(比如GCC的-Wall参数),编译器会直接提示未初始化变量的问题:warning: 'result' is used uninitialized in this function。

内容的提问来源于stack exchange,提问作者dkristof04

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 20:58:27