当前位置: 首页 > news >正文

【深度学习-Day 15】告别“盲猜”:一文读懂深度学习损失函数

Langchain系列文章目录

01-玩转LangChain:从模型调用到Prompt模板与输出解析的完整指南
02-玩转 LangChain Memory 模块:四种记忆类型详解及应用场景全覆盖
03-全面掌握 LangChain:从核心链条构建到动态任务分配的实战指南
04-玩转 LangChain:从文档加载到高效问答系统构建的全程实战
05-玩转 LangChain:深度评估问答系统的三种高效方法(示例生成、手动评估与LLM辅助评估)
06-从 0 到 1 掌握 LangChain Agents:自定义工具 + LLM 打造智能工作流!
07-【深度解析】从GPT-1到GPT-4:ChatGPT背后的核心原理全揭秘
08-【万字长文】MCP深度解析:打通AI与世界的“USB-C”,模型上下文协议原理、实践与未来

Python系列文章目录

PyTorch系列文章目录

机器学习系列文章目录

深度学习系列文章目录

Java系列文章目录

JavaScript系列文章目录

深度学习系列文章目录

01-【深度学习-Day 1】为什么深度学习是未来?一探究竟AI、ML、DL关系与应用
02-【深度学习-Day 2】图解线性代数:从标量到张量,理解深度学习的数据表示与运算
03-【深度学习-Day 3】搞懂微积分关键:导数、偏导数、链式法则与梯度详解
04-【深度学习-Day 4】掌握深度学习的“概率”视角:基础概念与应用解析
05-【深度学习-Day 5】Python 快速入门:深度学习的“瑞士军刀”实战指南
06-【深度学习-Day 6】掌握 NumPy:ndarray 创建、索引、运算与性能优化指南
07-【深度学习-Day 7】精通Pandas:从Series、DataFrame入门到数据清洗实战
08-【深度学习-Day 8】让数据说话:Python 可视化双雄 Matplotlib 与 Seaborn 教程
09-【深度学习-Day 9】机器学习核心概念入门:监督、无监督与强化学习全解析
10-【深度学习-Day 10】机器学习基石:从零入门线性回归与逻辑回归
11-【深度学习-Day 11】Scikit-learn实战:手把手教你完成鸢尾花分类项目
12-【深度学习-Day 12】从零认识神经网络:感知器原理、实现与局限性深度剖析
13-【深度学习-Day 13】激活函数选型指南:一文搞懂Sigmoid、Tanh、ReLU、Softmax的核心原理与应用场景
14-【深度学习-Day 14】从零搭建你的第一个神经网络:多层感知器(MLP)详解
15-【深度学习-Day 15】告别“盲猜”:一文读懂深度学习损失函数


文章目录

  • Langchain系列文章目录
  • Python系列文章目录
  • PyTorch系列文章目录
  • 机器学习系列文章目录
  • 深度学习系列文章目录
  • Java系列文章目录
  • JavaScript系列文章目录
  • 深度学习系列文章目录
  • 前言
  • 一、什么是损失函数?
    • 1.1 定义与重要性
      • 1.1.1 损失函数的概念
      • 1.1.2 损失函数的重要性
    • 1.2 损失函数、成本函数与目标函数的区别与联系
      • 1.2.1 损失函数 (Loss Function)
      • 1.2.2 成本函数 (Cost Function)
      • 1.2.3 目标函数 (Objective Function)
  • 二、回归任务中的常用损失函数
    • 2.1 均方误差 (Mean Squared Error - MSE)
      • 2.1.1 公式解析
      • 2.1.2 特点与适用场景
      • 2.1.3 Python 实现示例
    • 2.2 平均绝对误差 (Mean Absolute Error - MAE)
      • 2.2.1 公式解析
      • 2.2.2 特点与适用场景
      • 2.2.3 Python 实现示例
    • 2.3 MSE vs. MAE 对比
  • 三、分类任务中的常用损失函数
    • 3.1 交叉熵损失 (Cross-Entropy Loss)
      • 3.1.1 信息论基础简介 (可选但有助于理解)
      • 3.1.2 二分类交叉熵 (Binary Cross-Entropy - BCE)
        • (1) 公式解析
        • (2) 与 Sigmoid 的关系
        • (3) Python 实现示例 (概念性)
      • 3.1.3 多分类交叉熵 (Categorical Cross-Entropy)
        • (1) 公式解析
        • (2) 与 Softmax 的关系
        • (3) Python 实现示例 (概念性)
    • 3.2 合页损失 (Hinge Loss)
      • 3.2.1 公式解析
      • 3.2.2 特点与适用场景
  • 四、选择损失函数的考量因素
    • 4.1 问题类型 (Problem Type)
    • 4.2 模型输出层的激活函数 (Model Output Activation)
    • 4.3 对异常值的敏感度 (Sensitivity to Outliers)
    • 4.4 训练稳定性与收敛速度 (Training Stability & Convergence Speed)
    • 4.5 特定任务需求 (Specific Task Requirements)
  • 五、总结


前言

