Skip to main content

深度学习基础


感知机 (Perceptron)

通俗例子: 想象一个非常简单的**“决策机器人”**,它要根据一些输入信息来做一个二选一的决定(比如“去”或“不去”,“是”或“否”)。

  1. 收集信息 (输入 Inputs): 机器人收集多个信息片段,比如:

    • 天气好不好?(x₁)
    • 朋友去不去?(x₂)
    • 今天心情如何?(x₃) 这些信息可以是数值(比如天气评分1-10)或者0/1的布尔值。
  2. 给信息赋予权重 (Weights): 机器人对每个信息的重要性有不同的看法:

    • 天气可能很重要 (w₁ = 0.5)
    • 朋友去不去非常重要 (w₂ = 0.8)
    • 心情一般重要 (w₃ = 0.3) 这些权重表示了每个输入对最终决策的影响程度。
  3. 加权求和并加上偏好 (Weighted Sum + Bias): 机器人把每个信息和它的权重相乘,然后加起来,得到一个总分。它可能还有一个固有的“偏好”或“门槛”(偏置项 bias,b)。

    • z = (x₁ * w₁) + (x₂ * w₂) + (x₃ * w₃) + b
  4. 做决策 (激活函数 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 if z > θ (或 z > 0 如果 θ 被吸收到 b 中)
      • output = 0 (或 -1) if z ≤ θ (或 z ≤ 0)
    • 模型的输出是一个离散的类别标签。
  • 学习算法 (Perceptron Learning Algorithm):
    • 一种迭代算法,用于调整权重 w 和偏置 b
    • 过程:
      1. 初始化权重 w 和偏置 b (通常为0或小的随机数)。
      2. 对于训练集中的每个样本 (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_truey_pred 通常取 +1 和 -1)
      3. 重复步骤2,直到所有样本都被正确分类,或者达到最大迭代次数。
  • 目的/用途 (Purpose / Use Cases):
    • 解决线性可分 (linearly separable) 的二分类问题。
    • 例如,逻辑门 AND、OR 的实现。
  • 优点:
    • 简单,易于理解和实现。
    • 如果数据是线性可分的,感知机学习算法保证在有限次迭代后收敛到一个解。
  • 缺点:
    • 只能解决线性可分问题。 对于线性不可分的问题(如异或 XOR 问题),它无法找到一个有效的超平面来分隔数据。这是感知机的一个重大局限。
    • 如果数据不是严格线性可分的,算法可能不会收敛,权重会持续振荡。
    • 输出是离散的,不能提供概率信息。
    • 阶跃激活函数不可导(或导数为0),不适用于基于梯度的优化方法(如反向传播)。

多层感知机 (Multilayer Perceptron, MLP)

通俗例子: 想象之前的“决策机器人”变得更聪明了,它不再是简单地把所有信息加权求和然后做一次决策,而是组建了一个“决策委员会”

  1. 第一层决策员 (隐藏层 Hidden Layer):

    • 不是直接对原始信息(天气、朋友、心情)做最终决定,而是先有几个“初级决策员”。
    • 每个初级决策员也像单个感知机一样,接收原始信息,有自己的权重和偏好,然后做出一个初步的“判断”或提取一个“中间特征”。
    • 例如:
      • 决策员A 可能专门判断“今天是否适合户外活动?”(综合天气和心情)。
      • 决策员B 可能专门判断“社交需求是否强烈?”(综合朋友和心情)。
    • 这些初级决策员的输出不再是简单的0/1,而是可能用更平滑的函数(如Sigmoid或ReLU)来表示“判断的强度”或“特征的激活程度”。
  2. 更高层决策员 (可以有多层隐藏层):

    • 初级决策员的判断结果,会作为输入信息传递给“中级决策员”。
    • 中级决策员再根据这些“中间特征”进行更复杂的判断。
    • 这样可以一层层地传递和组合信息。
  3. 最终决策者 (输出层 Output Layer):

    • 最高层的决策员(或者一个决策小组)根据前面各层传递上来的高度概括和抽象的“特征”,做出最终的决定(比如“去”、“不去”,或者更复杂的分类,比如“去公园”、“去电影院”、“待在家”)。

多层感知机就是通过引入一个或多个“隐藏层”来克服单个感知机的线性限制。

结合技术点:

  • 核心思想 (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)来训练。
    • 过程:
      1. 前向传播 (Forward Pass): 将输入数据通过网络,计算每一层的输出,直到得到最终的预测结果。
      2. 计算损失 (Loss Calculation): 将预测结果与真实标签进行比较,计算损失函数的值(如交叉熵损失、均方误差)。
      3. 反向传播 (Backward Pass): 从输出层开始,将损失逐层向后传播,利用链式法则计算损失函数对网络中每个权重和偏置的梯度。
      4. 参数更新 (Parameter Update): 根据计算出的梯度和选择的优化算法,更新网络中的权重和偏置,以减小损失。
      5. 重复以上步骤,直到损失收敛或达到预设的训练轮数。
  • 目的/用途 (Purpose / Use Cases):
    • 分类任务: 图像识别、文本分类、情感分析等。
    • 回归任务: 预测房价、股票价格等。
    • 能够学习复杂的非线性映射。
  • 优点:
    • 通用近似定理 (Universal Approximation Theorem): 理论上,具有一个足够宽的隐藏层(或多个隐藏层)的MLP可以以任意精度近似任何连续函数。这意味着它具有强大的表示能力。
    • 能够解决线性不可分的问题。
    • 是许多更复杂深度学习模型的基础。
  • 缺点:
    • 容易过拟合: 如果模型过于复杂或训练数据不足,MLP可能会在训练数据上表现很好,但在未见过的数据上表现差。需要正则化技术(如L1/L2正则化、Dropout)来缓解。
    • 需要调整的超参数多: 网络结构(层数、每层神经元数量)、激活函数的选择、学习率、优化器选择等。
    • 可能陷入局部最优: 梯度下降算法可能会陷入损失函数的局部最小值而不是全局最小值(尽管在实践中,对于高维度的神经网络,这通常不是主要问题)。
    • 训练可能较慢: 尤其是对于深层和宽层的网络。
    • “黑箱”模型: 对于复杂的MLP,其内部决策过程可能难以解释。

理解感知机是理解MLP的起点,而MLP则是通往更复杂的神经网络结构(如卷积神经网络CNN、循环神经网络RNN、Transformer等)的重要桥梁。、

好的,我们来简单介绍一下几种常见的激活函数,并重点讨论如何根据不同情况挑选它们。

激活函数 (Activation Function)

在神经网络中,激活函数被应用到神经元的加权和(z = w·x + b)之后,引入非线性因素。没有非线性激活函数,无论神经网络有多少层,它本质上都只是一个线性模型,无法学习复杂的数据模式。


常见的激活函数:

  1. Sigmoid 函数

    • 公式: σ(z) = 1 / (1 + e^(-z))
    • 输出范围: (0, 1)
    • 形状: S 型曲线。
    • 优点:
      • 输出在 (0, 1) 之间,可以解释为概率(尤其是在二分类问题的输出层)。
      • 平滑可导。
    • 缺点:
      • 梯度消失 (Vanishing Gradient): 当输入 z 非常大或非常小时,Sigmoid 的导数(梯度)接近于0。在深层网络中,这会导致反向传播时梯度逐层衰减,使得靠近输入层的权重更新非常缓慢,甚至停止学习。
      • 输出非零中心 (Not zero-centered): 输出恒为正,这可能导致后续层输入的非零中心化,可能影响梯度下降的效率。
      • 计算相对复杂(指数运算)。
  2. Tanh (双曲正切) 函数

    • 公式: tanh(z) = (e^z - e^(-z)) / (e^z + e^(-z)) (也可以表示为 2 * sigmoid(2z) - 1
    • 输出范围: (-1, 1)
    • 形状: S 型曲线,但中心在0。
    • 优点:
      • 输出零中心 (Zero-centered): 相比 Sigmoid,这通常能使模型收敛更快。
      • 平滑可导。
    • 缺点:
      • 梯度消失: 仍然存在梯度消失问题,只是程度比 Sigmoid 略轻(因为梯度范围比 Sigmoid 稍大)。
      • 计算相对复杂(指数运算)。
  3. ReLU (Rectified Linear Unit, 修正线性单元)

    • 公式: ReLU(z) = max(0, z)
    • 输出范围: [0, +∞)
    • 形状: 输入为负时输出0,输入为正时输出等于输入。
    • 优点:
      • 有效缓解梯度消失: 当输入 z > 0 时,导数为1,梯度可以很好地传播。
      • 计算非常高效: 只需要一个简单的比较和赋值操作。
      • 收敛速度快: 在实践中,使用 ReLU 的网络通常比使用 Sigmoid 或 Tanh 的网络收敛更快。
      • 稀疏性: 会使一部分神经元的输出为0,这可以引入网络的稀疏性,可能有助于特征提取。
    • 缺点:
      • Dying ReLU (神经元死亡): 如果一个神经元的输入在训练过程中持续为负,那么它的输出将一直是0,梯度也将一直是0,导致该神经元不再学习(“死亡”)。这通常发生在学习率设置过大或初始化不当时。
      • 输出非零中心。
  4. Leaky ReLU (带泄露的 ReLU)

    • 公式: LeakyReLU(z) = max(αz, z) 或者写成:
      • z if z > 0
      • αz if z ≤ 0 (其中 α 是一个小的正常数,如 0.01 或 0.2)
    • 输出范围: (-∞, +∞) (如果 α > 0)
    • 形状: 类似于 ReLU,但在负输入区域有一个小的非零斜率。
    • 优点:
      • 解决了 Dying ReLU 问题: 即使输入为负,神经元仍然会有非零梯度,允许学习继续。
      • 保留了 ReLU 的大部分优点(如计算效率、缓解梯度消失)。
    • 缺点:
      • 引入了一个新的超参数 α 需要调整(尽管通常对 α 的选择不那么敏感)。
      • 表现不一定总是优于 ReLU。
    • 变种:PReLU (Parametric ReLU),其中 α 不是固定的超参数,而是作为模型参数通过学习得到。
  5. Softmax 函数

    • 公式: Softmax(zᵢ) = e^(zᵢ) / Σ e^(zⱼ) (对向量 z 中的每个元素 zᵢ 计算)
    • 输出范围: 每个输出元素在 (0, 1) 之间,且所有输出元素之和为 1。
    • 形状: 将一个实数向量转换为概率分布。
    • 用途:
      • 专门用于多分类问题的输出层。
      • 它将网络的原始输出(logits)转换为每个类别的概率。
    • 优点:
      • 输出可以直观地解释为概率。
      • 与交叉熵损失函数(Cross-Entropy Loss)结合使用效果很好。
    • 缺点:
      • 通常不用于隐藏层。
      • 如果 logits 之间的差异很大,可能会导致输出概率非常接近0或1,可能影响数值稳定性(但通常有数值稳定的实现)。

如何挑选激活函数?

选择激活函数没有绝对的“黄金法则”,但可以遵循一些通用的指导原则和经验:

  1. 输出层 (Output Layer):

    • 二分类问题 (Binary Classification):
      • 通常使用 Sigmoid 函数,因为它的输出 (0, 1) 可以直接解释为属于正类的概率。
    • 多分类问题 (Multi-class Classification):
      • 通常使用 Softmax 函数,它会输出一个概率分布,表示样本属于每个类别的概率。
    • 回归问题 (Regression):
      • 通常不使用激活函数(或者说使用一个线性激活函数 f(z) = z),因为目标是预测任意连续值,而不是限制在特定范围内或解释为概率。
      • 如果回归目标值有特定范围(如非负),可以在输出层使用相应的激活函数(如 ReLU 用于非负输出)。
  2. 隐藏层 (Hidden Layers):

    • 首选通常是 ReLU:
      • 由于其简单性、计算效率以及在实践中通常能带来更快的收敛速度和更好的性能(尤其是在较深的网络中,能有效缓解梯度消失)。
      • 从 ReLU 开始尝试是一个好的起点。
    • 如果遇到 Dying ReLU 问题:
      • 可以尝试 Leaky ReLU 或其变体 (如 PReLU, ELU)。
      • 检查学习率是否过大,或者尝试更好的权重初始化方法 (如 He 初始化)。
    • Tanh:
      • 在某些特定场景下(例如一些循环神经网络 RNN 的变体,如 LSTM、GRU 的门控单元中)仍然被使用,因为它输出零中心。
      • 有时在 ReLU 表现不佳时,可以尝试 Tanh 作为备选。
    • Sigmoid:
      • 在现代深度神经网络的隐藏层中已经很少使用,主要是因为梯度消失和非零中心问题。
      • 它仍然可能出现在一些旧的网络结构中,或者在需要将输出压缩到 (0,1) 范围的特定门控机制中(如 LSTM 中的某些门)。
  3. 实验和经验:

    • 没有免费午餐定理: 没有哪个激活函数在所有情况下都是最优的。最好的选择往往取决于具体的数据集、网络架构和任务。
    • 进行实验: 尝试不同的激活函数,并通过验证集的性能来评估哪种最适合你的问题。
    • 关注研究进展: 新的激活函数不断被提出和研究 (如 Swish, GELU 等,常用于 Transformer 模型)。了解最新的研究成果可能有助于你做出更好的选择。

总结挑选策略:

  1. 输出层: 根据任务类型(二分类用 Sigmoid,多分类用 Softmax,回归用线性或无激活)。
  2. 隐藏层:
    • 默认尝试 ReLU。
    • 如果 ReLU 出现神经元死亡问题,尝试 Leaky ReLU / PReLU / ELU
    • Tanh 可以作为 ReLU 表现不佳时的备选,或者在需要零中心输出的特定结构中使用。
    • 尽量避免在深层网络的隐藏层中使用 Sigmoid。
  3. 始终通过实验验证你的选择。

记住,激活函数的选择是神经网络设计中的一个重要超参数,合理的选择可以显著影响模型的训练效率和最终性能。

损失函数 (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 个样本的模型预测值。
    • Σ 表示对所有样本求和。
  • 通俗解释: 想象你在射箭,靶心是真实值,你射出的箭是预测值。

    1. 误差: 你的箭离靶心的距离。
    2. 平方误差: 这个距离的平方。为什么要平方?
      • 惩罚大误差: 误差越大,平方后会变得更大,模型会更努力地去修正这些大错误。
      • 消除负号: 确保误差总是正的。
      • 数学特性好: 平方函数是凸函数,求导方便,有助于优化。
    3. 均方误差: 把所有箭的“平方误差”加起来,然后取个平均,看看你平均射得有多偏。
  • 主要用途/适用场景:

    • 回归问题 (Regression Problems): 当目标是预测一个连续的数值时,MSE 是最常用的损失函数。
      • 例如:预测房价、预测股票价格、预测温度。
    • 当假设误差服从高斯分布时,最小化 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)。

  • 核心思想: 衡量两个概率分布之间的差异。在分类问题中,这两个概率分布是:

    1. 真实概率分布: 通常是一个独热编码 (one-hot encoded) 的向量,表示样本实际属于哪个类别(真实类别的概率为1,其他类别为0)。
    2. 模型预测的概率分布: 模型输出的样本属于每个类别的概率(通常由 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 越高,损失越小。
  • 通俗解释 (以多分类为例): 想象你在参加一个多项选择题考试,每道题只有一个正确答案。

    1. 真实答案: 你知道正确答案是C。
    2. 你的预测概率: 你对每个选项都有一个相信它是正确答案的概率(比如 A:10%, B:20%, C:60%, D:10%)。
    3. 交叉熵的惩罚: 如果你对正确答案C的预测概率很高(比如60%或更高),那么你的“损失”就很小。如果你对正确答案C的预测概率很低(比如只给了10%),那么你的“损失”就很大。交叉熵就是用来量化这种“预测概率与真实答案之间的不匹配程度”。
  • 主要用途/适用场景:

    • 分类问题 (Classification Problems):
      • 二分类问题: 使用二分类交叉熵 (BCE Loss)。
      • 多分类问题: 使用分类交叉熵 (CCE Loss)。
    • 当模型的输出是概率时,交叉熵是衡量其性能的自然选择。
    • 在信息论中,交叉熵衡量了用一个概率分布(模型的预测)来编码另一个真实概率分布所需的平均比特数。
  • 优点:

    • 对于分类问题,尤其是在输出层使用 Sigmoid 或 Softmax 时,交叉熵损失函数通常能提供比 MSE 更好的梯度特性,有助于模型更快地收敛。
    • 当预测概率远离真实标签时,会给予较大的惩罚。
    • 与 Sigmoid/Softmax 结合使用时,梯度计算相对简洁。
  • 缺点:

    • 如果模型预测的概率非常接近0或1,而真实标签相反(比如真实为1,预测概率接近0),log 函数会导致损失值非常大,甚至数值不稳定(但在实际实现中通常有平滑处理,如 log(p + epsilon))。
  • 例子 (二分类): 真实标签 (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)

大多数优化器都是基于梯度下降的思想。梯度下降的基本步骤是:

  1. 计算损失函数关于模型参数的梯度(表示损失函数在该点下降最快的方向)。
  2. 沿着梯度的反方向更新参数,步长由学习率 (Learning Rate) 控制。 参数_新 = 参数_旧 - 学习率 * 梯度

常见的优化器:

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

    • 核心思想: 不是用整个训练集的梯度来更新参数(这是批量梯度下降 BGD),也不是用单个样本的梯度(这是纯粹的随机梯度下降),而通常指的是小批量随机梯度下降 (Mini-batch SGD)。即每次更新使用一小批 (mini-batch) 样本计算的平均梯度。
    • 优点:
      • 相比 BGD,更新更频繁,收敛速度可能更快。
      • 引入的噪声(因为每次只看一小批数据)有助于跳出局部最小值,可能找到更好的全局最小值。
      • 计算和内存效率高,因为不需要一次性加载整个数据集。
    • 缺点:
      • 由于梯度的随机性,损失函数的下降过程可能会有较多振荡。
      • 选择合适的学习率比较困难,对学习率敏感。
      • 在梯度变化剧烈或稀疏的特征上可能表现不佳。
    • 通俗例子: 摸黑下山,每次只看脚下一小块区域(mini-batch)的地形来决定下一步往哪走。
  2. Momentum (动量SGD)

    • 核心思想: 在 SGD 的基础上引入了“动量”的概念,模拟物理学中物体运动的惯性。它会累积过去梯度的方向,使得参数更新方向更加平滑,并能加速在梯度方向一致时的收敛,同时抑制振荡。
    • 更新规则 (简化): velocity_新 = β * velocity_旧 + (1-β) * 梯度 (β 通常取 0.9 左右,是动量参数) 参数_新 = 参数_旧 - 学习率 * velocity_新
    • 优点:
      • 加速收敛,尤其是在梯度方向较为一致的平坦区域。
      • 减少 SGD 在某些方向上的振荡。
      • 有助于冲过一些平缓的鞍点或较浅的局部最小值。
    • 缺点:
      • 引入了新的超参数 β (动量系数)。
    • 通俗例子: 推一个球下山。球不仅会沿着当前坡度滚,还会因为之前的惯性继续往前冲,更容易滚过小的坑洼。
  3. AdaGrad (Adaptive Gradient Algorithm, 自适应梯度算法)

    • 核心思想: 为模型中的每个参数维护一个自适应的学习率。对于更新不频繁的参数(梯度较小),使用较大的学习率;对于更新频繁的参数(梯度较大),使用较小的学习率。它通过累积参数过去所有梯度的平方来实现这一点。
    • 更新规则 (简化): 累积平方梯度_新 = 累积平方梯度_旧 + 梯度² 参数_新 = 参数_旧 - (学习率 / √(累积平方梯度_新 + ε)) * 梯度 (ε 是一个很小的平滑项,防止分母为0)
    • 优点:
      • 能够自动调整每个参数的学习率,不需要手动精细调整全局学习率。
      • 对于稀疏数据(如 NLP 中的词嵌入)或特征尺度差异较大的情况表现较好。
    • 缺点:
      • 由于分母中的累积平方梯度会不断增大,学习率会单调递减,最终可能变得非常小,导致训练提前停止或收敛过慢。
    • 通俗例子: 在不同地形上下山。在陡峭的地方(梯度大),步子迈小一点;在平缓的地方(梯度小),步子迈大一点。但走得越久,步子会整体变小。
  4. RMSProp (Root Mean Square Propagation)

    • 核心思想: 是对 AdaGrad 的改进,旨在解决其学习率过早且急剧下降的问题。它不是简单地累积所有历史平方梯度,而是使用指数加权移动平均来计算平方梯度,使得近期梯度的影响更大,远期梯度的影响逐渐减小。
    • 更新规则 (简化): 移动平均平方梯度_新 = γ * 移动平均平方梯度_旧 + (1-γ) * 梯度² (γ 是衰减率,如0.9) 参数_新 = 参数_旧 - (学习率 / √(移动平均平方梯度_新 + ε)) * 梯度
    • 优点:
      • 缓解了 AdaGrad 学习率急剧下降的问题,在非凸优化问题上表现通常比 AdaGrad 好。
      • 仍然具有自适应学习率的特性。
    • 缺点:
      • 引入了新的超参数 γ (衰减率)。
    • 通俗例子: 类似 AdaGrad,但更关注近期的地形变化来调整步长,而不是把所有走过的路都同等重要地记下来。
  5. Adam (Adaptive Moment Estimation)

    • 核心思想: 可以看作是 Momentum 和 RMSProp 的结合体。它既利用了梯度的一阶矩估计(均值,像 Momentum 一样)来保持梯度的方向,又利用了梯度的二阶矩估计(未中心化的方差,像 RMSProp 一样)来调整每个参数的学习率。同时还进行了偏差校正,以解决初始化阶段一阶和二阶矩估计偏向于0的问题。
    • 更新规则 (非常简化,忽略偏差校正): 一阶矩估计_新 (动量项) = β₁ * 一阶矩估计_旧 + (1-β₁) * 梯度 二阶矩估计_新 (缩放项) = β₂ * 二阶矩估计_旧 + (1-β₂) * 梯度² 参数_新 = 参数_旧 - 学习率 * (一阶矩估计_新 / (√(二阶矩估计_新) + ε)) (β₁ 通常为 0.9, β₂ 通常为 0.999)
    • 优点:
      • 结合了 Momentum 和 RMSProp 的优点。
      • 对每个参数计算自适应学习率。
      • 通常在各种任务和网络结构上都表现良好,收敛速度快。
      • 对初始学习率的选择相对不那么敏感(但仍然重要)。
      • 是目前非常流行和默认推荐的优化器之一。
    • 缺点:
      • 引入了多个超参数 (β₁, β₂, ε),尽管通常使用默认值效果就不错。
      • 在某些情况下,可能会找到与 SGD+Momentum 不同的(有时是次优的)解,或者泛化能力略逊于精心调整的 SGD+Momentum(尽管这种情况不常见)。
    • 通俗例子: 一个经验丰富的登山者,既会利用之前的冲劲(动量),也会根据当前脚下地形的崎岖程度(二阶矩)来调整每一步的幅度和方向。

如何挑选优化器?

选择优化器并没有一成不变的规则,但可以遵循以下一些指导原则:

  1. Adam 通常是默认的好选择:

    • 对于大多数问题和网络结构,Adam(或其变体如 AdamW,它在权重衰减的处理上有所改进)通常能提供快速的收敛和良好的性能。
    • 如果你不确定从哪里开始,Adam 是一个安全的起点。 通常使用其推荐的默认超参数(如 PyTorch 中的 lr=0.001, betas=(0.9, 0.999), eps=1e-08)。
  2. SGD + Momentum 仍然是强有力的竞争者:

    • 虽然 Adam 很流行,但精心调整学习率和动量的 SGD+Momentum 仍然可以在许多任务上达到最佳或接近最佳的性能,有时甚至在泛化能力上略优于 Adam。
    • 如果你有足够的时间和计算资源进行超参数调整,或者你发现 Adam 的泛化能力不理想,可以尝试 SGD+Momentum。
    • 对于计算机视觉等领域,SGD+Momentum 仍然被广泛使用。
  3. 考虑数据和模型的特性:

    • 稀疏数据/特征: AdaGrad 或 RMSProp 可能表现更好,因为它们能为稀疏特征提供更大的更新。但 Adam 通常也能处理得不错。
    • 非常深或复杂的网络: 自适应学习率方法 (Adam, RMSProp) 通常比手动调整学习率的 SGD 更容易获得好的结果。
  4. 实验和迭代:

    • 没有免费午餐定理: 没有哪个优化器在所有情况下都是最优的。
    • 进行实验: 尝试不同的优化器,并比较它们在你的验证集上的性能。
    • 监控训练过程: 观察损失曲线的下降情况。如果下降太慢、振荡剧烈或卡在某个平台,可能需要调整优化器或其超参数。
  5. 学习率仍然是关键:

    • 即使是自适应优化器,初始学习率仍然是一个非常重要的超参数。 如果学习率设置不当,即使是 Adam 也可能表现不佳。
    • 考虑使用学习率调度器 (Learning Rate Schedulers),如指数衰减、余弦退火、warmup 等,来在训练过程中动态调整学习率,这通常能带来更好的性能。
  6. 关注最新的研究和社区实践:

    • 优化器的研究仍在不断发展,新的算法和改进版本会不时出现。
    • 了解特定领域(如NLP、CV)或特定模型架构(如Transformer)中常用的优化器和最佳实践。例如,对于Transformer模型,AdamW 配合特定的学习率调度(如带warmup的线性衰减或余弦退火)是常见的选择。

总结挑选策略:

  1. 首选 Adam 或 AdamW 作为起点,使用推荐的默认参数。
  2. 如果 Adam 表现不佳或你想追求极致性能,并且有资源进行调优,可以尝试 SGD + Momentum,并仔细调整学习率和动量。
  3. 对于特别稀疏的数据,可以考虑 AdaGrad 或 RMSProp,但通常 Adam 也能处理。
  4. 不要忘记调整学习率和使用学习率调度器,这对所有优化器都很重要。
  5. 最终通过实验来确定最适合你特定任务的优化器。

选择合适的优化器及其超参数是训练成功的关键因素之一,值得花时间去理解和实验。