返回

用传统梯度下降法驯服误差曲面:算法简介和示例

闲谈

在机器学习的迷人世界中,梯度下降法犹如一位忠诚的向导,引领着我们穿梭于误差曲面的起伏跌宕,最终找到最优解。在这趟算法之旅中,我们将探寻传统梯度下降法的奥秘,以一元二次函数、非凸函数和二元函数为练兵场,揭开算法的特性和应用秘籍。

算法原理:逐小步迈向最优

传统梯度下降法基于这样一个直观的思想:沿着误差曲面的负梯度方向,小步小步地更新参数,直到误差最小化。它的数学公式简洁而优雅:

θ = θ - α * ∇f(θ)

其中,θ是模型参数,α是学习率,∇f(θ)是误差函数f(θ)的梯度。

代码实现:一元二次函数初探

让我们从最简单的案例入手——一元二次函数。其误差函数为f(x) = (x - 2)^2,梯度为f'(x) = 2(x - 2)。根据梯度下降公式,我们写出Python代码:

import numpy as np

def gradient_descent(x0, alpha, num_iter):
    x = x0
    for i in range(num_iter):
        grad = 2 * (x - 2)
        x = x - alpha * grad
    return x

x0 = 5  # 初始值
alpha = 0.1  # 学习率
num_iter = 100  # 迭代次数

result = gradient_descent(x0, alpha, num_iter)
print(f"最优解:{result:.4f}")

运行代码后,我们会发现算法成功找到了最优解x = 2。

非凸函数:崎岖地形的挑战

非凸函数的误差曲面布满峰谷,对传统梯度下降法提出了严峻挑战。考虑函数f(x) = x^4 - 2x^2 + 1。其梯度为f'(x) = 4x^3 - 4x,在区间[-2, 2]内有多个极值点。

针对这种场景,我们优化了代码:

import numpy as np
from scipy.optimize import minimize

def gradient_descent(x0, alpha, num_iter):
    result = minimize(lambda x: (x - 2)**4 - 2*(x - 2)** 2 + 1, x0, method='BFGS', options={'maxiter': num_iter})
    return result.x

x0 = 5  # 初始值
alpha = 0.1  # 学习率
num_iter = 100  # 迭代次数

result = gradient_descent(x0, alpha, num_iter)
print(f"最优解:{result:.4f}")

通过使用BFGS算法作为优化器,我们可以克服非凸函数的挑战,找到全局最优解。

二元函数:多维空间的探索

二元函数的误差曲面更加复杂多变。考虑函数f(x, y) = (x - 2)^2 + (y - 3)^2。其梯度为∇f(x, y) = [2(x - 2), 2(y - 3)]。

import numpy as np
from scipy.optimize import minimize

def gradient_descent(x0, y0, alpha, num_iter):
    result = minimize(lambda params: (params[0] - 2)**2 + (params[1] - 3)** 2, x0=np.array([x0, y0]), method='BFGS', options={'maxiter': num_iter})
    return result.x

x0 = 5  # 初始值
y0 = 4  # 初始值
alpha = 0.1  # 学习率
num_iter = 100  # 迭代次数

result = gradient_descent(x0, y0, alpha, num_iter)
print(f"最优解:{result}")

运行代码后,算法成功找到了最优解[2, 3]。

算法依赖性:步履轻盈还是沉重

初始值的影响

传统梯度下降法对初始值的选择十分敏感。不同的初始值可能导致算法收敛到不同的极值点。为了避免陷入局部最优解,通常采用多组不同的初始值进行多次优化,取其中最优的结果。

学习率的选择

学习率α控制着算法的步长。太小,算法收敛缓慢;太大,算法可能不稳定,甚至导致发散。选择合适的学习率至关重要。可以通过试错法或者自适应学习率策略来确定最优的α值。

代码优化:提升速度和效率

针对大规模数据或复杂模型,优化代码可以显著提升梯度下降法的运行效率。一些常见的优化技巧包括:

  • 向量化代码:使用NumPy等库进行向量化运算,提高并行化程度。
  • 批处理:将数据分批处理,降低单次迭代的计算量。
  • 提前计算:对不变的梯度项进行预计算,减少重复计算。

结语

传统梯度下降法是一种强大的优化算法,它能高效地解决各种机器学习问题。通过深入理解算法原理、细致调参和代码优化,我们可以充分发挥其优势,征服误差曲面的险峰,找到问题的最优解。