在深度学习的征途上,我们精心搭建神经网络模型,期望它能出色地完成特定任务,例如精准地识别图像中的猫狗,或者流畅地翻译不同语言的文本。但是,我们如何衡量模型“学”得好不好呢?模型又是如何知道自己应该朝哪个方向“努力学习”以变得更好呢?这背后离不开一个至关重要的概念——损失函数(Loss Function)。损失函数就像一把标尺,量化了模型预测结果与真实目标之间的差距。这个差距就是“损失”,模型训练的目标就是不断调整参数,使得这个损失尽可能小。本文将带你深入理解损失函数的概念、常见的损失函数类型及其在不同场景下的应用与选择。

一、什么是损失函数?

1.1 定义与重要性

1.1.1 损失函数的概念

损失函数,顾名思义,是用来计算模型单次预测结果的好坏程度的函数。更具体地说,它衡量的是模型预测值( h a t y \\hat{y} haty)与真实值( y y y)之间的差异。这个差异值,我们称之为“损失值”或“误差值”。一个理想的模型,其预测值应该无限接近真实值,此时损失值也应该趋近于零。

举个例子:
假设我们训练一个模型来预测房价。

  • 对于某套房子,真实价格是 300 万( y y y)。
  • 模型A预测价格为 310 万( h a t y _ A \\hat{y}\_A haty_A)。
  • 模型B预测价格为 350 万( h a t y _ B \\hat{y}\_B haty_B)。

直观上,模型A的预测更接近真实价格,因此模型A的“损失”应该比模型B小。损失函数就是用数学方式来精确计算这种“损失”的大小。

1.1.2 损失函数的重要性

损失函数在深度学习中扮演着核心角色,其重要性体现在:

  1. 指导模型优化方向:损失值是模型参数优化的直接依据。在训练过程中,我们会通过梯度下降等优化算法,根据损失函数计算出的梯度来调整模型的权重和偏置,目标是使损失值不断减小。没有损失函数,模型就失去了学习的方向。
  2. 评估模型性能:虽然最终评估模型性能我们会用准确率、召回率等指标,但在训练过程中,损失函数的值是监控模型训练状态、判断模型是否收敛的重要参考。
  3. 影响模型行为:选择不同的损失函数,可能会引导模型学习到不同的数据特征和行为模式。例如,某些损失函数对异常值更敏感,而另一些则更鲁棒。

1.2 损失函数、成本函数与目标函数的区别与联系

在文献中,我们经常会看到与损失函数相似的术语:成本函数(Cost Function)和目标函数(Objective Function)。它们之间既有联系也有区别:

1.2.1 损失函数 (Loss Function)

通常指计算单个样本的预测误差的函数。例如,对于上面房价预测的例子,我们分别计算模型对每一套房子预测的误差。
数学表示上,如果模型的参数是 t h e t a \\theta theta,对于第 i i i 个样本 ( x _ i , y _ i ) (x\_i, y\_i) (x_i,y_i),损失函数可以表示为 L ( y _ i , f ( x _ i ; t h e t a ) ) L(y\_i, f(x\_i; \\theta)) L(y_i,f(x_i;theta)),其中 f ( x _ i ; t h e t a ) f(x\_i; \\theta) f(x_i;theta) 是模型的预测值 h a t y _ i \\hat{y}\_i haty_i

1.2.2 成本函数 (Cost Function)

通常指计算**整个训练集或一个批次(batch)**中所有样本的平均损失的函数。它是所有单个样本损失的某种聚合,最常见的是平均值。
数学表示上,对于包含 N N N 个样本的数据集,成本函数 J ( t h e t a ) J(\\theta) J(theta) 可以是:
J ( θ ) = 1 N ∑ i = 1 N L ( y i , f ( x i ; θ ) ) J(\theta) = \frac{1}{N} \sum_{i=1}^{N} L(y_i, f(x_i; \theta)) J(θ)=N1i=1NL(yi,f(xi;θ))
在实际应用中,损失函数和成本函数这两个术语有时会混用,但理解其细微差别有助于更清晰地把握概念。

1.2.3 目标函数 (Objective Function)

这是一个更广义的概念。在机器学习(尤其是深度学习)的优化问题中,目标函数是我们最终希望最小化(或最大化)的函数
成本函数通常是目标函数的主要组成部分。但目标函数有时还会包含其他项,比如正则化项(Regularization Term),用于防止模型过拟合。
例如,一个带有L2正则化的目标函数可能是:
O b j ( θ ) = J ( θ ) + λ ∑ j θ j 2 Obj(\theta) = J(\theta) + \lambda \sum_{j} \theta_j^2 Obj(θ)=J(θ)+λjθj2
其中 J ( t h e t a ) J(\\theta) J(theta) 是成本函数, l a m b d a s u m _ j t h e t a _ j 2 \\lambda \\sum\_{j} \\theta\_j^2 lambdasum_jtheta_j2 是L2正则化项。

简单总结:

  • 损失函数:针对单个样本。
  • 成本函数:针对整个数据集(或一批数据)的平均损失。
  • 目标函数:最终优化的目标,可能包含成本函数和正则化项等。

在本文后续内容中,如无特别说明,我们主要关注的是用于衡量预测误差的“损失函数”部分。

二、回归任务中的常用损失函数

回归任务的目标是预测一个连续值,如股票价格、温度、房屋面积等。

2.1 均方误差 (Mean Squared Error - MSE)

均方误差是最常用的回归损失函数之一。它计算的是预测值与真实值之差的平方的平均值。

2.1.1 公式解析

