梯度下降
梯度下降用局部斜率寻找函数的较小值。对可微函数 ,迭代式为 其中 是步长。负梯度是当前点一阶近似中下降最快的方向;但步长过大仍可能越过低谷,使函数值上升。
二次函数的每一步
取 ,梯度 。若 、固定步长 ,则 。于是 、;令误差 ,可见 ,因此趋向 0。若步长取 1,则 ,在 0 与 6 之间来回跳,不会收敛。
图中金点依次是 ,白点是最小点 3。每次横向位置到 3 的距离缩成一半,纵向函数值则从 9 变成 、;轨迹说明步长合适时的收敛,但不能替代误差递推式的证明。
可运行的 Python 例子
Python 3
def gradient_descent(start: float, step: float, rounds: int) -> list[float]:
"""Minimize (x - 3)^2; return x_0,...,x_rounds."""
if step <= 0 or rounds < 0:
raise ValueError("step must be positive and rounds nonnegative")
x = float(start)
path = [x]
for _ in range(rounds):
x -= step * 2 * (x - 3)
path.append(x)
return path
print(gradient_descent(0, 0.25, 3)) # [0.0, 1.5, 2.25, 2.625]
代码不改写传入对象,返回含初值的迭代轨迹。运行 步需 时间和 输出空间;若只需终点,可不保存轨迹,将额外空间降为 。
收敛条件
对于梯度 -Lipschitz 的函数,固定 可保证常见的下降性质;若再有适当凸性,还能得到到最优值的收敛结论。上例 ,所以 对应误差因子 。一般非凸函数可能停在局部极小点或鞍点附近,不能仅凭“反复下降”宣称找到全局最优。