学习Andrew Ng课程实现Python梯度下降,参数收敛曲线与参考图差异排查
代码存在的核心问题
1. 梯度更新方向写反
按照Andrew Ng课上的线性回归梯度下降推导逻辑:
- 损失函数为 $J(m,b) = \frac{1}{2n}\sum_{i=1}^n (\hat{y}_i - y_i)^2$,其中预测值 $\hat{y}_i = m*x_i + b$
- 参数更新需要沿负梯度方向移动,公式为:
- $m = m - \alpha * \frac{\partial J}{\partial m}$,其中偏导 $\frac{\partial J}{\partial m} = \frac{1}{n}\sum_{i=1}^n (\hat{y}_i - y_i)*x_i$
- $b = b - \alpha * \frac{\partial J}{\partial b}$,其中偏导 $\frac{\partial J}{\partial b} = \frac{1}{n}\sum_{i=1}^n (\hat{y}_i - y_i)$
你代码中计算的m_derivative为sum((y_actual[i] - \hat{y}_i)*x_i),等价于 $-n * \frac{\partial J}{\partial m}$,但更新时直接套用了负号,最终实际的更新逻辑是 $m = m + \alpha * \frac{\partial J}{\partial m}$,相当于在做梯度上升,参数根本不会向损失最小的位置迭代。
b的更新逻辑同理,方向完全错误。
2. 学习率过小、迭代次数不足
你设置的学习率为0.0001,搭配1000次迭代的训练配置,步长过短。哪怕方向完全正确,这个学习率也需要数千次迭代才能观察到参数进入收敛平稳阶段。
叠加更新方向错误的问题,你看到的曲线只会是参数缓慢单向漂移,完全不会出现参考图里“前期快速拟合、后期逐步平稳”的特征。
3. 训练数据集缺乏线性相关性
你传入的x、y样本对的线性相关系数不足0.1,几乎没有可拟合的线性关系,本身最优参数和初始值的距离极近,但因为上述两个问题,根本无法收敛到最优值。
修改参考
调整梯度计算方向,将偏导部分替换为和推导一致的逻辑,适当提高学习率到0.01~0.1区间,即可得到符合预期的收敛曲线:
for z in range(iterations): m_derivative = 0 b_derivative = 0 for i in range(len(x_dataset)): y_hat = m_current * x_dataset[i] + b_current # 替换为正确的偏导计算逻辑 m_derivative += (y_hat - y_actual[i]) * x_dataset[i] b_derivative += (y_hat - y_actual[i]) itr.append(z) m_current = m_current - alpha * (m_derivative / len(x_dataset)) b_current = b_current - alpha * (b_derivative / len(x_dataset)) new_m.append(m_current) new_b.append(b_current)
如果想更直观看到和参考图一致的收敛形态,可以换一组强线性相关的数据集,收敛的“快速下降-平稳”特征会非常明显。
内容的提问来源于stack exchange,提问作者wong
相关产品推荐
相关产品推荐