对于 N N N 个样本,MSE 的计算公式如下:
M S E = 1 N ∑ i = 1 N ( y i − y ^ i ) 2 MSE = \frac{1}{N} \sum_{i=1}^{N} (y_i - \hat{y}_i)^2 MSE=N1i=1N(yiy^i)2
其中:

  • N N N 是样本数量。
  • y _ i y\_i y_i 是第 i i i 个样本的真实值。
  • h a t y _ i \\hat{y}\_i haty_i 是模型对第 i i i 个样本的预测值。

2.1.2 特点与适用场景

特点:

  1. 平滑可导:MSE 函数在其定义域内处处可导,这使得它非常适合用于基于梯度的优化算法。其导数计算简单,有助于稳定的梯度下降。
  2. 惩罚大误差:由于误差是平方的,所以 MSE 会对预测误差较大的样本给予更大的惩罚。如果一个样本的预测误差是另一个样本的两倍,那么它在 MSE 中的贡献会是四倍。
  3. 对异常值敏感:正是因为平方项的存在,MSE 对异常值(outliers)非常敏感。一个远离正常数据分布的异常点会产生巨大的误差平方项,从而主导损失函数的梯度,可能导致模型训练方向的偏移。

适用场景:

  • 当数据中的异常值较少,或者我们希望模型对大误差特别敏感时。
  • 当模型的输出是连续值,并且我们假设误差服从高斯分布时(MSE 与最大似然估计在高斯误差假设下是等价的)。

2.1.3 Python 实现示例

下面是一个使用 NumPy 计算 MSE 的简单示例:

import numpy as npdef mean_squared_error(y_true, y_pred):"""计算均方误差 (MSE)参数:y_true (np.array): 真实值数组y_pred (np.array): 预测值数组返回:float: MSE 值"""# 确保输入是 NumPy 数组y_true = np.asarray(y_true)y_pred = np.asarray(y_pred)# 检查维度是否匹配if y_true.shape != y_pred.shape:raise ValueError("真实值和预测值的形状必须相同!")return np.mean((y_true - y_pred)**2)# 示例数据
y_true_example = np.array([1.0, 2.0, 3.0, 4.0, 5.0])
y_pred_example_good = np.array([1.1, 1.9, 3.2, 4.0, 4.8]) # 较好的预测
y_pred_example_bad = np.array([1.5, 2.8, 2.5, 5.0, 3.5])  # 较差的预测
y_pred_example_outlier = np.array([1.1, 1.9, 3.2, 4.0, 10.0]) # 包含异常值的预测mse_good = mean_squared_error(y_true_example, y_pred_example_good)
mse_bad = mean_squared_error(y_true_example, y_pred_example_bad)
mse_outlier = mean_squared_error(y_true_example, y_pred_example_outlier)print(f"真实值: {y_true_example}")
print(f"较好预测: {y_pred_example_good}, MSE: {mse_good:.4f}")
print(f"较差预测: {y_pred_example_bad}, MSE: {mse_bad:.4f}")
print(f"含异常值预测: {y_pred_example_outlier}, MSE: {mse_outlier:.4f}")

预期输出:

真实值: [1. 2. 3. 4. 5.]
较好预测: [1.1 1.9 3.2 4.  4.8], MSE: 0.0180
较差预测: [1.5 2.8 2.5 5.  3.5], MSE: 0.8300
含异常值预测: [1.1 1.9 3.2 4.  10.], MSE: 5.0180

从输出可以看到,包含异常值的预测 y_pred_example_outlier (最后一个预测值10.0远大于真实值5.0) 导致了显著增大的 MSE 值。

2.2 平均绝对误差 (Mean Absolute Error - MAE)

平均绝对误差是另一种常用的回归损失函数,它计算的是预测值与真实值之差的绝对值的平均值。

2.2.1 公式解析

对于 N N N 个样本,MAE 的计算公式如下:
M A E = 1 N ∑ i = 1 N ∣ y i − y ^ i ∣ MAE = \frac{1}{N} \sum_{i=1}^{N} |y_i - \hat{y}_i| MAE=N1i=1Nyiy^i
其中:

  • N N N 是样本数量。
  • y _ i y\_i y_i 是第 i i i 个样本的真实值。
  • h a t y _ i \\hat{y}\_i haty_i 是模型对第 i i i 个样本的预测值。

2.2.2 特点与适用场景

特点:

  1. 对异常值鲁棒:由于使用的是绝对值而不是平方,MAE 对于异常值的敏感度远低于 MSE。异常值产生的误差不会被不成比例地放大。
  2. 梯度恒定:当预测值与真实值不相等时,MAE 的梯度在误差大于零时为 1,误差小于零时为 -1(在误差为零处不可导,但实际中通常可以忽略或使用次梯度)。这意味着无论误差大小,梯度更新的幅度是相同的。这可能导致在接近最优解时,模型仍在以较大的步长更新,从而在最优解附近震荡,不易精确收敛到最小值。
  3. 直观易懂:MAE 的值直接反映了平均预测误差的大小,解释起来更直观。

适用场景:

  • 当数据中存在较多异常值,并且不希望这些异常值过多地影响模型训练时。
  • 当希望损失函数的解释更直接时。

2.2.3 Python 实现示例

下面是一个使用 NumPy 计算 MAE 的简单示例:

