授课语音

梯度下降算法及其变种

梯度下降算法(Gradient Descent)是一种用于优化机器学习模型的优化算法。它通过计算损失函数的梯度(即损失函数关于模型参数的导数),然后根据这个梯度调整模型参数,逐步使模型的预测误差最小化。

梯度下降是深度学习中最常用的优化算法,广泛应用于各种神经网络训练任务中。其变种包括批量梯度下降、随机梯度下降、迷你批量梯度下降和Adam等算法,它们在计算效率、收敛速度和稳定性方面各有不同。


1. 梯度下降算法的核心思想

梯度下降算法的基本目标是最小化一个损失函数(如均方误差),并通过更新模型参数来逐步降低损失值。

给定模型参数θ和损失函数L(θ),梯度下降的更新规则为:

θ = θ - η * ∇L(θ)

其中:

  • θ是模型的参数;
  • η是学习率(Learning Rate),控制每次更新的步长;
  • ∇L(θ)是损失函数关于模型参数θ的梯度。

梯度下降的核心思想就是通过沿着梯度方向反向调整参数,直到找到损失函数的最小值。


2. 梯度下降的变种

根据每次计算梯度时使用的数据量不同,梯度下降可分为三种常见的变种:

2.1 批量梯度下降(Batch Gradient Descent)

批量梯度下降是最传统的梯度下降方法,每次迭代时都使用整个训练集来计算梯度。因此,更新规则为:

θ = θ - η * (1/m) * Σ∇L(θ)

其中,m是训练集的样本数,Σ∇L(θ)表示所有样本梯度的平均值。

特点:

  • 优点:每次迭代都计算了全局最优的梯度,收敛到最优解的理论性强。
  • 缺点:计算量大,特别是在数据集非常大的情况下,内存开销和计算时间较长。

2.2 随机梯度下降(Stochastic Gradient Descent,SGD)

随机梯度下降每次只使用一个样本来更新模型参数,而不是使用整个训练集。更新规则为:

θ = θ - η * ∇L(θ)  (对于每个样本)

每次迭代时,随机选择一个样本,计算该样本的梯度,并更新模型参数。

特点:

  • 优点:计算速度快,因为每次只需要一个样本就能进行参数更新,适用于大规模数据集。
  • 缺点:由于每次迭代只使用一个样本,梯度波动较大,容易导致训练不稳定,收敛速度较慢,甚至无法稳定收敛。

2.3 迷你批量梯度下降(Mini-Batch Gradient Descent)

迷你批量梯度下降结合了批量梯度下降和随机梯度下降的优点,每次迭代使用一个小批量(mini-batch)样本来计算梯度,并更新参数。更新规则为:

θ = θ - η * (1/m) * Σ∇L(θ)  (对于mini-batch)

其中,m是每次迭代使用的小批量样本的大小。

特点:

  • 优点:比批量梯度下降计算效率高,且比随机梯度下降更稳定。通过使用小批量数据,既能保持梯度估计的准确性,又能加速训练过程。
  • 缺点:需要选择适当的mini-batch大小,通常是超参数之一。

2.4 Adam(Adaptive Moment Estimation)

Adam优化器是目前使用最广泛的深度学习优化算法之一。Adam结合了动量(Momentum)和自适应学习率(Adaptive Learning Rate)的优点,自动调整每个参数的学习率,使得训练更加高效。

更新规则为:

m_t = β1 * m_(t-1) + (1 - β1) * ∇L(θ)
v_t = β2 * v_(t-1) + (1 - β2) * (∇L(θ))²
θ = θ - η * m_t / (√v_t + ε)

其中:

  • m_tv_t是梯度的移动平均和平方梯度的移动平均;
  • β1β2分别控制一阶矩(动量)和二阶矩(自适应学习率)的衰减率;
  • ε是防止分母为零的小常数。

特点:

  • 优点:Adam能自适应地调整每个参数的学习率,能在稀疏梯度和大规模数据上表现得更好。适用于大多数深度学习任务,且通常不需要过多的超参数调优。
  • 缺点:相比简单的SGD,Adam可能会消耗更多的内存,且在某些任务上表现可能不如SGD。

3. 梯度下降算法变种的比较

算法 优点 缺点
批量梯度下降 计算稳定,理论上收敛到最优解 计算量大,训练时间长,内存开销大
随机梯度下降 计算速度快,适合大规模数据集 收敛不稳定,梯度波动较大,可能需要更多的迭代才能收敛
迷你批量梯度下降 计算效率高,较为稳定,结合了批量和随机的优点 需要调节小批量的大小,计算复杂度相对较高
Adam 自适应学习率,快速收敛,广泛应用于深度学习 内存消耗较大,部分任务可能不如SGD表现好

4. 代码实现

以下是使用不同梯度下降算法进行线性回归的Python代码实现,展示了如何使用批量梯度下降、随机梯度下降和Adam优化器。

4.1 批量梯度下降实现

import numpy as np

# 生成模拟数据
X = np.random.rand(100, 1)
y = 2 * X + 1 + np.random.randn(100, 1) * 0.1  # 真实关系为y = 2x + 1

# 初始化参数
theta = np.random.randn(2, 1)
X_b = np.c_[np.ones((100, 1)), X]  # 增加偏置项
learning_rate = 0.1
n_iterations = 1000
m = len(X_b)

# 批量梯度下降
for iteration in range(n_iterations):
    gradients = 2/m * X_b.T.dot(X_b.dot(theta) - y)  # 计算梯度
    theta -= learning_rate * gradients  # 更新参数

print(f"优化后的参数:{theta}")

4.2 随机梯度下降实现

# 随机梯度下降
for iteration in range(n_iterations):
    for i in range(m):
        random_index = np.random.randint(m)
        xi = X_b[random_index:random_index+1]
        yi = y[random_index:random_index+1]
        gradients = 2 * xi.T.dot(xi.dot(theta) - yi)  # 计算单个样本的梯度
        theta -= learning_rate * gradients  # 更新参数

print(f"优化后的参数:{theta}")

4.3 Adam优化器实现

# 初始化Adam相关参数
m = np.zeros_like(theta)
v = np.zeros_like(theta)
t = 0
beta1 = 0.9
beta2 = 0.999
epsilon = 1e-8

# Adam优化
for iteration in range(n_iterations):
    t += 1
    gradients = 2/m * X_b.T.dot(X_b.dot(theta) - y)  # 计算梯度
    m = beta1 * m + (1 - beta1) * gradients
    v = beta2 * v + (1 - beta2) * (gradients ** 2)
    
    m_hat = m / (1 - beta1 ** t)
    v_hat = v / (1 - beta2 ** t)
    
    theta -= learning_rate * m_hat / (np.sqrt(v_hat) + epsilon)

print(f"优化后的参数:{theta}")

5. 总结

  • 梯度下降是深度学习中最基础的优化算法,旨在通过调整模型参数来最小化损失函数。
  • 批量梯度下降适用于较小数据集,但计算效率较低,特别是对于大规模数据集。
  • 随机梯度下降计算速度快,但可能会因梯度波动较大而导致收敛不稳定。
  • 迷你批量梯度下降通过平衡批量和随机的优点,适用于大规模数据集。
  • Adam优化器通过自适应调整学习率,快速收敛,广泛应用于深度学习任务。
去1:1私密咨询

系列课程: