Skip to content

正则化与优化

约 2120 个字 预计阅读时间 14 分钟

上节回顾:线性分类器

线性分类器可以从三个角度理解:

线性分类器的三种视角

  1. 代数视角\(f(x,W) = Wx\)
  2. 视觉视角:每个类别有一个模板
  3. 几何视角:超平面划分空间

[线性分类器三种视角的示意图:代数矩阵乘法,类别模板图像,几何空间划分]

线性分类器的损失函数量化了我们对权重的偏好:

  • 数据集:\((x, y)\)
  • 得分函数:\(f(x;W,b) = Wx + b\)(线性分类器)
  • 损失函数:
    • Softmax损失:\(L_i = -\log\frac{\exp(s_{y_i})}{\sum_j \exp(s_j)}\)
    • SVM损失:\(L_i = \sum_{j\neq y_i} \max(0, s_j - s_{y_i} + 1)\)

问题:损失函数鼓励在训练数据上表现良好,但我们实际关心的是测试数据的性能。


过拟合

过拟合定义

当模型在训练数据上表现太好,但在未见过的数据上表现不佳时,我们称之为过拟合。

过拟合示例

以一维输入、两个类别的线性分类器(使用Softmax损失)为例:

\[s_i = W_i x + b_i$$ $$P_i = \frac{\exp(s_i)}{\exp(s_0) + \exp(s_1)}$$ $$L = -\log P_y\]

[过拟合示例图:显示两个模型在训练数据上都有完美准确率,但一个模型在训练点之间有不自然的"悬崖"]

虽然两个模型在训练数据上都有完美的准确率,但一个模型在没有训练数据的区域表现出过度自信,可能导致泛化能力差。


正则化:超越训练误差

我们的目标是找到一个权重矩阵W,使得:

  1. 模型在训练数据上表现良好
  2. 模型能够很好地泛化到未见过的数据

为此,我们引入正则化。

损失函数带正则化

\[L(W) = \frac{1}{N}\sum_{i=1}^N L_i(f(x_i, W), y_i) + \lambda R(W)\]

其中: - 第一项是数据损失:模型预测应该匹配训练数据 - 第二项是正则化:防止模型在训练数据上表现得太好 - λ是一个超参数,控制正则化强度

常见的正则化方法

  1. L2正则化\(R(W) = \sum_{i,j} W_{i,j}^2\)
  2. L1正则化\(R(W) = \sum_{i,j} |W_{i,j}|\)
  3. 更复杂的方法
    • Dropout
    • Batch normalization
    • Cutout, Mixup, Stochastic depth等

正则化:偏好更简单的模型

[正则化效果图:显示带有正则化的模型如何避免在训练点之间形成"悬崖"]

使用正则化后,尖锐的"悬崖"模型的损失会增加,鼓励更平滑的解决方案。

正则化:表达偏好

L2正则化偏好权重"分散":

w = [1, 1, 1, 1]
w1 = [1, 0, 0, 0]
w2 = [0.25, 0.25, 0.25, 0.25]

假设w1和w2产生相同的预测(所以数据损失相同),但: - ||w1||^2 = 1 - ||w2||^2 = 0.25

因此L2正则化更喜欢w2。


优化

我们的目标是找到最优权重:

\[W^* = \arg\min_W L(W)\]

随机搜索(不好的方法)

随机尝试不同的权重,保留表现最好的一个。 - 在CIFAR-10上,随机搜索可以达到约15.5%的准确率 - 但最先进的方法可以达到~95%

梯度下降:沿着斜率走

在一维中,函数的导数给出了斜率:

\[\frac{df}{dx} = \lim_{h\to 0} \frac{f(x+h) - f(x)}{h}\]

在多维中,梯度是每个维度上的偏导数向量。 - 任何方向上的斜率是该方向与梯度的点积 - 最陡下降的方向是负梯度

计算梯度的方法

  1. 数值梯度

    • 近似计算
    • 速度慢:O(维度数量)
    • 容易编写
    • 例:计算第一维度的导数
      (loss(W+h) - loss(W))/h ≈ dL/dW[0]
      
  2. 解析梯度

    • 精确计算
    • 速度快
    • 容易出错
    • 使用微积分推导公式

梯度检查

在实践中:总是使用解析梯度,但用数值梯度检查实现。这被称为梯度检查。


梯度下降算法

批量梯度下降(Batch Gradient Descent)

迭代地朝负梯度方向前进(局部最陡下降的方向):

\[W_{t+1} = W_t - \alpha \nabla L(W_t)\]

超参数: - 权重初始化方法 - 步数 - 学习率

[梯度下降示意图:显示在二维空间中沿负梯度方向更新权重]

当数据集很大时,计算完整的梯度代价很高:

\[\nabla_W L(W) = \frac{1}{N}\sum_{i=1}^N \nabla_W L_i(x_i, y_i, W) + \lambda \nabla_W R(W)\]

随机梯度下降(SGD)

使用小批量(minibatch)样本来近似梯度:

\[\nabla_W L(W) \approx \frac{1}{|B|}\sum_{i \in B} \nabla_W L_i(x_i, y_i, W) + \lambda \nabla_W R(W)\]

其中B是小批量样本的索引集合。

可以将损失视为数据分布上的期望,通过采样来近似:

\[L(W) = \mathbb{E}_{x,y \sim p_{data}} [L(x, y, W) + \lambda R(W)]$$ $$\approx \frac{1}{|B|}\sum_{i \in B} L(x_i, y_i, W) + \lambda R(W)\]