import numpy as npdef mean_absolute_error(y_true, y_pred):"""计算平均绝对误差 (MAE)参数:y_true (np.array): 真实值数组y_pred (np.array): 预测值数组返回:float: MAE 值"""y_true = np.asarray(y_true)y_pred = np.asarray(y_pred)if y_true.shape != y_pred.shape:raise ValueError("真实值和预测值的形状必须相同!")return np.mean(np.abs(y_true - y_pred))# 使用与 MSE 相同的示例数据
mae_good = mean_absolute_error(y_true_example, y_pred_example_good)
mae_bad = mean_absolute_error(y_true_example, y_pred_example_bad)
mae_outlier = mean_absolute_error(y_true_example, y_pred_example_outlier)print(f"真实值: {y_true_example}")
print(f"较好预测: {y_pred_example_good}, MAE: {mae_good:.4f}")
print(f"较差预测: {y_pred_example_bad}, MAE: {mae_bad:.4f}")
print(f"含异常值预测: {y_pred_example_outlier}, MAE: {mae_outlier:.4f}")

预期输出:

真实值: [1. 2. 3. 4. 5.]
较好预测: [1.1 1.9 3.2 4.  4.8], MAE: 0.1200
较差预测: [1.5 2.8 2.5 5.  3.5], MAE: 0.8600
含异常值预测: [1.1 1.9 3.2 4.  10.], MAE: 1.0800

对比 MSE 的结果,可以看到 mse_outlier (5.0180) 相对于 mse_bad (0.8300) 增加了约 5 倍,而 mae_outlier (1.0800) 相对于 mae_bad (0.8600) 增加的幅度要小得多,这体现了 MAE 对异常值的鲁棒性。

2.3 MSE vs. MAE 对比

特性均方误差 (MSE)平均绝对误差 (MAE)
公式 f r a c 1 N s u m ( y _ i − h a t y _ i ) 2 \\frac{1}{N} \\sum (y\_i - \\hat{y}\_i)^2 frac1Nsum(y_ihaty_i)2$\frac{1}{N} \sum
对异常值敏感鲁棒
惩罚机制误差越大,惩罚呈指数级增长误差越大,惩罚呈线性增长
导数处处可导,梯度随误差变化在误差为0处不可导,其余地方梯度恒定
收敛性通常梯度平滑,易于找到最小值接近最优点时可能因梯度恒定而震荡
解释性不如MAE直观更直观地反映平均误差大小

何时选择?

  • 如果异常值是需要特别关注并惩罚的,或者数据比较干净,MSE 可能是个不错的选择,因为它通常能更快地收敛。
  • 如果数据中包含较多异常值,或者希望模型对异常值不那么敏感,MAE 是更安全的选择。
  • 有时也会使用 Huber Loss 或 Smooth L1 Loss,它们结合了 MSE 和 MAE 的优点:在误差较小时表现像 MSE(平滑),在误差较大时表现像 MAE(鲁棒)。

下面是一个简单的Mermaid流程图,展示了选择回归损失函数时的一个基本考量:

开始: 选择回归损失函数
数据中是否存在较多异常值?
考虑 MAE 或 Huber Loss
是否希望重点惩罚大误差?
考虑 MSE
MAE 或 MSE 可能都适用, 可进一步实验
结束

三、分类任务中的常用损失函数

分类任务的目标是预测一个离散的类别标签,例如判断一张图片是猫还是狗(二分类),或者识别手写数字是0到9中的哪一个(多分类)。

3.1 交叉熵损失 (Cross-Entropy Loss)

交叉熵损失是分类任务中最核心、最常用的损失函数。它源于信息论中的交叉熵概念,用来衡量两个概率分布之间的差异。在分类问题中,这两个概率分布分别是:

  1. 真实标签的概率分布:通常是 one-hot 编码形式,即正确类别概率为1,其他类别概率为0。
  2. 模型预测的概率分布:通常由模型的最后一层(如 Sigmoid 或 Softmax 层)输出,表示模型认为样本属于各个类别的概率。

交叉熵损失越小,说明模型的预测概率分布与真实标签的概率分布越接近。

3.1.1 信息论基础简介 (可选但有助于理解)

要理解交叉熵,简单回顾一下信息论中的几个概念会很有帮助:

  • 信息量:一个事件发生所带来的信息多少。越不可能发生的事件发生了,其信息量越大。公式为 I ( x ) = − l o g ( P ( x ) ) I(x) = -\\log(P(x)) I(x)=log(P(x)),其中 P ( x ) P(x) P(x) 是事件 x x x 发生的概率。
  • 熵 (Entropy):表示一个随机变量不确定性的度量,或者说是对所有可能事件信息量的期望。对于一个离散随机变量 X X X 可能取值为 x _ 1 , . . . , x _ n x\_1, ..., x\_n x_1,...,x_n,对应概率为 P ( x _ 1 ) , . . . , P ( x _ n ) P(x\_1), ..., P(x\_n) P(x_1),...,P(x_n),其熵为 H ( X ) = − s u m _ i = 1 n P ( x _ i ) l o g ( P ( x _ i ) ) H(X) = -\\sum\_{i=1}^{n} P(x\_i) \\log(P(x\_i)) H(X)=sum_i=1nP(x_i)log(P(x_i))。熵越大,不确定性越大。
  • 相对熵 (Relative Entropy / Kullback-Leibler Divergence, KL散度):衡量两个概率分布 P P P Q Q Q 之间的差异。 D _ K L ( P ∣ ∣ Q ) = s u m P ( x ) l o g ( f r a c P ( x ) Q ( x ) ) D\_{KL}(P||Q) = \\sum P(x) \\log(\\frac{P(x)}{Q(x)}) D_KL(P∣∣Q)=sumP(x)log(fracP(x)Q(x))。KL散度是不对称的,即 D _ K L ( P ∣ ∣ Q ) n e q D _ K L ( Q ∣ ∣ P ) D\_{KL}(P||Q) \\neq D\_{KL}(Q||P) D_KL(P∣∣Q)neqD_KL(Q∣∣P)
  • 交叉熵 (Cross-Entropy) H ( P , Q ) = − s u m P ( x ) l o g ( Q ( x ) ) H(P, Q) = -\\sum P(x) \\log(Q(x)) H(P,Q)=sumP(x)log(Q(x))。它可以看作是使用基于分布 Q Q Q 的编码方式来编码来自真实分布 P P P 的事件时,所需要的平均比特数。

