深度学习基础
感知机 (Perceptron)
通俗例子: 想象一个非常简单的**“决策机器人”**,它要根据一些输入信息来做一个二选一的决定(比如“去”或“不去”,“是”或“否”)。
-
收集信息 (输入 Inputs): 机器人收集多个信息片段,比如:
- 天气好不好?(x₁)
- 朋友去不去?(x₂)
- 今天心情如何?(x₃) 这些信息可以是数值(比如天气评分1-10)或者0/1的布尔值。
-
给信息赋予权重 (Weights): 机器人对每个信息的重要性有不同的看法:
- 天气可能很重要 (w₁ = 0.5)
- 朋友去不去非常重要 (w₂ = 0.8)
- 心情一般重要 (w₃ = 0.3) 这些权重表示了每个输入对最终决策的影响程度。
-
加权求和并加上偏好 (Weighted Sum + Bias): 机器人把每个信息和它的权重相乘,然后加起来,得到一个总分。它可能还有一个固有的“偏好”或“门槛”(偏置项 bias,b)。
z = (x₁ * w₁) + (x₂ * w₂) + (x₃ * w₃) + b
-
做决策 (激活函数 Activation Function - 阶跃函数):
- 如果总分
z
大于某个阈值(或者简单地说,如果z > 0
),机器人就决定“去”(输出1)。 - 如果总分
z
小于或等于某个阈值(或者z ≤ 0
),机器人就决定“不去”(输出0或-1)。 这个决策过程就像一个开关,要么开要么关。
- 如果总分
感知机就是这样一个简单的二分类模型。
结合技术点:
- 核心思想 (Core Idea):
- 由 Frank Rosenblatt 于1957年提出,是最早的人工神经网络模型之一。
- 一个线性二分类器。它试图找到一个超平面 (hyperplane) 来分隔两种不同类别的数据点。
- 模拟了单个神经元的基本行为:接收多个输入信号,根据这些信号的加权和以及一个激活函数来决定是否“激活”(输出)。
- 数学表示 (Mathematical Representation):
- 输入 (Inputs):
x = (x₁, x₂, ..., xₙ)
(一个特征向量) - 权重 (Weights):
w = (w₁, w₂, ..., wₙ)
(一个权重向量) - 偏置 (Bias):
b
(一个标量) - 加权和 (Weighted Sum / Net Input):
z = w · x + b = Σ(wᵢ * xᵢ) + b
- 激活函数 (Activation Function): 通常是符号函数 (sign function) 或 阶跃函数 (step function)。
output = 1
ifz > θ
(或z > 0
如果θ
被吸收到b
中)output = 0
(或-1
) ifz ≤ θ
(或z ≤ 0
)
- 模型的输出是一个离散的类别标签。
- 输入 (Inputs):
- 学习算法 (Perceptron Learning Algorithm):
- 一种迭代算法,用于调整权重
w
和偏置b
。 - 过程:
- 初始化权重
w
和偏置b
(通常为0或小的随机数)。 - 对于训练集中的每个样本
(x, y_true)
(其中y_true
是真实标签): a. 计算模型的预测输出y_pred
。 b. 如果y_pred ≠ y_true
(预测错误): * 更新权重:w := w + η * (y_true - y_pred) * x
* 更新偏置:b := b + η * (y_true - y_pred)
(其中η
是学习率,y_true
和y_pred
通常取 +1 和 -1) - 重复步骤2,直到所有样本都被正确分类,或者达到最大迭代次数。
- 初始化权重
- 一种迭代算法,用于调整权重
- 目的/用途 (Purpose / Use Cases):
- 解决线性可分 (linearly separable) 的二分类问题。
- 例如,逻辑门 AND、OR 的实现。
- 优点:
- 简单,易于理解和实现。
- 如果数据是线性可分的,感知机学习算法保证在有限次迭代后收敛到一个解。
- 缺点:
- 只能解决线性可分问题。 对于线性不可分的问题(如异或 XOR 问题),它无法找到一个有效的超平面来分隔数据。这是感知机的一个重大局限。
- 如果数据不是严格线性可分的,算法可能不会收敛,权重会持续振荡。
- 输出是离散的,不能提供概率信息。
- 阶跃激活函数不可导(或导数为0),不适用于基于梯度的优化方法(如反向传播)。
多层感知机 (Multilayer Perceptron, MLP)
通俗例子: 想象之前的“决策机器人”变得更聪明了,它不再是简单地把所有信息加权求和然后做一次决策,而是组建了一个“决策委员会”。
多层感知机就是通过引入一个或多个“隐藏层”来克服单个感知机的线性限制。
结合技术点:
- 核心思想 (Core Idea):
- 一种前馈神经网络 (Feedforward Neural Network),由至少三层节点组成:一个输入层 (Input Layer),一个或多个隐藏层 (Hidden Layer(s)),以及一个输出层 (Output Layer)。
- 每个节点(除了输入节点)都是一个带有非线性激活函数的神经元(通常不再是阶跃函数,而是如 Sigmoid, Tanh, ReLU 等平滑可导的函数)。
- 通过在层与层之间引入非线性激活函数,MLP 能够学习和表示非线性关系,从而解决线性不可分的问题(如XOR问题)。
- 信息从输入层单向流向输出层,没有反馈环路(与循环神经网络RNN不同)。
- 数学表示 (Mathematical Representation - 简化版,一个隐藏层):
- 输入层到隐藏层:
- 隐藏层第
j
个神经元的净输入:z_j^(h) = w_j^(h) · x + b_j^(h)
- 隐藏层第
j
个神经元的激活输出:a_j^(h) = g(z_j^(h))
(其中g
是非线性激活函数,如Sigmoid, ReLU)
- 隐藏层第
- 隐藏层到输出层:
- 输出层第
k
个神经元的净输入:z_k^(o) = w_k^(o) · a^(h) + b_k^(o)
(其中a^(h)
是隐藏层所有神经元的激活输出向量) - 输出层第
k
个神经元的激活输出:y_k_pred = f(z_k^(o))
(其中f
是输出层的激活函数,如Sigmoid用于二分类概率,Softmax用于多分类概率,线性函数用于回归)
- 输出层第
- 输入层到隐藏层:
- 学习算法 (反向传播 Backpropagation):
- MLP通常使用反向传播算法结合梯度下降 (Gradient Descent) 及其变种(如Adam, SGD with momentum)来训练。
- 过程:
- 前向传播 (Forward Pass): 将输入数据通过网络,计算每一层的输出,直到得到最终的预测结果。
- 计算损失 (Loss Calculation): 将预测结果与真实标签进行比较,计算损失函数的值(如交叉熵损失、均方误差)。
- 反向传播 (Backward Pass): 从输出层开始,将损失逐层向后传播,利用链式法则计算损失函数对网络中每个权重和偏置的梯度。
- 参数更新 (Parameter Update): 根据计算出的梯度和选择的优化算法,更新网络中的权重和偏置,以减小损失。
- 重复以上步骤,直到损失收敛或达到预设的训练轮数。
- 目的/用途 (Purpose / Use Cases):
- 分类任务: 图像识别、文本分类、情感分析等。
- 回归任务: 预测房价、股票价格等。
- 能够学习复杂的非线性映射。
- 优点:
- 通用近似定理 (Universal Approximation Theorem): 理论上,具有一个足够宽的隐藏层(或多个隐藏层)的MLP可以以任意精度近似任何连续函数。这意味着它具有强大的表示能力。
- 能够解决线性不可分的问题。
- 是许多更复杂深度学习模型的基础。
- 缺点:
- 容易过拟合: 如果模型过于复杂或训练数据不足,MLP可能会在训练数据上表现很好,但在未见过的数据上表现差。需要正则化技术(如L1/L2正则化、Dropout)来缓解。
- 需要调整的超参数多: 网络结构(层数、每层神经元数量)、激活函数的选择、学习率、优化器选择等。
- 可能陷入局部最优: 梯度下降算法可能会陷入损失函数的局部最小值而不是全局最小值(尽管在实践中,对于高维度的神经网络,这通常不是主要问题)。
- 训练可能较慢: 尤其是对于深层和宽层的网络。
- “黑箱”模型: 对于复杂的MLP,其内部决策过程可能难以解释。
理解感知机是理解MLP的起点,而MLP则是通往更复杂的神经网络结构(如卷积神经网络CNN、循环神经网络RNN、Transformer等)的重要桥梁。、
好的,我们来简单介绍一下几种常见的激活函数,并重点讨论如何根据不同情况挑选它们。
激活函数 (Activation Function)
在神经网络中,激活函数被应用到神经元的加权和(z = w·x + b
)之后,引入非线性因素。没有非线性激活函数,无论神经网络有多少层,它本质上都只是一个线性模型,无法学习复杂的数据模式。
常见的激活函数:
-
Sigmoid 函数
- 公式:
σ(z) = 1 / (1 + e^(-z))
- 输出范围:
(0, 1)
- 形状: S 型曲线。
- 优点:
- 输出在 (0, 1) 之间,可以解释为概率(尤其是在二分类问题的输出层)。
- 平滑可导。
- 缺点:
- 梯度消失 (Vanishing Gradient): 当输入
z
非常大或非常小时,Sigmoid 的导数(梯度)接近于0。在深层网络中,这会导致反向传播时梯度逐层衰减,使得靠近输入层的权重更新非常缓慢,甚至停止学习。 - 输出非零中心 (Not zero-centered): 输出恒为正,这可能导致后续层输入的非零中心化,可能影响梯度下降的效率。
- 计算相对复杂(指数运算)。
- 梯度消失 (Vanishing Gradient): 当输入
- 公式:
-
Tanh (双曲正切) 函数
- 公式:
tanh(z) = (e^z - e^(-z)) / (e^z + e^(-z))
(也可以表示为2 * sigmoid(2z) - 1
) - 输出范围:
(-1, 1)
- 形状: S 型曲线,但中心在0。
- 优点:
- 输出零中心 (Zero-centered): 相比 Sigmoid,这通常能使模型收敛更快。
- 平滑可导。
- 缺点:
- 梯度消失: 仍然存在梯度消失问题,只是程度比 Sigmoid 略轻(因为梯度范围比 Sigmoid 稍大)。
- 计算相对复杂(指数运算)。
- 公式:
-
ReLU (Rectified Linear Unit, 修正线性单元)
- 公式:
ReLU(z) = max(0, z)
- 输出范围:
[0, +∞)
- 形状: 输入为负时输出0,输入为正时输出等于输入。
- 优点:
- 有效缓解梯度消失: 当输入
z > 0
时,导数为1,梯度可以很好地传播。 - 计算非常高效: 只需要一个简单的比较和赋值操作。
- 收敛速度快: 在实践中,使用 ReLU 的网络通常比使用 Sigmoid 或 Tanh 的网络收敛更快。
- 稀疏性: 会使一部分神经元的输出为0,这可以引入网络的稀疏性,可能有助于特征提取。
- 有效缓解梯度消失: 当输入
- 缺点:
- Dying ReLU (神经元死亡): 如果一个神经元的输入在训练过程中持续为负,那么它的输出将一直是0,梯度也将一直是0,导致该神经元不再学习(“死亡”)。这通常发生在学习率设置过大或初始化不当时。
- 输出非零中心。
- 公式:
-
Leaky ReLU (带泄露的 ReLU)
- 公式:
LeakyReLU(z) = max(αz, z)
或者写成:z
ifz > 0
αz
ifz ≤ 0
(其中α
是一个小的正常数,如 0.01 或 0.2)
- 输出范围:
(-∞, +∞)
(如果α > 0
) - 形状: 类似于 ReLU,但在负输入区域有一个小的非零斜率。
- 优点:
- 解决了 Dying ReLU 问题: 即使输入为负,神经元仍然会有非零梯度,允许学习继续。
- 保留了 ReLU 的大部分优点(如计算效率、缓解梯度消失)。
- 缺点:
- 引入了一个新的超参数
α
需要调整(尽管通常对α
的选择不那么敏感)。 - 表现不一定总是优于 ReLU。
- 引入了一个新的超参数
- 变种:PReLU (Parametric ReLU),其中
α
不是固定的超参数,而是作为模型参数通过学习得到。
- 公式:
-
Softmax 函数
- 公式:
Softmax(zᵢ) = e^(zᵢ) / Σ e^(zⱼ)
(对向量z
中的每个元素zᵢ
计算) - 输出范围: 每个输出元素在
(0, 1)
之间,且所有输出元素之和为 1。 - 形状: 将一个实数向量转换为概率分布。
- 用途:
- 专门用于多分类问题的输出层。
- 它将网络的原始输出(logits)转换为每个类别的概率。
- 优点:
- 输出可以直观地解释为概率。
- 与交叉熵损失函数(Cross-Entropy Loss)结合使用效果很好。
- 缺点:
- 通常不用于隐藏层。
- 如果 logits 之间的差异很大,可能会导致输出概率非常接近0或1,可能影响数值稳定性(但通常有数值稳定的实现)。
- 公式:
如何挑选激活函数?
选择激活函数没有绝对的“黄金法则”,但可以遵循一些通用的指导原则和经验:
-
输出层 (Output Layer):
- 二分类问题 (Binary Classification):
- 通常使用 Sigmoid 函数,因为它的输出 (0, 1) 可以直接解释为属于正类的概率。
- 多分类问题 (Multi-class Classification):
- 通常使用 Softmax 函数,它会输出一个概率分布,表示样本属于每个类别的概率。
- 回归问题 (Regression):
- 通常不使用激活函数(或者说使用一个线性激活函数
f(z) = z
),因为目标是预测任意连续值,而不是限制在特定范围内或解释为概率。 - 如果回归目标值有特定范围(如非负),可以在输出层使用相应的激活函数(如 ReLU 用于非负输出)。
- 通常不使用激活函数(或者说使用一个线性激活函数
- 二分类问题 (Binary Classification):
-
隐藏层 (Hidden Layers):
- 首选通常是 ReLU:
- 由于其简单性、计算效率以及在实践中通常能带来更快的收敛速度和更好的性能(尤其是在较深的网络中,能有效缓解梯度消失)。
- 从 ReLU 开始尝试是一个好的起点。
- 如果遇到 Dying ReLU 问题:
- 可以尝试 Leaky ReLU 或其变体 (如 PReLU, ELU)。
- 检查学习率是否过大,或者尝试更好的权重初始化方法 (如 He 初始化)。
- Tanh:
- 在某些特定场景下(例如一些循环神经网络 RNN 的变体,如 LSTM、GRU 的门控单元中)仍然被使用,因为它输出零中心。
- 有时在 ReLU 表现不佳时,可以尝试 Tanh 作为备选。
- Sigmoid:
- 在现代深度神经网络的隐藏层中已经很少使用,主要是因为梯度消失和非零中心问题。
- 它仍然可能出现在一些旧的网络结构中,或者在需要将输出压缩到 (0,1) 范围的特定门控机制中(如 LSTM 中的某些门)。
- 首选通常是 ReLU:
-
实验和经验:
- 没有免费午餐定理: 没有哪个激活函数在所有情况下都是最优的。最好的选择往往取决于具体的数据集、网络架构和任务。
- 进行实验: 尝试不同的激活函数,并通过验证集的性能来评估哪种最适合你的问题。
- 关注研究进展: 新的激活函数不断被提出和研究 (如 Swish, GELU 等,常用于 Transformer 模型)。了解最新的研究成果可能有助于你做出更好的选择。
总结挑选策略:
- 输出层: 根据任务类型(二分类用 Sigmoid,多分类用 Softmax,回归用线性或无激活)。
- 隐藏层:
- 默认尝试 ReLU。
- 如果 ReLU 出现神经元死亡问题,尝试 Leaky ReLU / PReLU / ELU。
- Tanh 可以作为 ReLU 表现不佳时的备选,或者在需要零中心输出的特定结构中使用。
- 尽量避免在深层网络的隐藏层中使用 Sigmoid。
- 始终通过实验验证你的选择。
记住,激活函数的选择是神经网络设计中的一个重要超参数,合理的选择可以显著影响模型的训练效率和最终性能。
损失函数 (Loss Function) / 代价函数 (Cost Function)
在机器学习(尤其是监督学习)中,损失函数用来衡量模型预测结果与真实标签之间的差异(即“损失”或“误差”)。模型训练的目标就是通过调整模型参数来最小化这个损失函数的值。
一个好的损失函数应该能够:
- 反映模型预测的准确程度。
- 对于错误的预测给予较大的惩罚。
- 通常是可微的(或至少有次梯度),以便使用基于梯度的优化算法(如梯度下降)来更新模型参数。
1. 均方误差 (Mean Squared Error, MSE、L2 损失)
-
也称为 L2 损失 (L2 Loss)。
-
核心思想: 计算每个样本的预测值与真实值之差的平方,然后对所有样本的这些平方差取平均值。
-
公式:
MSE = (1/N) * Σ (yᵢ_true - yᵢ_pred)²
N
: 样本数量。yᵢ_true
: 第i
个样本的真实标签值。yᵢ_pred
: 第i
个样本的模型预测值。Σ
表示对所有样本求和。
-
通俗解释: 想象你在射箭,靶心是真实值,你射出的箭是预测值。
- 误差: 你的箭离靶心的距离。
- 平方误差: 这个距离的平方。为什么要平方?
- 惩罚大误差: 误差越大,平方后会变得更大,模型会更努力地去修正这些大错误。
- 消除负号: 确保误差总是正的。
- 数学特性好: 平方函数是凸函数,求导方便,有助于优化。
- 均方误差: 把所有箭的“平方误差”加起来,然后取个平均,看看你平均射得有多偏。
-
主要用途/适用场景:
- 回归问题 (Regression Problems): 当目标是预测一个连续的数值时,MSE 是最常用的损失函数。
- 例如:预测房价、预测股票价格、预测温度。
- 当假设误差服从高斯分布时,最小化 MSE 等价于最大似然估计。
- 回归问题 (Regression Problems): 当目标是预测一个连续的数值时,MSE 是最常用的损失函数。
-
优点:
- 数学上易于处理,可导,且导数计算简单。
- 对于较大的误差给予较大的惩罚。
- 损失函数是凸的(对于线性回归),保证能找到全局最优解。
-
缺点:
- 对异常值 (Outliers) 敏感: 因为误差是平方的,如果数据中存在离群点(预测值与真实值差异极大的点),这些点会对 MSE 产生非常大的影响,可能导致模型过于关注这些异常点而牺牲其他正常点的表现。
- 量纲问题:MSE 的单位是目标变量单位的平方,有时不直观。其平方根 RMSE (Root Mean Squared Error) 在解释上更直观,单位与目标变量相同。
-
例子: 真实房价: [200万, 300万, 250万] 预测房价: [210万, 280万, 230万] MSE = (1/3) * [(200-210)² + (300-280)² + (250-230)²] = (1/3) * [(-10)² + (20)² + (20)²] = (1/3) * [100 + 400 + 400] = (1/3) * 900 = 300 (单位是 万平方)
2. 交叉熵 (Cross-Entropy Loss)
-
也称为对数损失 (Log Loss)。
-
核心思想: 衡量两个概率分布之间的差异。在分类问题中,这两个概率分布是:
- 真实概率分布: 通常是一个独热编码 (one-hot encoded) 的向量,表示样本实际属于哪个类别(真实类别的概率为1,其他类别为0)。
- 模型预测的概率分布: 模型输出的样本属于每个类别的概率(通常由 Softmax 或 Sigmoid 函数产生)。 交叉熵损失越小,说明模型的预测概率分布与真实概率分布越接近。
-
公式:
-
二分类交叉熵 (Binary Cross-Entropy, BCE Loss): 通常用于二分类问题,其中只有一个输出节点(使用 Sigmoid 激活函数,输出样本属于正类的概率
p
)。BCE Loss = - (1/N) * Σ [yᵢ_true * log(pᵢ) + (1 - yᵢ_true) * log(1 - pᵢ)]
N
: 样本数量。yᵢ_true
: 第i
个样本的真实标签 (0 或 1)。pᵢ
: 模型预测第i
个样本属于正类 (类别1) 的概率。log
: 通常是自然对数 (ln)。- 解释:
- 如果
yᵢ_true = 1
(真实为正类),损失是-log(pᵢ)
。pᵢ
越接近1,损失越小;pᵢ
越接近0,损失越大(趋向无穷)。 - 如果
yᵢ_true = 0
(真实为负类),损失是-log(1 - pᵢ)
。1-pᵢ
(属于负类的概率) 越接近1(即pᵢ
越接近0),损失越小;1-pᵢ
越接近0(即pᵢ
越接近1),损失越大。
- 如果
-
分类交叉熵 (Categorical Cross-Entropy, CCE Loss): 通常用于多分类问题(有多个类别,输出层使用 Softmax 激活函数)。
CCE Loss = - (1/N) * Σ Σ_{c=1}^{M} yᵢ,c_true * log(pᵢ,c_pred)
N
: 样本数量。M
: 类别数量。yᵢ,c_true
: 指示函数,如果样本i
的真实类别是c
,则为1,否则为0 (通常是 one-hot 编码的真实标签)。pᵢ,c_pred
: 模型预测样本i
属于类别c
的概率。Σ_{c=1}^{M}
表示对所有类别求和。- 解释: 对于每个样本,我们只关心其真实类别对应的预测概率。如果真实类别是
k
,那么该样本的损失就是-log(pᵢ,k_pred)
。模型对真实类别的预测概率pᵢ,k_pred
越高,损失越小。
-
-
通俗解释 (以多分类为例): 想象你在参加一个多项选择题考试,每道题只有一个正确答案。
- 真实答案: 你知道正确答案是C。
- 你的预测概率: 你对每个选项都有一个相信它是正确答案的概率(比如 A:10%, B:20%, C:60%, D:10%)。
- 交叉熵的惩罚: 如果你对正确答案C的预测概率很高(比如60%或更高),那么你的“损失”就很小。如果你对正确答案C的预测概率很低(比如只给了10%),那么你的“损失”就很大。交叉熵就是用来量化这种“预测概率与真实答案之间的不匹配程度”。
-
主要用途/适用场景:
- 分类问题 (Classification Problems):
- 二分类问题: 使用二分类交叉熵 (BCE Loss)。
- 多分类问题: 使用分类交叉熵 (CCE Loss)。
- 当模型的输出是概率时,交叉熵是衡量其性能的自然选择。
- 在信息论中,交叉熵衡量了用一个概率分布(模型的预测)来编码另一个真实概率分布所需的平均比特数。
- 分类问题 (Classification Problems):
-
优点:
- 对于分类问题,尤其是在输出层使用 Sigmoid 或 Softmax 时,交叉熵损失函数通常能提供比 MSE 更好的梯度特性,有助于模型更快地收敛。
- 当预测概率远离真实标签时,会给予较大的惩罚。
- 与 Sigmoid/Softmax 结合使用时,梯度计算相对简洁。
-
缺点:
- 如果模型预测的概率非常接近0或1,而真实标签相反(比如真实为1,预测概率接近0),log 函数会导致损失值非常大,甚至数值不稳定(但在实际实现中通常有平滑处理,如
log(p + epsilon)
)。
- 如果模型预测的概率非常接近0或1,而真实标签相反(比如真实为1,预测概率接近0),log 函数会导致损失值非常大,甚至数值不稳定(但在实际实现中通常有平滑处理,如
-
例子 (二分类): 真实标签 (y_true): [1, 0, 1] (1表示垃圾邮件, 0表示非垃圾邮件) 模型预测概率 (p_pred, 属于垃圾邮件的概率): [0.9, 0.2, 0.6]
损失计算: 样本1: y=1, p=0.9 =>
-(1 * log(0.9) + (1-1) * log(1-0.9)) = -log(0.9)
样本2: y=0, p=0.2 =>-(0 * log(0.2) + (1-0) * log(1-0.2)) = -log(0.8)
样本3: y=1, p=0.6 =>-(1 * log(0.6) + (1-1) * log(1-0.6)) = -log(0.6)
BCE Loss = (1/3) *[-log(0.9) - log(0.8) - log(0.6)]
总结对比:
特性 | 均方误差 (MSE) | 交叉熵 (Cross-Entropy) |
---|---|---|
主要用途 | 回归问题 | 分类问题 |
模型输出 | 连续数值 | 概率 (Sigmoid/Softmax 输出) |
衡量对象 | 预测值与真实值之间的数值差异 | 预测概率分布与真实概率分布之间的差异 |
对异常值 | 敏感 | 相对不那么敏感(但对极端错误概率敏感) |
梯度特性 | 简单,但有时可能导致学习缓慢(如Sigmoid+MSE) | 通常在分类中提供更好的梯度,加速学习 |
选择哪种损失函数很大程度上取决于你解决的问题类型(回归还是分类)以及模型的输出形式。
好的,我们来介绍一下几种常见的优化器,并讨论如何挑选它们。优化器在训练神经网络时扮演着至关重要的角色,它们负责根据损失函数计算出的梯度来更新模型的权重,目标是使损失函数最小化。
核心概念:梯度下降 (Gradient Descent)
大多数优化器都是基于梯度下降的思想。梯度下降的基本步骤是:
- 计算损失函数关于模型参数的梯度(表示损失函数在该点下降最快的方向)。
- 沿着梯度的反方向更新参数,步长由学习率 (Learning Rate) 控制。
参数_新 = 参数_旧 - 学习率 * 梯度
常见的优化器:
-
SGD (Stochastic Gradient Descent, 随机梯度下降)
- 核心思想: 不是用整个训练集的梯度来更新参数(这是批量梯度下降 BGD),也不是用单个样本的梯度(这是纯粹的随机梯度下降),而通常指的是小批量随机梯度下降 (Mini-batch SGD)。即每次更新使用一小批 (mini-batch) 样本计算的平均梯度。
- 优点:
- 相比 BGD,更新更频繁,收敛速度可能更快。
- 引入的噪声(因为每次只看一小批数据)有助于跳出局部最小值,可能找到更好的全局最小值。
- 计算和内存效率高,因为不需要一次性加载整个数据集。
- 缺点:
- 由于梯度的随机性,损失函数的下降过程可能会有较多振荡。
- 选择合适的学习率比较困难,对学习率敏感。
- 在梯度变化剧烈或稀疏的特征上可能表现不佳。
- 通俗例子: 摸黑下山,每次只看脚下一小块区域(mini-batch)的地形来决定下一步往哪走。
-
Momentum (动量SGD)
- 核心思想: 在 SGD 的基础上引入了“动量”的概念,模拟物理学中物体运动的惯性。它会累积过去梯度的方向,使得参数更新方向更加平滑,并能加速在梯度方向一致时的收敛,同时抑制振荡。
- 更新规则 (简化):
velocity_新 = β * velocity_旧 + (1-β) * 梯度
(β 通常取 0.9 左右,是动量参数)参数_新 = 参数_旧 - 学习率 * velocity_新
- 优点:
- 加速收敛,尤其是在梯度方向较为一致的平坦区域。
- 减少 SGD 在某些方向上的振荡。
- 有助于冲过一些平缓的鞍点或较浅的局部最小值。
- 缺点:
- 引入了新的超参数
β
(动量系数)。
- 引入了新的超参数
- 通俗例子: 推一个球下山。球不仅会沿着当前坡度滚,还会因为之前的惯性继续往前冲,更容易滚过小的坑洼。
-
AdaGrad (Adaptive Gradient Algorithm, 自适应梯度算法)
- 核心思想: 为模型中的每个参数维护一个自适应的学习率。对于更新不频繁的参数(梯度较小),使用较大的学习率;对于更新频繁的参数(梯度较大),使用较小的学习率。它通过累积参数过去所有梯度的平方来实现这一点。
- 更新规则 (简化):
累积平方梯度_新 = 累积平方梯度_旧 + 梯度²
参数_新 = 参数_旧 - (学习率 / √(累积平方梯度_新 + ε)) * 梯度
(ε 是一个很小的平滑项,防止分母为0) - 优点:
- 能够自动调整每个参数的学习率,不需要手动精细调整全局学习率。
- 对于稀疏数据(如 NLP 中的词嵌入)或特征尺度差异较大的情况表现较好。
- 缺点:
- 由于分母中的累积平方梯度会不断增大,学习率会单调递减,最终可能变得非常小,导致训练提前停止或收敛过慢。
- 通俗例子: 在不同地形上下山。在陡峭的地方(梯度大),步子迈小一点;在平缓的地方(梯度小),步子迈大一点。但走得越久,步子会整体变小。
-
RMSProp (Root Mean Square Propagation)
- 核心思想: 是对 AdaGrad 的改进,旨在解决其学习率过早且急剧下降的问题。它不是简单地累积所有历史平方梯度,而是使用指数加权移动平均来计算平方梯度,使得近期梯度的影响更大,远期梯度的影响逐渐减小。
- 更新规则 (简化):
移动平均平方梯度_新 = γ * 移动平均平方梯度_旧 + (1-γ) * 梯度²
(γ 是衰减率,如0.9)参数_新 = 参数_旧 - (学习率 / √(移动平均平方梯度_新 + ε)) * 梯度
- 优点:
- 缓解了 AdaGrad 学习率急剧下降的问题,在非凸优化问题上表现通常比 AdaGrad 好。
- 仍然具有自适应学习率的特性。
- 缺点:
- 引入了新的超参数
γ
(衰减率)。
- 引入了新的超参数
- 通俗例子: 类似 AdaGrad,但更关注近期的地形变化来调整步长,而不是把所有走过的路都同等重要地记下来。
-
Adam (Adaptive Moment Estimation)
- 核心思想: 可以看作是 Momentum 和 RMSProp 的结合体。它既利用了梯度的一阶矩估计(均值,像 Momentum 一样)来保持梯度的方向,又利用了梯度的二阶矩估计(未中心化的方差,像 RMSProp 一样)来调整每个参数的学习率。同时还进行了偏差校正,以解决初始化阶段一阶和二阶矩估计偏向于0的问题。
- 更新规则 (非常简化,忽略偏差校正):
一阶矩估计_新 (动量项) = β₁ * 一阶矩估计_旧 + (1-β₁) * 梯度
二阶矩估计_新 (缩放项) = β₂ * 二阶矩估计_旧 + (1-β₂) * 梯度²
参数_新 = 参数_旧 - 学习率 * (一阶矩估计_新 / (√(二阶矩估计_新) + ε))
(β₁ 通常为 0.9, β₂ 通常为 0.999) - 优点:
- 结合了 Momentum 和 RMSProp 的优点。
- 对每个参数计算自适应学习率。
- 通常在各种任务和网络结构上都表现良好,收敛速度快。
- 对初始学习率的选择相对不那么敏感(但仍然重要)。
- 是目前非常流行和默认推荐的优化器之一。
- 缺点:
- 引入了多个超参数 (
β₁
,β₂
,ε
),尽管通常使用默认值效果就不错。 - 在某些情况下,可能会找到与 SGD+Momentum 不同的(有时是次优的)解,或者泛化能力略逊于精心调整的 SGD+Momentum(尽管这种情况不常见)。
- 引入了多个超参数 (
- 通俗例子: 一个经验丰富的登山者,既会利用之前的冲劲(动量),也会根据当前脚下地形的崎岖程度(二阶矩)来调整每一步的幅度和方向。
如何挑选优化器?
选择优化器并没有一成不变的规则,但可以遵循以下一些指导原则:
-
Adam 通常是默认的好选择:
- 对于大多数问题和网络结构,Adam(或其变体如 AdamW,它在权重衰减的处理上有所改进)通常能提供快速的收敛和良好的性能。
- 如果你不确定从哪里开始,Adam 是一个安全的起点。 通常使用其推荐的默认超参数(如 PyTorch 中的
lr=0.001, betas=(0.9, 0.999), eps=1e-08
)。
-
SGD + Momentum 仍然是强有力的竞争者:
- 虽然 Adam 很流行,但精心调整学习率和动量的 SGD+Momentum 仍然可以在许多任务上达到最佳或接近最佳的性能,有时甚至在泛化能力上略优于 Adam。
- 如果你有足够的时间和计算资源进行超参数调整,或者你发现 Adam 的泛化能力不理想,可以尝试 SGD+Momentum。
- 对于计算机视觉等领域,SGD+Momentum 仍然被广泛使用。
-
考虑数据和模型的特性:
- 稀疏数据/特征: AdaGrad 或 RMSProp 可能表现更好,因为它们能为稀疏特征提供更大的更新。但 Adam 通常也能处理得不错。
- 非常深或复杂的网络: 自适应学习率方法 (Adam, RMSProp) 通常比手动调整学习率的 SGD 更容易获得好的结果。
-
实验和迭代:
- 没有免费午餐定理: 没有哪个优化器在所有情况下都是最优的。
- 进行实验: 尝试不同的优化器,并比较它们在你的验证集上的性能。
- 监控训练过程: 观察损失曲线的下降情况。如果下降太慢、振荡剧烈或卡在某个平台,可能需要调整优化器或其超参数。
-
学习率仍然是关键:
- 即使是自适应优化器,初始学习率仍然是一个非常重要的超参数。 如果学习率设置不当,即使是 Adam 也可能表现不佳。
- 考虑使用学习率调度器 (Learning Rate Schedulers),如指数衰减、余弦退火、warmup 等,来在训练过程中动态调整学习率,这通常能带来更好的性能。
-
关注最新的研究和社区实践:
- 优化器的研究仍在不断发展,新的算法和改进版本会不时出现。
- 了解特定领域(如NLP、CV)或特定模型架构(如Transformer)中常用的优化器和最佳实践。例如,对于Transformer模型,AdamW 配合特定的学习率调度(如带warmup的线性衰减或余弦退火)是常见的选择。
总结挑选策略:
- 首选 Adam 或 AdamW 作为起点,使用推荐的默认参数。
- 如果 Adam 表现不佳或你想追求极致性能,并且有资源进行调优,可以尝试 SGD + Momentum,并仔细调整学习率和动量。
- 对于特别稀疏的数据,可以考虑 AdaGrad 或 RMSProp,但通常 Adam 也能处理。
- 不要忘记调整学习率和使用学习率调度器,这对所有优化器都很重要。
- 最终通过实验来确定最适合你特定任务的优化器。
选择合适的优化器及其超参数是训练成功的关键因素之一,值得花时间去理解和实验。
反向传播算法
核心目标:
神经网络通过损失函数 (Loss Function) 来衡量其预测与真实值之间的差距。训练的目标是调整网络中的权重 (weights) 和偏置 (biases),以最小化这个损失函数。
反向传播算法就是一种高效计算损失函数相对于网络中所有权重和偏置的梯度 (gradients) 的方法。一旦我们有了这些梯度,就可以使用梯度下降等优化算法来更新参数。
为什么需要反向传播?
想象一个非常深的网络,有成千上万甚至百万的参数。如果我们要对每个参数单独计算它对最终损失的影响(比如通过微小的扰动来近似梯度),计算量会极其巨大。
反向传播利用了链式法则 (Chain Rule) 和动态规划 (Dynamic Programming) 的思想,使得梯度的计算变得高效。
核心思想:
-
前向传播 (Forward Propagation):
- 首先,输入数据通过网络一层一层地向前传播。
- 在每一层,神经元的输入是前一层神经元输出的加权和加上偏置,然后通过激活函数得到该神经元的输出。
- 这个过程一直持续到输出层,得到模型的最终预测结果。
- 然后,根据预测结果和真实标签计算损失函数的值。
-
反向传播 (Backward Propagation):
- 从后向前: 梯度计算从输出层开始,然后逐层向后传播到输入层。
- 链式法则的应用:
- 我们想知道损失函数
L
相对于网络中某个参数w
(例如,某一层中的一个权重)的梯度∂L/∂w
。 - 损失
L
是输出层激活值的函数,输出层激活值是其净输入(加权和)的函数,输出层净输入又是前一层激活值的函数,以此类推,最终会涉及到参数w
。 - 链式法则允许我们将这个复杂的依赖关系分解成一系列局部偏导数的乘积。
- 例如,如果
L
依赖于y
,y
依赖于z
,z
依赖于w
,那么∂L/∂w = (∂L/∂y) * (∂y/∂z) * (∂z/∂w)
。
- 我们想知道损失函数
- 误差信号的传播:
- 在输出层,可以直接计算损失函数相对于输出层激活值的梯度
∂L/∂a^(L)
(其中a^(L)
是输出层的激活值)。 - 然后,利用这个梯度和输出层激活函数相对于其净输入的导数,可以计算损失函数相对于输出层净输入
z^(L)
的梯度δ^(L) = ∂L/∂z^(L)
。这个δ^(L)
通常被称为输出层的“误差信号”。 - 接下来,这个误差信号
δ^(L)
会被用来计算损失函数相对于连接到输出层的权重和偏置的梯度。 - 更重要的是,这个误差信号会反向传播到前一层(隐藏层 L-1)。我们可以计算出隐藏层 L-1 的误差信号
δ^(L-1)
,它表示损失函数相对于隐藏层 L-1 净输入的梯度。 δ^(L-1)
的计算会依赖于δ^(L)
和连接层 L-1 和层 L 的权重。具体来说,δ^(L-1)
是δ^(L)
通过这些权重“加权反向传播”回来,并乘以层 L-1 激活函数导数的结果。
- 在输出层,可以直接计算损失函数相对于输出层激活值的梯度
- 逐层计算梯度:
- 一旦我们有了某一层的误差信号
δ^(l)
,就可以很容易地计算损失函数相对于连接到该层(即产生z^(l)
)的权重w^(l)
和偏置b^(l)
的梯度:∂L/∂w^(l) = a^(l-1) * δ^(l)
(其中a^(l-1)
是前一层的激活输出)∂L/∂b^(l) = δ^(l)
- 一旦我们有了某一层的误差信号
- 这个过程一直重复,直到梯度传播回网络的输入层附近。
简化步骤概览:
- 初始化权重和偏置。
- 对于每个训练样本 (或一批样本):
- a. 前向传播:
- 将输入数据送入网络。
- 逐层计算每个神经元的净输入 (
z
) 和激活输出 (a
),直到得到输出层的预测结果。 - 计算损失函数
L
。
- b. 反向传播:
- 计算输出层的误差信号
δ^(L)
:δ^(L) = ∂L/∂a^(L) * f'(z^(L))
(其中f'
是输出层激活函数的导数) - 逐层向后传播误差并计算梯度: 对于
l = L-1, L-2, ..., 1
(从倒数第二层到第一层):- 计算当前隐藏层
l
的误差信号δ^(l)
:δ^(l) = ( (W^(l+1))ᵀ * δ^(l+1) ) ⊙ g'(z^(l))
(其中W^(l+1)
是连接层l
和层l+1
的权重矩阵,ᵀ
表示转置,⊙
表示逐元素相乘,g'
是层l
激活函数的导数) - 计算连接到层
l
的权重和偏置的梯度:∂L/∂W^(l) = δ^(l) * (a^(l-1))ᵀ
∂L/∂b^(l) = δ^(l)
(通常对批次中的所有样本求和或平均)
- 计算当前隐藏层
- 计算输出层的误差信号
- a. 前向传播:
- 参数更新:
- 使用计算出的梯度和选择的优化算法(如 SGD, Adam)来更新网络中的所有权重和偏置:
W^(l) := W^(l) - η * ∂L/∂W^(l)
b^(l) := b^(l) - η * ∂L/∂b^(l)
(η 是学习率)
- 使用计算出的梯度和选择的优化算法(如 SGD, Adam)来更新网络中的所有权重和偏置:
- 重复步骤 2 和 3 直到模型收敛或达到预设的训练轮数。
关键要素和数学细节:
- 激活函数的导数: 反向传播算法要求激活函数是可微的(或者至少有次梯度)。常见的激活函数如 Sigmoid, Tanh, ReLU, LeakyReLU 都有简单的导数形式。
- Sigmoid:
σ'(z) = σ(z) * (1 - σ(z))
- Tanh:
tanh'(z) = 1 - tanh²(z)
- ReLU:
ReLU'(z) = 1
ifz > 0
,0
ifz < 0
(在 z=0处不可导,但实践中通常设为0或1)
- Sigmoid:
- 链式法则的优雅应用: 反向传播的核心就是巧妙地组织链式法则的计算,避免重复计算。每一层的误差信号
δ^(l)
包含了损失函数相对于该层净输入z^(l)
的所有必要信息。 - 计算图 (Computation Graph): 可以将神经网络的计算过程看作一个计算图。前向传播是在图上计算节点的值,反向传播则是在图上反向计算梯度。
- 动态规划思想: 梯度的计算是逐层进行的,并且后一层的梯度计算依赖于前一层已经计算好的梯度(误差信号),这体现了动态规划中“存储和重用中间结果”的思想。
通俗例子:
想象一条工厂流水线,有很多道工序(网络层),最终生产出一个产品(预测结果),然后质检员根据标准(真实标签)判断产品好坏并给出一个“不合格分数”(损失)。
- 前向传播: 原材料(输入数据)经过流水线每一道工序加工,最终变成成品。
- 计算损失: 质检员打分。
- 反向传播 (追责与改进):
- 最后一关追责: 质检员首先告诉最后一道工序的负责人,他的操作导致了多少“不合格分数”(输出层误差信号)。这位负责人根据这个反馈调整自己的操作参数(权重和偏置)。
- 逐级向前追责: 最后一道工序的负责人,会根据他收到的“不合格反馈”以及他与前一道工序的“交接情况”(连接权重),向前一道工序的负责人传递“责任信息”(反向传播误差信号)。
- 连锁反应: 前一道工序的负责人也根据收到的“责任信息”和自己的操作情况,调整自己的参数,并继续向前一道工序传递“责任信息”。
- 直到源头: 这个“追责”过程一直持续到流水线的最初几道工序,每一道工序的负责人都得到了关于如何改进操作以减少最终产品“不合格分数”的指导(梯度)。
- 集体改进: 所有工序负责人都根据得到的指导调整自己的操作。
- 重复: 不断生产、质检、追责、改进,直到产品合格率最高(损失最小)。
为什么反向传播如此重要?
- 效率: 它提供了一种计算所有参数梯度的系统且高效的方法,其计算复杂度与前向传播大致相当。
- 可行性: 使得训练具有大量参数的深层神经网络成为可能。没有反向传播,深度学习就不会有今天的成就。
理解反向传播的原理对于深入理解神经网络的训练过程和进行相关的研究与调试都非常有帮助。虽然现代深度学习框架(如 PyTorch, TensorFlow)会自动处理反向传播的计算,但了解其背后的机制仍然是重要的。
超参数:批量大小 (Batch Size)、学习率 (Learning Rate) 和迭代次数 (Epochs)。
1. 批量大小 (Batch Size)
-
定义: 在一次参数更新(即一次梯度下降的迭代)中,用来计算梯度的样本数量。
-
训练过程中的作用:
- 批量梯度下降 (Batch Gradient Descent, BGD): Batch Size = 整个训练集的大小。每次更新参数都使用整个训练集来计算梯度。
- 随机梯度下降 (Stochastic Gradient Descent, SGD): Batch Size = 1。每次更新参数只使用一个随机选择的样本来计算梯度。
- 小批量随机梯度下降 (Mini-batch Gradient Descent, MBGD): Batch Size 是一个介于 1 和整个训练集大小之间的正整数 (例如 32, 64, 128, 256)。这是目前最常用的方式,通常我们说的 SGD 实际上指的就是 MBGD。
-
通俗解释: 想象你在教一个学生(模型)识别图片中的猫。
- BGD (看所有照片再总结): 你把所有猫的照片一次性都给学生看,然后总结规律,调整学生的认知。
- SGD (看一张学一张): 你每次只给学生看一张猫的照片,学生看完一张就调整一下自己的认知。
- MBGD (看一小叠照片再总结): 你每次给学生看一小叠猫的照片(比如32张),学生看完这一小叠就总结一下规律,调整认知。
-
影响:
- Batch Size 较大:
- 优点:
- 梯度估计更准确,因为基于更多样本,噪声较小,损失函数下降方向更稳定。
- 在某些硬件(如 GPU)上,并行计算效率更高,训练速度可能更快(指每次迭代的时间,但总的收敛时间不一定)。
- 缺点:
- 需要更多的内存来存储一批数据及其梯度。
- 可能更容易陷入尖锐的局部最小值,泛化能力可能稍差(因为梯度太平滑,不容易跳出来)。
- 达到相同精度的总迭代次数可能更多(因为每次更新的“信息量”更集中)。
- 优点:
- Batch Size 较小:
- 优点:
- 引入的梯度噪声有助于模型跳出局部最小值,可能找到更好的全局最小值或更平坦的最小值,从而获得更好的泛化能力。
- 内存占用较小。
- 达到相同精度的总迭代次数可能更少(因为更新更频繁,学习更“敏捷”)。
- 缺点:
- 梯度估计噪声较大,损失函数下降过程可能非常振荡。
- 并行计算效率可能较低,每次迭代的时间可能更长。
- 可能需要更小的学习率来配合。
- 优点:
- Batch Size 较大:
-
如何选择:
- 没有固定的最佳值,通常需要根据具体任务、数据集大小、模型大小和硬件资源进行实验。
- 常见的值有 32, 64, 128, 256。
- 如果内存允许,可以尝试稍大的 Batch Size,但要注意观察泛化能力。
- 如果希望获得更好的泛化,可以尝试较小的 Batch Size,并配合合适的学习率。
- 通常会选择2的幂次方的值,这有时能更好地利用硬件的并行计算能力。
2. 学习率 (Learning Rate)
-
定义: 在梯度下降算法中,控制每次参数更新步长大小的超参数。它决定了模型在损失函数梯度的反方向上移动多远。
-
公式中的体现:
参数_新 = 参数_旧 - 学习率 * 梯度
-
通俗解释: 想象你蒙着眼睛下山(最小化损失函数)。
- 学习率: 你每走一步的“步子大小”。
- 学习率过大: 你每一步迈得太大,可能会直接跨过山谷的最低点,甚至跑到对面山坡上去了,导致损失函数来回振荡甚至发散。
- 学习率过小: 你每一步迈得太小,下山速度会非常慢,可能需要很长时间才能到达谷底,或者困在一个平缓的局部区域。
-
影响:
- 学习率过高:
- 损失函数可能在最小值附近振荡,难以收敛。
- 甚至可能导致损失函数发散(越来越大)。
- 学习率过低:
- 收敛速度非常缓慢,训练时间大大增加。
- 容易陷入不好的局部最小值或鞍点。
- 合适的学习率:
- 能够使损失函数稳定且较快地下降,最终收敛到较好的最小值。
- 学习率过高:
-
如何选择:
- 选择合适的学习率是训练神经网络中最具挑战性的任务之一。
- 经验范围: 通常从一些常见的值开始尝试,如 0.1, 0.01, 0.001, 0.0001。
- 实验: 通过实验观察损失曲线的变化来调整。
- 学习率查找器 (Learning Rate Finder): 一种技术,从小到大逐渐增加学习率,观察损失的变化,找到损失开始显著下降和开始发散的范围,从而选择一个合适的初始学习率(通常是损失下降最快区域的某个值)。
- 学习率调度器/衰减 (Learning Rate Schedulers/Decay): 在训练过程中动态调整学习率是一种常见的有效策略。
- 例如: 开始时使用较大的学习率以快速下降,随着训练的进行逐渐减小学习率以进行更精细的调整(如步进衰减、指数衰减、余弦退火、warmup 后衰减)。
- 与优化器的关系: 不同的优化器对学习率的敏感程度不同。例如,Adam 等自适应优化器对初始学习率的选择相对不那么敏感,但学习率仍然重要。
3. 迭代次数 (Epochs)
-
定义: 一个 Epoch 指的是整个训练数据集中的所有样本都被模型“过”了一遍(即前向传播和反向传播了一次)。
-
计算: 如果训练集有 N 个样本,Batch Size 为 B,那么一个 Epoch 需要
N / B
次迭代 (iterations) 或参数更新。这里的迭代通常指一个小批量的处理。 -
通俗解释: 想象你在复习一整本书(整个训练集)准备考试。
- 一个 Epoch: 你把这本书从头到尾完整地看了一遍。
- 多个 Epochs: 你把这本书完整地看了好几遍。
-
影响:
- Epochs 过少:
- 模型可能欠拟合 (Underfitting),即模型还没有充分学习到数据中的模式,在训练集和测试集上表现都不好。
- Epochs 过多:
- 模型可能过拟合 (Overfitting),即模型过度学习了训练数据中的噪声和细节,导致在训练集上表现很好,但在未见过的测试集上表现很差。
- 训练时间增加。
- 合适的 Epochs:
- 模型在训练集和验证集(或测试集)上都能达到较好的性能,并且两者性能差距不大。
- Epochs 过少:
-
如何选择:
- 监控验证集性能: 在每个 Epoch 结束后,在验证集上评估模型的性能(如损失或准确率)。
- 早停 (Early Stopping): 一种常用的策略。当模型在验证集上的性能在一定数量的 Epochs 内不再提升甚至开始下降时,就停止训练,以防止过拟合,并保存性能最佳时的模型。
- 观察训练曲线: 观察训练损失和验证损失(或准确率)的曲线。
- 如果两者都在下降,可以继续训练。
- 如果训练损失持续下降,但验证损失开始上升,说明可能发生了过拟合,应该考虑停止或采取其他正则化措施。
- 没有固定的最佳 Epochs 数量,它取决于数据集的复杂性、模型的大小、学习率等多种因素。
三者之间的关系和权衡:
- Batch Size 和学习率通常需要一起调整。 例如,如果增大了 Batch Size,梯度估计更稳定,可以适当增大学习率;如果减小了 Batch Size,梯度噪声增大,可能需要减小学习率。有一个经验法则叫“线性缩放规则”(Linear Scaling Rule),即当 Batch Size 乘以 k 时,学习率也乘以 k,但这并非总是有效。
- 学习率和 Epochs 共同决定了模型参数的更新总量和精细程度。
- 训练时间:
总训练时间 ≈ Epochs * (训练样本数 / Batch Size) * 单次迭代时间
。
总结:
- Batch Size: 决定每次参数更新基于多少样本,影响梯度估计的准确性和噪声水平,以及内存占用和训练速度。
- Learning Rate: 决定每次参数更新的步长,对模型的收敛速度和最终性能至关重要。
- Epochs: 决定整个训练数据集被模型学习多少遍,需要平衡欠拟合和过拟合。
这三个超参数是模型训练中最常调整的部分,需要通过实验、监控和经验来找到一个适合特定任务的最佳组合。
过拟合 (Overfitting)
- 定义: 当一个机器学习模型在训练数据上表现非常好(例如,损失很低,准确率很高),但在未见过的新数据(测试集或验证集)上表现显著较差时,我们就说这个模型发生了过拟合。
- 核心原因: 模型过于复杂,学习了训练数据中的噪声和随机波动,而不仅仅是潜在的真实模式。它“记住”了训练数据,而不是“理解”了数据的内在规律。
- 通俗解释:
- 想象一个学生准备考试。
- 正常学习: 学生理解了知识点和解题思路,在练习题(训练数据)和真实考试(测试数据)中都能取得好成绩。
- 过拟合 (死记硬背): 学生把练习册上的所有题目和答案都背了下来,所以在做练习题时能得满分。但是真实考试题目稍有变化,他就不会做了,因为他没有真正理解。
- 想象一个学生准备考试。
- 表现:
- 训练损失持续下降,但验证/测试损失在某个点后开始上升。
- 训练准确率很高,但验证/测试准确率远低于训练准确率,或者在某个点后开始下降。
- 导致过拟合的常见原因:
- 模型过于复杂: 例如,神经网络层数过多、神经元过多,参数量远大于数据量。
- 训练数据量不足: 模型没有足够的数据来学习普适的规律,更容易记住少量数据中的噪声。
- 特征过多: 包含了不相关或冗余的特征。
- 训练时间过长: 即使模型不那么复杂,训练太久也可能开始拟合噪声。
正则化 (Regularization)
- 定义: 一系列旨在防止模型过拟合、提高模型泛化能力的技术。其核心思想是在模型的损失函数中加入一个惩罚项 (Penalty Term),或者在训练过程中引入一些机制,来限制模型的复杂度。
- 目标: 在拟合训练数据的能力(降低偏差 Bias)和模型的简单性/泛化能力(降低方差 Variance)之间找到一个平衡。
1. L1 正则化 (L1 Regularization / Lasso Regularization)
- 核心思想: 在损失函数中加入模型所有权重参数的绝对值之和乘以一个正则化系数
λ
。 - 惩罚项:
λ * Σ |wᵢ|
(其中wᵢ
是模型的权重参数,λ ≥ 0
是正则化强度系数) - 新的损失函数:
L_new = L_original + λ * Σ |wᵢ|
- 效果:
- 稀疏性 (Sparsity): L1 正则化倾向于将一些不重要的特征对应的权重压缩到恰好为零。
- 特征选择: 由于能够产生稀疏权重,L1 正则化可以被认为是一种嵌入式的特征选择方法,它会自动选择出对模型预测贡献较大的特征,而忽略掉那些贡献小的特征。
- 通俗解释:
想象你要装修房子,预算有限 (
λ
控制预算紧张程度)。L_original
:你希望房子装修得尽可能漂亮(拟合数据)。λ * Σ |wᵢ|
:每使用一种材料(特征),或者材料用量增加,都会增加成本(惩罚)。- 为了在预算内达到最好的效果,你会倾向于只使用那些最关键、效果最明显的材料(重要的特征),而一些可有可无的材料(不重要的特征)可能就干脆不用了(权重为0)。
- 适用场景:
- 当特征数量很多,并且怀疑其中有很多不相关或冗余的特征时。
- 希望得到一个更简洁、更易于解释的模型。
2. L2 正则化 (L2 Regularization / Ridge Regularization / Weight Decay)
- 核心思想: 在损失函数中加入模型所有权重参数的平方和乘以一个正则化系数
λ
。 - 惩罚项:
λ * Σ wᵢ²
(或者常写成(λ/2) * Σ wᵢ²
以方便求导) - 新的损失函数:
L_new = L_original + λ * Σ wᵢ²
- 效果:
- 权重衰减 (Weight Decay): L2 正则化倾向于使模型的权重尽可能小,但通常不会精确到零。它会惩罚大的权重值。
- 使得模型的权重分布更平滑,模型对输入的微小变化不那么敏感,从而提高泛化能力。
- 通俗解释:
还是装修房子,预算也有限。
L_original
:你希望房子装修得尽可能漂亮。λ * Σ wᵢ²
:使用任何材料都会增加成本,并且材料用量越大(权重越大),成本(惩罚)会不成比例地急剧增加(因为是平方)。- 为了控制成本,你会倾向于让所有材料的用量都比较“平均”和“适度”,避免某一种材料用得特别多(避免个别权重过大)。
- 适用场景:
- 更通用的正则化方法,在大多数情况下都能有效防止过拟合。
- 当不确定哪些特征更重要,希望所有特征都对模型有所贡献,但又不希望某些特征权重过大时。
- 是神经网络中最常用的正则化方法之一。
L1 vs. L2 的简单对比:
特性 | L1 正则化 (Lasso) | L2 正则化 (Ridge / Weight Decay) |
---|---|---|
惩罚项 | `λ * Σ | wᵢ |
权重影响 | 使部分权重变为0 (稀疏) | 使权重变小,但不为0 (平滑) |
特征选择 | 内嵌特征选择功能 | 不直接进行特征选择 |
解的性质 | 可能非唯一 (如果特征相关) | 通常唯一 |
计算 | 绝对值不易求导 | 平方项易于求导 |
Elastic Net: L1 和 L2 正则化的结合,同时具有两者的优点。惩罚项 = λ₁ * Σ |wᵢ| + λ₂ * Σ wᵢ²
3. Dropout
- 核心思想: 在神经网络的训练过程中,以一定的概率
p
随机地“丢弃”(暂时移除)一部分神经元及其连接。 - 过程:
- 在每次训练迭代(或每个小批量)中,每个神经元(通常是隐藏层的神经元,有时也用于输入层)都有
p
的概率被“关闭”(其输出设为0)。 - 这意味着在每次前向传播和反向传播时,网络结构都在发生轻微的变化。
- 在测试阶段,所有神经元都会被激活,但它们的输出会乘以一个缩放因子
(1-p)
(或者在训练时对未被丢弃的神经元输出进行缩放1/(1-p)
,称为 Inverted Dropout,更常用),以保持输出的期望值与训练时一致。
- 在每次训练迭代(或每个小批量)中,每个神经元(通常是隐藏层的神经元,有时也用于输入层)都有
- 效果:
- 防止神经元协同适应 (Co-adaptation): 鼓励网络学习更鲁棒的特征,因为每个神经元不能过分依赖于其他特定神经元的存在。它必须学会与其他神经元的随机子集一起工作。
- 模型集成近似: Dropout 可以被看作是一种廉价的训练大量不同网络结构(通过随机丢弃神经元形成子网络)并将它们的预测进行平均(或近似平均)的方法。
- 通俗解释:
想象一个篮球队在训练。
- 没有 Dropout: 每次训练都是固定的5名主力队员上场配合。他们可能会形成一些只有他们之间才懂的默契,如果少了某个主力,其他人可能就打不好了。
- 有 Dropout: 每次训练时,教练随机让一些队员(主力或替补)休息(被丢弃),剩下的队员继续训练。这样,每个队员都必须学会和不同的队友配合,整体的适应能力和板凳深度(模型的鲁棒性)都会增强。当真正比赛(测试)时,所有队员都可以上场,并且因为之前的多样化训练,整体实力更强。
- 适用场景:
- 广泛应用于各种类型的神经网络,尤其是较深较宽的网络。
- 是非常有效且常用的正则化技术。
p
(丢弃概率) 是一个超参数,常见的值有 0.2 到 0.5。
4. 早停 (Early Stopping)
- 核心思想: 在训练过程中,持续监控模型在验证集 (Validation Set) 上的性能。当模型在验证集上的性能在一定数量的迭代次数(Epochs)内不再提升,甚至开始下降时,就提前停止训练。
- 过程:
- 将数据分为训练集、验证集和测试集。
- 在每个 Epoch 结束时,在验证集上评估模型的性能(如损失或准确率)。
- 记录到目前为止在验证集上性能最好的模型参数。
- 如果验证集性能在预设的“耐心轮数 (patience)”内没有超过之前的最佳性能,则停止训练。
- 最终使用的模型是那个在验证集上表现最佳的模型,而不是训练到最后的模型。
- 效果:
- 直接防止模型在训练集上过度拟合,因为它在验证集性能开始变差(过拟合的迹象)时就停止了。
- 通俗解释:
还是学生备考的例子。
- 学生不断刷练习题(训练)。
- 老师定期给他做模拟卷(验证集评估)。
- 一开始,练习越多,模拟卷成绩越好。
- 但到某个点,学生继续刷练习题,模拟卷成绩反而不提高了,甚至开始下降(因为他开始死记硬背练习题,而模拟卷是新题)。
- 老师发现这个情况后,就让学生停止刷题(早停),并以他模拟卷成绩最好的那个状态去参加真实考试。
- 优点:
- 简单且非常有效。
- 不需要修改损失函数。
- 可以自动确定合适的训练轮数。
- 缺点:
- 需要一个独立的验证集。
- “耐心轮数 (patience)”是一个需要设置的超参数。
- 可能会因为验证集上的随机波动而过早停止(但通常可以通过设置合适的patience来缓解)。
如何选择和使用正则化方法?
- 通常会组合使用多种正则化方法。 例如,同时使用 L2 正则化和 Dropout,并配合早停。
- L2 正则化是神经网络中非常常用的基线正则化方法。
- Dropout 对于较深较宽的网络特别有效。
- L1 正则化在需要特征稀疏性或进行特征选择时更有用。
- 早停是一种简单且几乎总是推荐使用的策略。
- 正则化强度 (
λ
for L1/L2,p
for Dropout) 是重要的超参数,需要通过交叉验证或在验证集上进行调整。 - 数据增强 (Data Augmentation) 也是一种非常有效的正则化技术,通过人工增加训练数据的多样性来防止过拟合。
选择和调整正则化方法是一个实验性的过程,目标是在模型的复杂度和泛化能力之间找到最佳平衡点。
No comments to display
No comments to display