使用梯度下降算法时出现初始值错误,收敛结果偏离真实最优解
问题原因分析
- 核心错误是循环参数设置错误:Python中
range()的入参要求为整数,布尔值True会被隐式转换为整数1,因此for _ in range(True)等价于仅执行1次的循环。你的参数只完成了一次步长极小的更新,远未达到收敛条件,因此输出结果接近初始值10000。 - 循环内部逻辑存在冗余问题:循环末尾的
x_new = x_old是无意义的重复赋值,且原代码先将x_old更新为新值再做收敛判断,逻辑顺序也容易引发额外错误。 - 预设的迭代次数参数
n_iter未被实际使用,缺少迭代次数上限的校验,即使修复了循环参数问题,极端情况下也可能出现死循环。
解决方法
- 修正循环逻辑:将循环改为基于你预设的
n_iter的遍历,或者使用同时限制迭代次数、收敛条件的while循环,保证算法有足够多的迭代次数完成收敛。 - 清理冗余代码:删除循环末尾无意义的
x_new = x_old赋值语句,调整收敛判断的位置,避免逻辑混乱。 - 可根据收敛需求调整学习率:当前目标函数是凸二次函数,Lipschitz常数为2,学习率最大可设置为小于1的值,例如将
lr调整为0.01或0.1,可以大幅加快收敛速度,减少所需迭代次数。
修复后的可运行代码
import numpy.linalg as nl x_ini = 10000 def obj(x): f = x**2 - 2*x + 3 return f def grad(x): df = 2*x - 2 return df n_iter = 10000 lr = 0.001 x_old = x_ini x_new = x_ini for _ in range(n_iter): x_new = x_old - lr * grad(x_old) if nl.norm(grad(x_new)) <= 1e-03: break x_old = x_new print(x_new)
运行上述代码会输出约1.000499的结果,和真实最优解x=1的误差在接受范围内。
内容的提问来源于stack exchange,提问作者RK S
相关产品推荐
相关产品推荐