可以证明, H ( P , Q ) = H ( P ) + D _ K L ( P ∣ ∣ Q ) H(P,Q) = H(P) + D\_{KL}(P||Q) H(P,Q)=H(P)+D_KL(P∣∣Q)。在机器学习中,真实分布 P P P 是固定的(由训练数据决定),所以 H ( P ) H(P) H(P) 是一个常数。因此,最小化交叉熵 H ( P , Q ) H(P,Q) H(P,Q) 等价于最小化 KL 散度 D _ K L ( P ∣ ∣ Q ) D\_{KL}(P||Q) D_KL(P∣∣Q),也就是让我们模型的预测分布 Q Q Q 尽可能地接近真实分布 P P P

3.1.2 二分类交叉熵 (Binary Cross-Entropy - BCE)

当分类任务只有两个类别时(例如,是/否,猫/狗,垃圾邮件/非垃圾邮件),我们使用二分类交叉熵损失,也称为对数损失(Log Loss)。

(1) 公式解析

假设 y y y 是真实标签(通常取值为 0 或 1), h a t y \\hat{y} haty 是模型预测样本为类别 1 的概率(由 Sigmoid 函数输出,范围在 (0, 1) 之间)。
对于单个样本,二分类交叉熵损失的公式为:
L B C E = − [ y log ⁡ ( y ^ ) + ( 1 − y ) log ⁡ ( 1 − y ^ ) ] L_{BCE} = -[y \log(\hat{y}) + (1 - y) \log(1 - \hat{y})] LBCE=[ylog(y^)+(1y)log(1y^)]

  • 当真实标签 y = 1 y=1 y=1 时,损失为 − l o g ( h a t y ) -\\log(\\hat{y}) log(haty)。此时,我们希望 h a t y \\hat{y} haty 尽可能接近 1,这样 − l o g ( h a t y ) -\\log(\\hat{y}) log(haty) 就尽可能接近 0。如果 h a t y \\hat{y} haty 接近 0,损失会变得非常大。
  • 当真实标签 y = 0 y=0 y=0 时,损失为 − l o g ( 1 − h a t y ) -\\log(1 - \\hat{y}) log(1haty)。此时,我们希望 h a t y \\hat{y} haty 尽可能接近 0(即 1 − h a t y 1-\\hat{y} 1haty 尽可能接近1),这样 − l o g ( 1 − h a t y ) -\\log(1 - \\hat{y}) log(1haty) 就尽可能接近 0。如果 h a t y \\hat{y} haty 接近 1,损失也会变得非常大。

对于 N N N 个样本,平均二分类交叉熵损失为:
B C E = − 1 N ∑ i = 1 N [ y i log ⁡ ( y ^ i ) + ( 1 − y i ) log ⁡ ( 1 − y ^ i ) ] BCE = - \frac{1}{N} \sum_{i=1}^{N} [y_i \log(\hat{y}_i) + (1 - y_i) \log(1 - \hat{y}_i)] BCE=N1i=1N[yilog(y^i)+(1yi)log(1y^i)]

(2) 与 Sigmoid 的关系

在二分类问题中,神经网络的输出层通常是一个神经元,接一个 Sigmoid 激活函数。Sigmoid 函数 s i g m a ( z ) = f r a c 1 1 + e − z \\sigma(z) = \\frac{1}{1 + e^{-z}} sigma(z)=frac11+ez 会将任意实数输入 z z z 压缩到 (0, 1) 区间,这个输出值可以被解释为样本属于正类(类别1)的概率 h a t y \\hat{y} haty。二分类交叉熵损失就是为这种概率输出量身定制的。

