如何修改线性回归Gradient Descent实现,使其迭代至参数收敛而非固定epochs?
线性回归梯度下降实现的收敛逻辑调整方案
核心修改思路
原有固定迭代次数的实现存在两个明显问题:迭代次数不足时参数未收敛导致拟合效果差,迭代次数过多时浪费计算资源。我们可以将for循环改为while循环,通过判断参数更新幅度是否小于设定阈值来判定收敛,同时保留最大迭代次数作为兜底防护,避免学习率设置不合理导致的死循环。
具体调整步骤
- 新增两个超参数:
- 收敛阈值
tol:一般设置为1e-6~1e-8,当参数单次更新的幅度小于该值时判定为收敛 - 最大迭代次数
max_epochs:兜底防护,超过该次数即使未收敛也强制停止,避免程序卡死
- 收敛阈值
- 每次迭代前先保存上一轮的参数
m和c,更新完成后计算两次参数的差值绝对值 - 当
m和c的更新幅度都小于tol,或者迭代次数超过max_epochs时终止循环
修改后完整实现代码
# 初始化模型参数 m = 0 c = 0 L = 0.0001 # 学习率 tol = 1e-6 # 收敛阈值 max_epochs = 100000 # 最大迭代次数兜底 n = float(len(X)) # 样本数量 epoch = 0 while True: # 保存上一轮参数 m_old = m c_old = c # 梯度计算与参数更新 Y_pred = m*X + c D_m = (-2/n) * sum(X * (Y - Y_pred)) D_c = (-2/n) * sum(Y - Y_pred) m = m - L * D_m c = c - L * D_c epoch += 1 # 收敛判断:两个参数更新幅度都小于阈值,或达到最大迭代次数就停止 if (abs(m - m_old) < tol and abs(c - c_old) < tol) or epoch >= max_epochs: break print(f"迭代次数:{epoch},参数m:{m},参数c:{c}")
可选优化方案
- 你也可以选择用损失函数的变化幅度作为收敛判断依据:每次迭代计算MSE损失,当两次迭代的损失差值小于
tol时判定收敛,这种方式更直观反映拟合效果的变化 - 如果出现迭代到最大次数还未收敛的情况,可适当调大学习率
L或者调大max_epochs数值,注意学习率不能设置过大,否则会出现参数震荡无法收敛的问题
内容的提问来源于stack exchange,提问作者RedFox
相关产品推荐
相关产品推荐

