Lecture 2: Regularization and Optimization
课程概述
本节课深入探讨了深度学习和计算机视觉中的两个核心概念:正则化(Regularization)和优化(Optimization)。课程首先回顾了图像分类任务和线性分类器的基本原理,然后详细讲解了如何通过损失函数评估模型性能,如何使用正则化防止过拟合,以及如何通过各种优化算法(特别是梯度下降及其变体)来训练模型。
目录
1. 回顾:图像分类与线性分类器
1.1 图像分类任务
图像分类是计算机视觉的核心任务之一,目标是将输入图像映射到预定义的类别标签集合中。
任务定义:
- 输入:图像(像素值的多维数组)
- 输出:类别标签(如:猫、狗、鸟、鹿、卡车)
1.2 图像分类的挑战
-
语义鸿沟(Semantic Gap)
- 人类感知:看到"猫"
- 计算机表示:像素值的数值网格
-
图像变化
- 光照变化:不同光照条件下像素强度不同
- 遮挡(Occlusion):物体部分被遮挡
- 形变(Deformation):物体可以弯曲、扭转
- 背景杂波:物体与背景融合
- 类内变化(Intra-class Variation):同一类别的不同实例外观差异大
1.3 K近邻分类器(K-Nearest Neighbors)
基本思想:对于新的数据点,找到训练集中距离最近的K个样本,采用多数投票决定类别。
距离度量:
-
L1距离(曼哈顿距离) :
d L 1 ( x , y ) = ∑ i = 1 n ∣ x i − y i ∣ d_{L1}(\mathbf{x}, \mathbf{y}) = \sum_{i=1}^{n} |x_i - y_i| dL1(x,y)=i=1∑n∣xi−yi∣ -
L2距离(欧氏距离) :
d L 2 ( x , y ) = ∑ i = 1 n ( x i − y i ) 2 d_{L2}(\mathbf{x}, \mathbf{y}) = \sqrt{\sum_{i=1}^{n} (x_i - y_i)^2} dL2(x,y)=i=1∑n(xi−yi)2
超参数选择:
- 使用训练集/验证集/测试集划分
- 在验证集上选择最优的K值
- 在测试集上评估最终性能
1.4 线性分类器
模型公式 :
f ( x , W ) = W x + b f(\mathbf{x}, \mathbf{W}) = \mathbf{W}\mathbf{x} + \mathbf{b} f(x,W)=Wx+b
其中:
- x \mathbf{x} x:输入图像(展平为向量,大小为 32 × 32 × 3 = 3072 32 \times 32 \times 3 = 3072 32×32×3=3072)
- W \mathbf{W} W:权重矩阵(大小为 C × D C \times D C×D,C为类别数,D为特征维度)
- b \mathbf{b} b:偏置向量(大小为 C C C)
三种理解视角:
-
代数视角:每一行权重与输入向量做点积,得到该类别的得分
-
模板视角:每一行权重可视化为该类别的"模板"
-
几何视角:每一行权重定义了特征空间中的决策边界(超平面)
局限性:线性分类器只能学习线性决策边界,无法处理非线性可分的数据
2. 损失函数
2.1 损失函数的定义
损失函数(Loss Function) 量化了模型预测与真实标签之间的差距。
数学定义 :
L = 1 N ∑ i = 1 N L i ( f ( x i , W ) , y i ) + λ R ( W ) L = \frac{1}{N} \sum_{i=1}^{N} L_i(f(\mathbf{x}_i, \mathbf{W}), y_i) + \lambda R(\mathbf{W}) L=N1i=1∑NLi(f(xi,W),yi)+λR(W)
其中:
- 数据损失(Data Loss) : 1 N ∑ i = 1 N L i \frac{1}{N} \sum_{i=1}^{N} L_i N1∑i=1NLi - 衡量模型对训练数据的拟合程度
- 正则化损失(Regularization Loss) : λ R ( W ) \lambda R(\mathbf{W}) λR(W) - 防止过拟合
- λ \lambda λ:正则化强度(超参数)
2.2 Softmax损失(交叉熵损失)
Softmax函数 :将任意实数向量转换为概率分布
P ( y i = k ∣ x i ) = e s k ∑ j e s j P(y_i = k | \mathbf{x}i) = \frac{e^{s_k}}{\sum{j} e^{s_j}} P(yi=k∣xi)=∑jesjesk
交叉熵损失 :
L i = − log P ( y i = y t r u e ∣ x i ) = − log ( e s y t r u e ∑ j e s j ) L_i = -\log P(y_i = y_{true} | \mathbf{x}i) = -\log \left(\frac{e^{s{y_{true}}}}{\sum_{j} e^{s_j}}\right) Li=−logP(yi=ytrue∣xi)=−log(∑jesjesytrue)
特性:
- 当正确类别概率高时,损失低
- 当正确类别概率低时,损失高
- 鼓励模型输出高置信度的正确预测
3. 正则化(Regularization)
3.1 正则化的动机
核心思想:在训练数据上表现稍差,但在测试数据上表现更好。
直观例子:
- 模型F1:完美拟合所有训练点(可能过拟合)
- 模型F2:更简单的模型,训练误差稍高,但泛化能力更强
奥卡姆剃刀原则:在多个竞争假设中,优先选择最简单的。
3.2 L2正则化(权重衰减)
定义 :
R ( W ) = ∑ i , j W i , j 2 R(\mathbf{W}) = \sum_{i,j} W_{i,j}^2 R(W)=i,j∑Wi,j2
特性:
- 惩罚大的权重值
- 偏好分散的权重分布
- 由于平方操作,小权重值的惩罚更小
- 导致权重值普遍较小但非零
梯度 :
∂ R ∂ W i , j = 2 W i , j \frac{\partial R}{\partial W_{i,j}} = 2W_{i,j} ∂Wi,j∂R=2Wi,j
3.3 L1正则化
定义 :
R ( W ) = ∑ i , j ∣ W i , j ∣ R(\mathbf{W}) = \sum_{i,j} |W_{i,j}| R(W)=i,j∑∣Wi,j∣
特性:
- 偏好稀疏的权重分布
- 导致许多权重值精确为0
- 可用于特征选择
梯度 :
∂ R ∂ W i , j = sign ( W i , j ) \frac{\partial R}{\partial W_{i,j}} = \text{sign}(W_{i,j}) ∂Wi,j∂R=sign(Wi,j)
3.4 L1 vs L2 对比示例
考虑两组权重,得分相同:
- w 1 = [ 1 , 0 , 0 , 0 ] \mathbf{w}_1 = [1, 0, 0, 0] w1=[1,0,0,0]
- w 2 = [ 0.25 , 0.25 , 0.25 , 0.25 ] \mathbf{w}_2 = [0.25, 0.25, 0.25, 0.25] w2=[0.25,0.25,0.25,0.25]
L2正则化:
- R ( w 1 ) = 1 2 = 1 R(\mathbf{w}_1) = 1^2 = 1 R(w1)=12=1
- R ( w 2 ) = 4 × ( 0.25 ) 2 = 0.25 R(\mathbf{w}_2) = 4 \times (0.25)^2 = 0.25 R(w2)=4×(0.25)2=0.25
- L2偏好 w 2 \mathbf{w}_2 w2(更分散)
L1正则化:
- R ( w 1 ) = 1 R(\mathbf{w}_1) = 1 R(w1)=1
- R ( w 2 ) = 4 × 0.25 = 1 R(\mathbf{w}_2) = 4 \times 0.25 = 1 R(w2)=4×0.25=1
- 两者相同(但实践中L1会倾向于稀疏解)
3.5 正则化的作用
- 表达模型偏好:通过选择不同的正则化项表达对权重的偏好
- 提高泛化能力:简化模型,防止过拟合
- 改善优化:L2正则化的凸性有助于优化过程
4. 优化(Optimization)
4.1 优化问题
目标 :找到使损失函数最小的权重 W ∗ \mathbf{W}^* W∗
W ∗ = arg min W L ( W ) \mathbf{W}^* = \arg\min_{\mathbf{W}} L(\mathbf{W}) W∗=argWminL(W)
4.2 损失景观(Loss Landscape)
可视化比喻:
- 垂直轴(Z轴):损失值
- 水平轴(X, Y轴):模型参数
- 目标:找到景观中的最低点
关键限制:
- 我们是"蒙眼"的 - 只能感知当前位置的局部梯度
- 无法直接看到全局最优点
4.3 策略1:随机搜索(不推荐)
python
# 伪代码
best_W = None
best_loss = float('inf')
for i in range(1000):
W_random = np.random.randn(D, C)
loss = compute_loss(W_random, X_train, y_train)
if loss < best_loss:
best_W = W_random
best_loss = loss
性能:CIFAR-10上约15.5%准确率(远低于99.7%的最优水平)
4.4 策略2:跟随斜率(梯度下降)
核心思想:计算当前位置的斜率,朝下坡方向移动
5. 梯度下降及其变体
5.1 梯度的数学定义
一维导数 :
d f d x = lim h → 0 f ( x + h ) − f ( x ) h \frac{df}{dx} = \lim_{h \to 0} \frac{f(x+h) - f(x)}{h} dxdf=h→0limhf(x+h)−f(x)
多维梯度 :
∇ W L = [ ∂ L ∂ W 1 , 1 , ∂ L ∂ W 1 , 2 , ... , ∂ L ∂ W m , n ] \nabla_{\mathbf{W}} L = \left[\frac{\partial L}{\partial W_{1,1}}, \frac{\partial L}{\partial W_{1,2}}, \ldots, \frac{\partial L}{\partial W_{m,n}}\right] ∇WL=[∂W1,1∂L,∂W1,2∂L,...,∂Wm,n∂L]
重要性质:
- 梯度方向是函数上升最快的方向
- 负梯度方向是函数下降最快的方向
5.2 梯度计算方法
方法1:数值梯度(慢,近似)
python
def numerical_gradient(f, W, h=1e-5):
grad = np.zeros_like(W)
for i in range(W.shape[0]):
for j in range(W.shape[1]):
W[i,j] += h
fpos = f(W)
W[i,j] -= 2*h
fneg = f(W)
W[i,j] += h # 恢复
grad[i,j] = (fpos - fneg) / (2*h)
return grad
方法2:解析梯度(快,精确)
- 使用微积分链式法则推导
- 精确且高效
- 推荐使用,并用数值梯度验证
5.3 梯度下降算法
基本算法:
python
# 伪代码
while True:
dW = compute_gradient(W, X, y) # 计算梯度
W = W - learning_rate * dW # 参数更新
数学形式 :
W t + 1 = W t − α ∇ W L ( W t ) \mathbf{W}_{t+1} = \mathbf{W}t - \alpha \nabla{\mathbf{W}} L(\mathbf{W}_t) Wt+1=Wt−α∇WL(Wt)
其中 α \alpha α 是学习率(步长)
5.4 随机梯度下降(SGD)
动机:计算全部数据的梯度开销太大
Mini-batch SGD:
python
# 伪代码
for epoch in range(num_epochs):
# 随机打乱数据
shuffle(X_train, y_train)
for i in range(0, N, batch_size):
# 提取mini-batch
X_batch = X_train[i:i+batch_size]
y_batch = y_train[i:i+batch_size]
# 计算梯度(仅在mini-batch上)
dW = compute_gradient(W, X_batch, y_batch)
# 更新参数
W = W - learning_rate * dW
关键概念:
- Batch Size:每次更新使用的样本数(如256)
- Epoch:遍历整个训练集一次
- 优势:计算高效,引入随机性有助于逃离局部最优
5.5 SGD的问题
问题1:狭窄山谷中的震荡
- 在陡峭方向上大幅震荡
- 在平缓方向上进展缓慢
- 原因:条件数(condition number)高 - Hessian矩阵最大/最小特征值比值大
问题2:局部最优和鞍点
- 局部最优:梯度为零但不是全局最优
- 鞍点:某些方向是最小值,其他方向是最大值
- 高维空间中鞍点更常见
问题3:梯度噪声
- Mini-batch采样引入噪声
- 更新方向不精确
5.6 动量法(Momentum)
动机:像滚动的球一样积累速度
算法:
python
v = 0 # 速度初始化
while True:
dW = compute_gradient(W, X_batch, y_batch)
v = rho * v - learning_rate * dW # 更新速度
W = W + v # 更新参数
数学形式 :
v t + 1 = ρ v t + ∇ W L ( W t ) \mathbf{v}_{t+1} = \rho \mathbf{v}t + \nabla{\mathbf{W}} L(\mathbf{W}t) vt+1=ρvt+∇WL(Wt)
W t + 1 = W t − α v t + 1 \mathbf{W}{t+1} = \mathbf{W}t - \alpha \mathbf{v}{t+1} Wt+1=Wt−αvt+1
参数:
- ρ \rho ρ:动量系数(通常0.9或0.99)
- 高动量 → 更依赖历史方向
优势:
- 穿越局部最优和鞍点
- 减少狭窄山谷中的震荡
- 在一致方向上加速
- 平滑梯度噪声
等价形式 :
v t + 1 = ρ v t − α ∇ W L ( W t ) \mathbf{v}_{t+1} = \rho \mathbf{v}t - \alpha \nabla{\mathbf{W}} L(\mathbf{W}t) vt+1=ρvt−α∇WL(Wt)
W t + 1 = W t + v t + 1 \mathbf{W}{t+1} = \mathbf{W}t + \mathbf{v}{t+1} Wt+1=Wt+vt+1
5.7 RMSprop
动机:在不同方向上自适应调整步长
算法:
python
grad_squared = 0
while True:
dW = compute_gradient(W, X_batch, y_batch)
grad_squared = decay_rate * grad_squared + (1 - decay_rate) * dW**2
W = W - learning_rate * dW / (np.sqrt(grad_squared) + 1e-7)
数学形式 :
s t = β s t − 1 + ( 1 − β ) ( ∇ W L ) 2 \mathbf{s}t = \beta \mathbf{s}{t-1} + (1-\beta) (\nabla_{\mathbf{W}} L)^2 st=βst−1+(1−β)(∇WL)2
W t + 1 = W t − α s t + ϵ ∇ W L \mathbf{W}_{t+1} = \mathbf{W}_t - \frac{\alpha}{\sqrt{\mathbf{s}t} + \epsilon} \nabla{\mathbf{W}} L Wt+1=Wt−st +ϵα∇WL
效果:
- 在陡峭方向上减小步长(除以大的梯度平方)
- 在平缓方向上增大步长(除以小的梯度平方)
- 自动适应损失景观的几何形状
5.8 Adam优化器(最流行)
Adam = Momentum + RMSprop
算法:
python
m = 0 # 一阶矩估计(动量)
v = 0 # 二阶矩估计(RMSprop)
t = 0 # 时间步
while True:
t += 1
dW = compute_gradient(W, X_batch, y_batch)
# 更新一阶和二阶矩估计
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 = W - learning_rate * m_hat / (np.sqrt(v_hat) + 1e-8)
数学形式 :
m t = β 1 m t − 1 + ( 1 − β 1 ) ∇ W L \mathbf{m}t = \beta_1 \mathbf{m}{t-1} + (1-\beta_1) \nabla_{\mathbf{W}} L mt=β1mt−1+(1−β1)∇WL
v t = β 2 v t − 1 + ( 1 − β 2 ) ( ∇ W L ) 2 \mathbf{v}t = \beta_2 \mathbf{v}{t-1} + (1-\beta_2) (\nabla_{\mathbf{W}} L)^2 vt=β2vt−1+(1−β2)(∇WL)2
m ^ t = m t 1 − β 1 t , v ^ t = v t 1 − β 2 t \hat{\mathbf{m}}_t = \frac{\mathbf{m}_t}{1-\beta_1^t}, \quad \hat{\mathbf{v}}_t = \frac{\mathbf{v}t}{1-\beta_2^t} m^t=1−β1tmt,v^t=1−β2tvt
W t + 1 = W t − α v ^ t + ϵ m ^ t \mathbf{W}{t+1} = \mathbf{W}_t - \frac{\alpha}{\sqrt{\hat{\mathbf{v}}_t} + \epsilon} \hat{\mathbf{m}}_t Wt+1=Wt−v^t +ϵαm^t
推荐超参数:
- β 1 = 0.9 \beta_1 = 0.9 β1=0.9
- β 2 = 0.999 \beta_2 = 0.999 β2=0.999
- α = 1 e − 3 \alpha = 1e-3 α=1e−3 或 5 e − 4 5e-4 5e−4
- ϵ = 1 e − 8 \epsilon = 1e-8 ϵ=1e−8
偏差修正的必要性:
- m 0 = v 0 = 0 \mathbf{m}_0 = \mathbf{v}_0 = 0 m0=v0=0(初始化为零)
- 早期时间步,矩估计偏向零
- 偏差修正解决初期步长过大的问题
5.9 AdamW(Adam with Decoupled Weight Decay)
关键区别:将权重衰减与梯度解耦
标准Adam:
python
dW = compute_gradient(W) + lambda * W # L2正则项包含在梯度中
AdamW:
python
dW = compute_gradient(W) # 不包含正则项
W = W - lr * m / sqrt(v) - lr * lambda * W # 单独应用权重衰减
优势:
- 权重衰减不影响动量计算
- 更好地分离优化和正则化
- 在许多任务上表现优于Adam(如Llama系列模型)
6. 学习率调度
6.1 学习率的重要性
学习率过高:
- 损失值爆炸
- 在最优点附近震荡
- 无法收敛
学习率过低:
- 收敛速度极慢
- 可能卡在鞍点
理想学习率:
- 快速下降
- 稳定收敛到较低损失
6.2 学习率衰减策略
1. 阶梯衰减(Step Decay)
python
if epoch % step_size == 0:
learning_rate *= gamma # 如 gamma=0.1
- 每隔固定epoch减小学习率
- ResNet训练中常用
2. 余弦退火(Cosine Annealing)
α t = α min + 1 2 ( α max − α min ) ( 1 + cos ( t π T ) ) \alpha_t = \alpha_{\min} + \frac{1}{2}(\alpha_{\max} - \alpha_{\min})(1 + \cos(\frac{t\pi}{T})) αt=αmin+21(αmax−αmin)(1+cos(Ttπ))
python
lr = lr_min + 0.5 * (lr_max - lr_min) * (1 + np.cos(epoch / max_epoch * np.pi))
- 平滑减小学习率
- 非常流行
3. 线性衰减(Linear Decay)
α t = α 0 ( 1 − t T ) \alpha_t = \alpha_0 (1 - \frac{t}{T}) αt=α0(1−Tt)
4. 逆平方根衰减(Inverse Square Root)
α t = α 0 t \alpha_t = \frac{\alpha_0}{\sqrt{t}} αt=t α0
6.3 学习率预热(Warmup)
策略:训练初期线性增加学习率
python
if epoch < warmup_epochs:
lr = lr_max * epoch / warmup_epochs
else:
lr = cosine_decay(epoch - warmup_epochs)
常见组合:
- Linear Warmup + Cosine Decay
- Linear Warmup + Step Decay
优势:
- 避免初期大步长导致的不稳定
- 在大batch size训练中尤其重要
6.4 线性缩放规则(Linear Scaling Rule)
经验法则 :
学习率 ∝ Batch Size \text{学习率} \propto \text{Batch Size} 学习率∝Batch Size
示例:
- Batch size从256增加到512
- 学习率也应从0.1增加到0.2
理论依据:
- Batch size越大,梯度估计越准确
- 可以使用更大的步长
7. 总结与展望
7.1 核心要点总结
正则化:
- 在训练数据上表现稍差,在测试数据上表现更好
- L2正则化偏好分散权重,L1正则化偏好稀疏权重
- 权重衰减是一种正则化策略
优化算法:
- SGD:简单但可能震荡、卡在鞍点
- Momentum:积累速度,穿越局部最优
- RMSprop:自适应调整不同方向的步长
- Adam/AdamW:结合Momentum和RMSprop,最常用
学习率调度:
- 训练过程中动态调整学习率
- Warmup + Cosine Decay是流行组合
- Linear Scaling Rule用于调整batch size
7.2 实践建议
首选配置:
- 优化器:Adam或AdamW
- 初始学习率:1e-3或5e-4
- 调度策略:Warmup + Cosine Decay
- Beta值: β 1 = 0.9 , β 2 = 0.999 \beta_1=0.9, \beta_2=0.999 β1=0.9,β2=0.999
调试技巧:
- 绘制损失曲线判断学习率是否合适
- 使用梯度检查验证反向传播实现
- 从小模型开始验证流程
7.3 二阶优化方法(简介)
牛顿法(Newton's Method):
- 使用Hessian矩阵(二阶导数)
- 拟合局部二次函数
- 更精确的步长选择
局限性:
- Hessian矩阵计算和存储开销巨大( O ( D 2 ) O(D^2) O(D2))
- 对于大规模深度学习模型不实用
- 仅在小模型上可行
7.4 展望:神经网络
下一讲主题:多层神经网络
核心思想:
- 堆叠多个线性层
- 层间插入非线性激活函数(如ReLU)
- 能够学习非线性决策边界
示例 :
h = ReLU ( W 1 x + b 1 ) \mathbf{h} = \text{ReLU}(\mathbf{W}_1 \mathbf{x} + \mathbf{b}_1) h=ReLU(W1x+b1)
y = W 2 h + b 2 \mathbf{y} = \mathbf{W}_2 \mathbf{h} + \mathbf{b}_2 y=W2h+b2
优势:
- 可以处理线性不可分数据
- 通过多层变换学习复杂特征表示
参考资料
- CS231n课程笔记:http://cs231n.github.io/
- 优化算法论文 :
- Adam: Kingma & Ba, 2014
- AdamW: Loshchilov & Hutter, 2017
- 相关概念 :
- 条件数(Condition Number)
- Hessian矩阵
- 凸优化(Convex Optimization)
附录:重要公式汇总
损失函数 :
L = 1 N ∑ i = 1 N L i + λ R ( W ) L = \frac{1}{N} \sum_{i=1}^{N} L_i + \lambda R(\mathbf{W}) L=N1i=1∑NLi+λR(W)
L2正则化 :
R ( W ) = ∑ i , j W i , j 2 R(\mathbf{W}) = \sum_{i,j} W_{i,j}^2 R(W)=i,j∑Wi,j2
L1正则化 :
R ( W ) = ∑ i , j ∣ W i , j ∣ R(\mathbf{W}) = \sum_{i,j} |W_{i,j}| R(W)=i,j∑∣Wi,j∣
梯度下降 :
W t + 1 = W t − α ∇ W L \mathbf{W}_{t+1} = \mathbf{W}t - \alpha \nabla{\mathbf{W}} L Wt+1=Wt−α∇WL
Momentum :
v t + 1 = ρ v t + ∇ W L , W t + 1 = W t − α v t + 1 \mathbf{v}{t+1} = \rho \mathbf{v}t + \nabla{\mathbf{W}} L, \quad \mathbf{W}{t+1} = \mathbf{W}t - \alpha \mathbf{v}{t+1} vt+1=ρvt+∇WL,Wt+1=Wt−αvt+1
Adam :
m t = β 1 m t − 1 + ( 1 − β 1 ) ∇ L \mathbf{m}t = \beta_1 \mathbf{m}{t-1} + (1-\beta_1) \nabla L mt=β1mt−1+(1−β1)∇L
v t = β 2 v t − 1 + ( 1 − β 2 ) ( ∇ L ) 2 \mathbf{v}t = \beta_2 \mathbf{v}{t-1} + (1-\beta_2) (\nabla L)^2 vt=β2vt−1+(1−β2)(∇L)2
W t + 1 = W t − α v ^ t + ϵ m ^ t \mathbf{W}_{t+1} = \mathbf{W}_t - \frac{\alpha}{\sqrt{\hat{\mathbf{v}}_t} + \epsilon} \hat{\mathbf{m}}_t Wt+1=Wt−v^t +ϵαm^t