(3) Python 实现示例 (概念性)
import numpy as npdef binary_cross_entropy(y_true, y_pred_prob):"""计算二分类交叉熵损失参数:y_true (np.array): 真实标签数组 (0或1)y_pred_prob (np.array): 模型预测为类别1的概率数组 (0到1之间)返回:float: BCE 损失值"""y_true = np.asarray(y_true)y_pred_prob = np.asarray(y_pred_prob)# 防止 log(0) 的情况,进行裁剪epsilon = 1e-12 # 一个很小的数,防止 log(0)y_pred_prob = np.clip(y_pred_prob, epsilon, 1. - epsilon)term1 = y_true * np.log(y_pred_prob)term2 = (1 - y_true) * np.log(1 - y_pred_prob)return -np.mean(term1 + term2)# 示例
y_true_binary = np.array([1, 0, 1, 0, 1])
# 假设模型输出(经过Sigmoid)
y_pred_prob_good = np.array([0.9, 0.1, 0.8, 0.2, 0.95]) # 较好的预测
y_pred_prob_bad = np.array([0.6, 0.7, 0.3, 0.8, 0.4])  # 较差的预测bce_good = binary_cross_entropy(y_true_binary, y_pred_prob_good)
bce_bad = binary_cross_entropy(y_true_binary, y_pred_prob_bad)print(f"真实标签: {y_true_binary}")
print(f"较好预测概率: {y_pred_prob_good}, BCE: {bce_good:.4f}")
print(f"较差预测概率: {y_pred_prob_bad}, BCE: {bce_bad:.4f}")

预期输出:

真实标签: [1 0 1 0 1]
较好预测概率: [0.9  0.1  0.8  0.2  0.95], BCE: 0.1419
较差预测概率: [0.6 0.7 0.3 0.8 0.4 ], BCE: 1.0733

可以看到,当模型的预测概率与真实标签更吻合时,BCE 损失更小。

3.1.3 多分类交叉熵 (Categorical Cross-Entropy)

当分类任务有三个或更多类别时(例如,手写数字识别0-9,物体识别中的多个类别),我们使用多分类交叉熵损失。

(1) 公式解析

假设有 C C C 个类别。

  • 真实标签 y _ i y\_i y_i 通常是一个 one-hot 向量,例如对于3个类别,如果真实类别是第2类,则 y _ i = [ 0 , 1 , 0 ] y\_i = [0, 1, 0] y_i=[0,1,0] y _ i j y\_{ij} y_ij 表示第 i i i 个样本是否属于第 j j j 类(是为1,否为0)。
  • 模型预测 h a t y ∗ i \\hat{y}*i hatyi 也是一个向量,由 Softmax 函数输出, h a t y ∗ i j \\hat{y}*{ij} hatyij 表示模型预测第 i i i 个样本属于第 j j j 类的概率,且 s u m _ j = 1 C h a t y _ i j = 1 \\sum\_{j=1}^{C} \\hat{y}\_{ij} = 1 sum_j=1Chaty_ij=1

对于单个样本,多分类交叉熵损失的公式为:
L C C E = − ∑ j = 1 C y j log ⁡ ( y ^ j ) L_{CCE} = - \sum_{j=1}^{C} y_j \log(\hat{y}_j) LCCE=j=1Cyjlog(y^j)由于 y _ j y\_j y_j 是 one-hot 编码,只有一个元素为1(假设为第 k k k 个类别),其余为0。所以上式可以简化为: L C C E = − log ⁡ ( y ^ k ) L_{CCE} = - \log(\hat{y}_k) LCCE=log(y^k)
其中 h a t y _ k \\hat{y}\_k haty_k 是模型预测样本属于真实类别 k k k 的概率。我们希望这个概率尽可能接近1,从而使损失接近0。

对于 N N N 个样本,平均多分类交叉熵损失为:
C C E = − 1 N ∑ i = 1 N ∑ j = 1 C y i j log ⁡ ( y ^ i j ) CCE = - \frac{1}{N} \sum_{i=1}^{N} \sum_{j=1}^{C} y_{ij} \log(\hat{y}_{ij}) CCE=N1i=1Nj=1Cyijlog(y^ij)

(2) 与 Softmax 的关系

在多分类问题中,神经网络的输出层通常有 C C C 个神经元( C C C 为类别数),接一个 Softmax 激活函数。Softmax 函数会将这 C C C 个神经元的输出(logits)转换为一个概率分布,其中每个元素表示样本属于对应类别的概率,并且所有元素的和为1。多分类交叉熵损失就是为这种概率分布输出设计的。