超参数: - 权重初始化 - 步数 - 学习率 - 批量大小 - 数据采样方法


SGD的问题

1. 高条件数问题

当损失函数在一个方向上变化快,在另一个方向上变化慢时,会有什么问题?

[高条件数问题图:显示在具有不同曲率的方向上梯度下降的行为]

SGD会在陡峭方向上抖动,在平缓方向上进展缓慢。

2. 局部最小值或鞍点

当损失函数有局部最小值或鞍点时,梯度为零,梯度下降会停滞。

[局部最小值和鞍点图:显示这些点的梯度为零,导致优化停滞]

3. 梯度噪声

小批量梯度是真实梯度的嘈杂估计,可能导致优化不稳定。


改进的优化算法

SGD + 动量(Momentum)

基本思想:累积过去的梯度形成"速度",帮助优化器跨越局部最小值和鞍点。

v_{t+1} = \rho v_t + \nabla L(W_t)
W_{t+1} = W_t - \alpha v_{t+1}

其中ρ是动量系数,通常为0.9或0.99。

[动量更新示意图:显示如何结合当前梯度和速度进行更新]

动量有助于: - 越过局部最小值 - 通过鞍点 - 减轻梯度噪声影响 - 加速平缓方向上的收敛

Nesterov动量

改进的动量版本,"预先看"到使用速度更新后的位置,计算该位置的梯度:

v_{t+1} = \rho v_t + \nabla L(W_t - \alpha \rho v_t)
W_{t+1} = W_t - \alpha v_{t+1}

[Nesterov动量示意图:显示"预先看"机制]

AdaGrad

基本思想:为每个参数维度设置不同的自适应学习率:

cache += dW ** 2
W += - learning_rate * dW / (sqrt(cache) + eps)

AdaGrad自动调整学习率: - 沿陡峭方向减小步长 - 沿平缓方向增大步长

[AdaGrad效果图:显示如何适应不同曲率]

RMSProp:"漏斗型AdaGrad"

改进AdaGrad,使用移动平均代替完整历史:

cache = decay_rate * cache + (1 - decay_rate) * dW ** 2
W += - learning_rate * dW / (sqrt(cache) + eps)

Adam:RMSProp + 动量

结合动量和自适应学习率:

m = beta1 * m + (1 - beta1) * dW      # 一阶矩估计
v = beta2 * v + (1 - beta2) * dW ** 2  # 二阶矩估计
m_hat = m / (1 - beta1 ** t)           # 偏差修正
v_hat = v / (1 - beta2 ** t)           # 偏差修正
W += - learning_rate * m_hat / (sqrt(v_hat) + eps)

实用建议

Adam使用以下参数是许多模型的良好起点: - beta1 = 0.9 - beta2 = 0.999 - learning_rate = 1e-3, 5e-4或1e-4


L2正则化与权重衰减

L2正则化和权重衰减在SGD中是等价的:

L2正则化

L(W) = L_data(W) + λ||W||^2
g_t = ∇L_data(W_t) + 2λW_t  # 梯度包含正则化项
W_{t+1} = W_t - αg_t

权重衰减

L(W) = L_data(W)
g_t = ∇L_data(W_t)
W_{t+1} = W_t - αg_t - αλW_t

注意

L2正则化和权重衰减对于SGD和SGD+动量是等价的,但对于自适应方法(AdaGrad、RMSProp、Adam等)则不同!

AdamW:解耦的权重衰减

改进的Adam版本,使用正确的权重衰减。

实践建议

AdamW应该是新问题的"默认"优化器。


二阶优化

一阶优化使用梯度构建线性近似: 1. 使用梯度构建线性近似 2. 迈步最小化这个近似

二阶优化使用梯度和Hessian构建二次近似: 1. 使用梯度和Hessian构建二次近似 2. 迈步最小化这个近似

[一阶与二阶优化对比图:显示二阶优化在低曲率区域采取更大步长]

二阶泰勒展开:

\[L(W + \Delta W) \approx L(W) + \nabla L(W)^T \Delta W + \frac{1}{2} \Delta W^T H \Delta W\]

解得牛顿参数更新:

\[\Delta W = -H^{-1} \nabla L(W)\]

问题:对于深度学习不可行,因为: - Hessian有O(N^2)个元素 - 求逆需要O(N^3)操作 - N通常是数百万级

L-BFGS

  • 拟牛顿方法,不需要形成/存储完整的Hessian逆矩阵
  • 在全批量、确定性模式下效果很好
  • 但在小批量设置中表现不佳

实践建议

  1. Adam是许多情况下的良好默认选择
  2. SGD+动量可能优于Adam,但可能需要更多调整

  3. 如果可以进行全批量更新,尝试L-BFGS

  4. 记得禁用所有噪声源

  5. 超参数搜索建议

  6. Adam: lr ∈ [1e-4, 3e-4, 1e-3]
  7. SGD+Momentum: lr ∈ [1e-3, 1e-2, 1e-1], momentum = 0.9
  8. 推荐使用学习率衰减

总结

  1. 使用线性模型进行图像分类问题
  2. 使用损失函数表达对不同权重选择的偏好
  3. 使用正则化防止对训练数据的过拟合
  4. 使用随机梯度下降最小化损失函数并训练模型

[总结图像:展示Softmax和SVM损失函数]