梯度下降算法原理解析:从数学基础到实现细节

1次阅读
没有评论

共计 1490 个字符,预计需要花费 4 分钟才能阅读完成。

image.webp

背景介绍

在机器学习中,我们经常需要解决各种优化问题。简单来说,优化就是找到一组参数,使得某个目标函数(通常是损失函数)的值最小化。梯度下降(Gradient Descent)就是解决这类问题最常用的方法之一。

梯度下降算法原理解析:从数学基础到实现细节

数学原理

损失函数与梯度

假设我们的目标是最小化一个连续可微的函数 $J(\theta)$,其中 $\theta$ 是模型的参数。梯度下降的核心思想是:沿着函数当前点的梯度反方向(即下降最快的方向)逐步调整参数。

数学表达式为:

$$\theta_{t+1} = \theta_t – \eta \cdot \nabla J(\theta_t)$$

其中:

  • $\eta$ 是学习率(learning rate),控制每次更新的步长
  • $\nabla J(\theta_t)$ 是损失函数在 $\theta_t$ 处的梯度

算法变体

批量梯度下降(BGD)

每次迭代使用全部训练数据计算梯度。优点是稳定,缺点是计算量大。

随机梯度下降(SGD)

每次迭代随机选取一个样本计算梯度。优点是计算快,缺点是波动大。

小批量梯度下降(Mini-batch GD)

折中方案,每次使用一小批(batch)数据计算梯度。兼具效率与稳定性,是最常用的变体。

Python 实现

以下是使用 NumPy 实现的基本梯度下降算法:

import numpy as np
import matplotlib.pyplot as plt

# 定义损失函数(以二次函数为例)def loss_function(theta):
    return theta**2 + 5*theta + 6

# 定义梯度函数
def gradient(theta):
    return 2*theta + 5

# 梯度下降实现
def gradient_descent(start_theta, learning_rate, n_iterations):
    theta = start_theta
    history = []

    for i in range(n_iterations):
        grad = gradient(theta)
        theta = theta - learning_rate * grad
        history.append(theta)

    return theta, history

# 参数设置
start_theta = 10.0
learning_rate = 0.1
n_iterations = 50

# 运行梯度下降
theta_min, theta_history = gradient_descent(start_theta, learning_rate, n_iterations)

# 可视化收敛过程
thetas = np.linspace(-10, 10, 100)
plt.plot(thetas, loss_function(thetas))
plt.scatter(theta_history, [loss_function(t) for t in theta_history], c='r')
plt.title('Gradient Descent Convergence')
plt.xlabel('Theta')
plt.ylabel('Loss')
plt.show()

调参技巧

学习率选择

学习率太大可能导致震荡甚至发散,太小则收敛缓慢。通常可以从 0.01 开始尝试。

收敛判断

可以设置以下停止条件:

  • 梯度范数小于某个阈值
  • 损失函数变化小于某个阈值
  • 达到最大迭代次数

常见问题

局部最优

在高维空间中,局部最优问题通常不如想象中严重,但仍是需要注意的问题。

梯度消失

当梯度变得非常小时,参数更新几乎停止。这在深层神经网络中尤为常见。

思考题

  1. 如何证明梯度方向确实是函数值下降最快的方向?
  2. 动量法(Momentum)如何改进标准梯度下降?
  3. 比较 Adam 优化器与标准梯度下降的异同
正文完
 0
评论(没有评论)