(3) Python 实现示例 (概念性)
import numpy as npdef categorical_cross_entropy(y_true_one_hot, y_pred_softmax):"""计算多分类交叉熵损失参数:y_true_one_hot (np.array): 真实标签的 one-hot 编码 (N, C)y_pred_softmax (np.array): 模型预测的 Softmax 输出概率 (N, C)返回:float: CCE 损失值"""y_true_one_hot = np.asarray(y_true_one_hot)y_pred_softmax = np.asarray(y_pred_softmax)# 防止 log(0) 的情况epsilon = 1e-12y_pred_softmax = np.clip(y_pred_softmax, epsilon, 1. - epsilon)# 计算每个样本的损失# 对于每个样本 i,损失是 -sum(y_true_one_hot[i,j] * log(y_pred_softmax[i,j]) for j in C)# 由于 y_true_one_hot 是 one-hot,这等价于 -log(y_pred_softmax[i, true_class_index_for_i])# 简洁实现:利用 NumPy 的乘法和求和sample_losses = -np.sum(y_true_one_hot * np.log(y_pred_softmax), axis=1)return np.mean(sample_losses)# 示例: 3个类别, 2个样本
# 样本1: 真实类别 0 ([1,0,0])
# 样本2: 真实类别 2 ([0,0,1])
y_true_multi = np.array([[1, 0, 0], [0, 0, 1]])# 较好的预测 (Softmax 输出)
y_pred_multi_good = np.array([[0.8, 0.1, 0.1],  # 样本1预测为类别0的概率高[0.1, 0.1, 0.8]]) # 样本2预测为类别2的概率高# 较差的预测 (Softmax 输出)
y_pred_multi_bad = np.array([[0.3, 0.4, 0.3],   # 样本1预测概率分散[0.5, 0.3, 0.2]])  # 样本2预测为类别0的概率反而最高cce_good = categorical_cross_entropy(y_true_multi, y_pred_multi_good)
cce_bad = categorical_cross_entropy(y_true_multi, y_pred_multi_bad)print(f"真实标签 (one-hot):\n{y_true_multi}")
print(f"较好预测概率 (Softmax):\n{y_pred_multi_good}, \nCCE: {cce_good:.4f}")
print(f"较差预测概率 (Softmax):\n{y_pred_multi_bad}, \nCCE: {cce_bad:.4f}")

预期输出:

真实标签 (one-hot):
[[1 0 0][0 0 1]]
较好预测概率 (Softmax):
[[0.8 0.1 0.1][0.1 0.1 0.8]], 
CCE: 0.2231
较差预测概率 (Softmax):
[[0.3 0.4 0.3][0.5 0.3 0.2]], 
CCE: 1.4053

同样,当模型的预测概率分布与真实的 one-hot 标签分布更接近时,CCE 损失更小。

稀疏分类交叉熵 (Sparse Categorical Cross-Entropy):
值得一提的是,许多深度学习框架(如 TensorFlow/Keras, PyTorch)还提供了“稀疏分类交叉熵”损失函数。它与普通的多分类交叉熵功能相同,区别在于它接受的真实标签 y _ t r u e y\_{true} y_true 是类别的整数索引(例如 [0, 2, 1, ...]),而不是 one-hot 编码的向量。这在类别数量非常多时可以节省内存。框架内部会自动将其转换为等效的 one-hot 计算。

3.2 合页损失 (Hinge Loss)

合页损失主要用于“最大间隔”分类器,例如支持向量机(SVM)。虽然在深度学习的神经网络中不如交叉熵常见,但了解它有助于拓宽视野。

3.2.1 公式解析

对于二分类问题,真实标签 y y y 通常取值为 − 1 , + 1 {-1, +1} 1,+1,模型输出 h a t y \\hat{y} haty 是一个原始的预测分数(未经 Sigmoid 等激活)。
Hinge Loss 的公式为:
L H = max ⁡ ( 0 , 1 − y ⋅ y ^ ) L_H = \max(0, 1 - y \cdot \hat{y}) LH=max(0,1yy^)

  • 如果 y c d o t h a t y g e 1 y \\cdot \\hat{y} \\ge 1 ycdothatyge1,意味着预测结果不仅类别正确(符号相同),而且置信度足够高( h a t y \\hat{y} haty 的绝对值足够大,使得 y c d o t h a t y y \\cdot \\hat{y} ycdothaty 大于等于1),此时损失为0。模型认为这些样本已经被正确且“足够好”地分类了。
  • 如果 KaTeX parse error: Undefined control sequence: \< at position 19: …\cdot \\hat{y} \̲<̲ 1,意味着分类错误或者虽然分类正确但置信度不足(在间隔边界内),此时损失为 1 − y c d o t h a t y 1 - y \\cdot \\hat{y} 1ycdothaty,是一个线性惩罚。

3.2.2 特点与适用场景

特点:

  1. 鼓励间隔最大化:Hinge Loss 的设计目标是找到一个决策边界,使得不同类别之间的间隔(margin)最大。
  2. 对某些“已正确分类”的样本不施加惩罚:对于 y c d o t h a t y g e 1 y \\cdot \\hat{y} \\ge 1 ycdothatyge1 的样本,损失为0,模型不会在这些样本上花费额外的“精力”。
  3. 不要求概率输出 h a t y \\hat{y} haty 是原始分数,不是概率。

适用场景:

  • 主要用于 SVM 模型。
  • 在某些深度学习任务中,如果目标是最大化决策边界的间隔,也可以借鉴 Hinge Loss 的思想。

多分类 Hinge Loss 也有多种形式,例如 Weston and Watkins 提出的版本。

四、选择损失函数的考量因素

选择一个合适的损失函数对于模型训练至关重要。以下是一些主要的考量因素:

4.1 问题类型 (Problem Type)

这是最首要的因素:

  • 回归问题:预测连续值。常用损失函数有 MSE、MAE、Huber Loss 等。
  • 二分类问题:预测两个类别之一。常用二分类交叉熵(Binary Cross-Entropy / Log Loss)。如果关注最大间隔,可考虑 Hinge Loss。
  • 多分类问题:预测多个类别之一。常用多分类交叉熵(Categorical Cross-Entropy)或稀疏多分类交叉熵(Sparse Categorical Cross-Entropy)。

4.2 模型输出层的激活函数 (Model Output Activation)

损失函数的选择通常与模型最后一层使用的激活函数紧密相关,以确保数值稳定性和梯度的良好计算:

  • Sigmoid 激活 (输出概率在 (0,1) 之间):通常配合 二分类交叉熵损失
  • Softmax 激活 (输出多类别概率分布,和为1):通常配合 多分类交叉熵损失
  • 线性激活 (输出原始分数,范围可以是 ( − i n f t y , + i n f t y ) (-\\infty, +\\infty) (infty,+infty)):
    • 用于回归任务时,常配合 MSEMAE
    • 用于某些分类任务(如SVM的原始形式)时,可配合 Hinge Loss

4.3 对异常值的敏感度 (Sensitivity to Outliers)

  • MSE:对异常值非常敏感,因为误差是平方的。
  • MAE:对异常值相对鲁棒,因为误差是线性的。
  • Huber Loss / Smooth L1 Loss:是 MSE 和 MAE 的一种折中,对小误差使用平方项,对大误差使用线性项,从而兼具 MSE 的平滑性和 MAE 的鲁棒性。
  • 交叉熵损失:如果模型对某个样本给出了非常自信但错误的预测(例如,真实为1,预测概率为0.0001),损失会非常大,因此也可能对标签噪声或极端错误的预测敏感。

4.4 训练稳定性与收敛速度 (Training Stability & Convergence Speed)

  • MSE 通常具有平滑的梯度,有助于稳定收敛。
  • MAE 在误差为0处不可导(次梯度存在),且在接近最优解时梯度不变,可能导致学习率需要精细调整以避免震荡。
  • 交叉熵损失 与 Sigmoid/Softmax 结合使用时,通常能提供较好的梯度特性,避免梯度消失问题(相比于例如 MSE 用于分类概率输出)。

4.5 特定任务需求 (Specific Task Requirements)

有时任务本身就有特定的偏好:

  • 例如,在某些不平衡分类问题中,可能会使用加权交叉熵 (Weighted Cross-Entropy) 来给予少数类更大的权重。
  • 在目标检测中,损失函数会更复杂,可能包括分类损失和边界框回归损失的组合。
  • 在生成模型(如GANs)中,损失函数的设计本身就是研究的核心。

实践建议:

  • 从对应问题类型的标准损失函数开始(例如,回归用MSE/MAE,分类用交叉熵)。
  • 理解数据特性,特别是异常值的存在情况。
  • 通过实验比较不同损失函数在验证集上的性能。
  • 查阅相关领域文献,看是否有针对特定问题的定制化损失函数。

五、总结

损失函数是深度学习模型训练的基石,它量化了模型的预测与真实目标之间的差距,并为模型优化指明了方向。本文详细介绍了:

  1. 损失函数的基本概念:阐述了损失函数、成本函数和目标函数的定义、重要性及它们之间的区别与联系。
  2. 回归任务常用损失函数
    • 均方误差 (MSE):对大误差惩罚较大,对异常值敏感,梯度平滑。
    • 平均绝对误差 (MAE):对异常值鲁棒,梯度在大部分区域恒定。
    • 并对比了 MSE 和 MAE 的特性及适用场景。
  3. 分类任务常用损失函数
    • 交叉熵损失:核心的分类损失函数,衡量预测概率分布与真实分布的差异。
      • 二分类交叉熵 (BCE):用于二分类问题,常与 Sigmoid 结合。
      • 多分类交叉熵 (CCE):用于多分类问题,常与 Softmax 结合。
    • 合页损失 (Hinge Loss):主要用于最大间隔分类器如 SVM。
  4. 选择损失函数的考量因素:包括问题类型、模型输出激活、对异常值的敏感度、训练稳定性以及特定任务需求。

理解并正确选择损失函数,是构建高性能深度学习模型的关键一步。在后续的学习中,我们还会接触到更多针对特定架构(如 GAN、目标检测、语义分割等)和特定挑战(如类别不平衡)的复杂或定制化损失函数。希望本文能为你打下坚实的基础!


相关文章:

  • 2. Java 基础语法通关:变量、数据类型与运算符详解​
  • CST求解器
  • HarmonyOS 鸿蒙应用开发基础:父组件调用子组件方法的几种实现方案对比
  • Linux Docker下安装tomcat
  • 首次使用倍福工控机修改IP
  • Redis--SpringDataRedis详解
  • 基于 Free2AI 的企业知识库搭建全流程实战:从数据采集到智能问答
  • 笔记:将一个文件服务器上的文件(一个返回文件数据的url)作为另一个http接口的请求参数
  • DDoS攻击应对指南:提升网站安全性的有效策略
  • 【Django ORM】三万字了解Django ORM的基本概念和基本使用
  • 华为云Flexus+DeepSeek征文 | 基于ModelArts Studio和Cherry Studio快速构建午餐管家助手
  • CentOS7挂载hgfs文件夹(VMware 共享文件夹)及网卡的自启动。
  • 【分治】归并排序:递归版 非递归版
  • Python后端框架新星Robyn:性能与开发体验的双重革命
  • 01. Qt介绍及Qt开发环境搭建(2025.05最新官网下载方式)
  • mysql可重复读隔离级别下的快照读和当前读
  • 物理定律的数学结构基础及AI推理
  • 六:操作系统虚拟内存之抖动
  • 如何在Java中进行PDF合并
  • 表格单元格多行文本溢出写法
  • 美国做调查网站/steam交易链接怎么改
  • 房产类网站建设费用/南昌seo优化
  • 网站拨测人员是干嘛的/站长工具在线查询
  • 遵义哪里做网站/it培训机构哪个好一点
  • 9个不需要门面的生意/app排名优化公司
  • 个人制作的网站/免费的seo网站