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

损失函数(平方损失MSE、绝对值损失MAE、负对数似然损失NLL、交叉熵损失CEL和二元交叉熵损失BCE)原理、公式调库实现与手动实现

目录

    • 1. 损失函数概述
      • 1.1 什么是损失函数
      • 1.2 损失函数通常使用的位置
    • 2. 平方损失函数(Mean Squared Error, MSE)
      • 2.1 基本介绍与原理
      • 2.2 计算公式
      • 2.3 使用方法
    • 3. 绝对值损失函数(Mean Absolute Error, MAE)
      • 3.1 基本介绍与原理
      • 3.2 计算公式
      • 3.3 使用方法
    • 4. 负对数似然损失函数(Negative Log-Likelihood, NLL)
      • 4.1 基本介绍与原理
      • 4.2 计算公式
      • 4.3 使用方法
    • 5. 交叉熵损失函数(Cross-Entropy Loss)
      • 5.1 基本介绍与原理
      • 5.2 计算公式
      • 5.3 使用方法
    • 6. 二元交叉熵损失函数(Binary Cross-Entropy, BCE)
      • 6.1 基本介绍与原理
      • 6.2 计算公式
      • 6.3 使用方法

1. 损失函数概述

1.1 什么是损失函数

损失函数(亦称代价函数、错误函数)损失函数是用来评估模型的预测值 f ( x ) f(x) f(x)与真实值 y y y的不一致程度,损失函数很小,表明机器学习模型与数据真实分布很接近,则模型性能好。

在这里插入图片描述

1.2 损失函数通常使用的位置

在端到端模型训练中,损失函数位于前向传播的最后一步,接收模型输出与真实标签后计算标量损失;随后通过反向传播算法,基于该损失对模型参数求梯度并更新,以逐步降低预测误差。

前向传播:将输入x通过模型model计算得到输出y的过程。

反向传播:要将预测值和真实值的差值减小,需要反向传播更新模型中的参数。

损失函数就基于这两种传播之间,起到承上启下的作用。承上:接受模型的预测值;启下:计算预测值和真实值的差值,为后面的反向传播提供输入数据。

在这里插入图片描述


2. 平方损失函数(Mean Squared Error, MSE)

2.1 基本介绍与原理

平方损失函数(也称L2 Loss)将预测误差平方后求平均,强调较大误差对总体损失的贡献,使模型对离群点更敏感。

2.2 计算公式

M S E = 1 n ∑ i = 1 n ( y i − y ^ i ) 2 \mathrm{MSE} = \frac{1}{n}\sum_{i=1}^n (y_i - \hat y_i)^2 MSE=n1i=1n(yiy^i)2

其中, y i y_i yi为真实值, y ^ i \hat y_i y^i为预测值, n n n为样本数。

在这里插入图片描述

上图的横坐标为 y i − y ^ i y_i - \hat y_i yiy^i,纵坐标为MSE。

在这里插入图片描述

MSE损失函数:即便学习率固定,也会收敛。当损失值趋向于0时会逐渐降低,从而让它在模型训练首尾时更加准确。

在这里插入图片描述

MSE:当真实值与预测值差大于1时,会增大其误差;小于1时,会减小其误差。即MSE会对误差较大(>1)的情况给予更大的惩罚,对误差较小(<1)的情况给予更小的惩罚。模型会偏向于惩罚较大的点,赋予其更大的权重。

(1)使用场景与作用

  • 回归任务:常用于线性回归、神经网络回归等场景;
  • 优化稳定:二阶可导,便于梯度计算与优化算法收敛。

(2)特点

  • 对大误差具有二次惩罚,模型更关注异常值;
  • 可导性好,但对离群点敏感。

2.3 使用方法

(1)调库实现

from sklearn.metrics import mean_squared_error
mse = mean_squared_error(y_true, y_pred)# 或在 PyTorch:
import torch.nn as nn
loss_fn = nn.MSELoss()
loss = loss_fn(outputs, targets) # outputs: 模型的输出, targets: 真实标签

(2)手动实现

import numpy as npdef mse(y_true, y_pred):y_true, y_pred = np.array(y_true), np.array(y_pred)return np.mean((y_true - y_pred) ** 2)

3. 绝对值损失函数(Mean Absolute Error, MAE)

3.1 基本介绍与原理

绝对值损失(L1 Loss)对误差取绝对值再求平均,避免了正负误差相互抵消,更具鲁棒性。

3.2 计算公式

M A E = 1 n ∑ i = 1 n ∣ y i − y ^ i ∣ \mathrm{MAE} = \frac{1}{n}\sum_{i=1}^n \bigl|\,y_i - \hat y_i\,\bigr| MAE=n1i=1n yiy^i

在这里插入图片描述

上图的横坐标为 y i − y ^ i y_i - \hat y_i yiy^i,纵坐标为MAE。

在这里插入图片描述

MAE损失函数:梯度始终一样,即使很小的损失,梯度也很大,很难收敛到更高的精度。(可使用动态学习率解决);且 y i − y ^ i = 0 y_i - \hat y_i=0 yiy^i=0处不可导。

(1)使用场景与作用

  • 回归任务:尤其当数据中存在异常值时,MAE比MSE更稳定;
  • 目标分位回归:可用于中位数回归。

(2)特点

  • 对离群点惩罚线性,较MSE更鲁棒;
  • 不可导于误差为0处,需在实现时处理不连续点。

3.3 使用方法

(1)调库实现

from sklearn.metrics import mean_absolute_error
mae = mean_absolute_error(y_true, y_pred)# 或在 PyTorch:
import torch
criterion = torch.nn.L1Loss() # 创建损失函数对象
output = criterion(y_pre, y_true) # 计算损失值

(1)手动实现

import numpy as npdef mae(y_true, y_pred):y_true, y_pred = np.array(y_true), np.array(y_pred)return np.mean(np.abs(y_true - y_pred))

4. 负对数似然损失函数(Negative Log-Likelihood, NLL)

4.1 基本介绍与原理

负对数似然将模型对真实标签的预测概率的对数取负,衡量模型预测分布与真实分布的差异。对数使得连乘概率变为累加损失,更易数值计算。

对数损失函数用于分类问题,而不是回归问题,它的输入与前面几个损失函数不同。首先真实值是一个类别,模型输出则是一个概率。

4.2 计算公式

对于单样本类别标签 y y y
N L L ( y , P ( y / x ) ) = − log ⁡ P ( y / x ) \mathrm{NLL(y,P(y/x))} = -\log P(y/x) NLL(y,P(y/x))=logP(y/x)
n n n 个样本取平均或求和即可。

(1)使用场景与作用

  • 多分类任务:常与 softmax 输出结合,用于分类神经网络;
  • 构建最大似然估计框架。

(2)特点

  • 与交叉熵等价(当输出为 softmax 概率时);
  • 对概率接近0的预测惩罚巨大。

4.3 使用方法

(1)示例

假设我们有一个简单的图像分类任务,要将图像分为猫、狗、兔子三类。我们训练了一个神经网络模型,它会输出一个长度为 3 的向量,表示输入图像属于猫、狗、兔子的概率。

图像编号预测为猫的概率预测为狗的概率上预测为兔子的概率真实值标签
10.70.20.10(猫)
20.10.80.11(狗)
30.60.30.10(猫)
40.10.20.72(兔子)
50.20.70.11(狗)
  • 对于第 1 张图像,真实标签是猫,模型预测为猫的概率是 0.7,所以该样本的损失为 −log(0.7)≈0.3567。
  • 对于第 2 张图像,真实标签是狗,模型预测为狗的概率是 0.8,该样本的损失为 −log(0.8)≈0.2231。
  • •对于第 3 张图像,真实标签是猫,模型预测为猫的概率是 0.6,损失为 −log(0.6)≈0.5108。
  • •对于第 4 张图像,真实标签是兔子,模型预测为兔子的概率是 0.7,损失为 −log(0.7)≈0.3567。
  • •对于第 5 张图像,真实标签是狗,模型预测为狗的概率是 0.7,损失为 −log(0.7)≈0.3567。

那么这 5 个样本的负对数似然损失函数值为:(0.3567+0.2231+0.5108+0.3567+0.3567)÷5=0.3604

从这个例子可以看出,模型对每个样本预测的概率越接近真实标签对应的概率,负对数似然损失函数值就越小,说明模型的性能越好。如果模型预测完全准确,即对于真实标签为猫的图像,预测为猫的概率为 1,那么该样本的损失为 −log(1)=0。

(2)调库实现(PyTorch)

import torch.nn as nn
loss_fn = nn.NLLLoss()
# 前提:模型最后输出需为 log-softmax
loss = loss_fn(log_probs, targets)import torch
import torch.nn as nn
# 示例数据
y_true = torch.tensor([0, 1, 0, 2, 1])
y_pred = torch.tensor([[0.7, 0.2, 0.1], [0.1, 0.8, 0.1], [0.6, 0.3, 0.1],[0.1, 0.2, 0.7],[0.2, 0.7, 0.1]], dtype=torch.float32)loss = nn.NLLLoss() # 创建负对数似然损失函数对象
output = torch.log(y_pred) # 对预测值取对数
result = loss(output, y_true) # 计算损失值
print(result)

(3)手动实现

import numpy as npdef nll(logits, targets):# logits: (n_samples, n_classes), raw scores# 转为概率并取对数exps = np.exp(logits - np.max(logits, axis=1, keepdims=True))probs = exps / np.sum(exps, axis=1, keepdims=True)log_probs = np.log(probs)# 选择真实类别nll = -log_probs[np.arange(len(targets)), targets]return np.mean(nll)# 上述示例代码实现:
import torch# 示例数据
y_true = torch.tensor([0, 1, 0, 2, 1])
y_pred = torch.tensor([[0.7, 0.2, 0.1], [0.1, 0.8, 0.1], [0.6, 0.3, 0.1],[0.1, 0.2, 0.7],[0.2, 0.7, 0.1]], dtype=torch.float32)# 公式计算对数损失函数
N = len(y_true) # 获取样本数量
loss = 0 # 初始化损失值
for i in range(N): #遍历样本# 获取真实标签true_label = y_true[i] # 获取真实标签对应的预测值y_p = y_pred[i, true_label]one = -torch.log(y_p)loss += one # 累加损失值
print(loss / N) # 计算平均损失值

5. 交叉熵损失函数(Cross-Entropy Loss)

5.1 基本介绍与原理

交叉熵损失函数(Cross - Entropy Loss Function)是机器学习和深度学习中用于衡量模型预测结果与真实标签之间差异的一种常用损失函数,在分类任务中应用广泛。交叉熵源自信息论,用于度量两个概率分布之间的距离。在分类中,计算真实分布与预测分布的交叉熵,值越小表示分布越接近。

5.2 计算公式

对于多分类(one-hot 编码 y i , k ∈ { 0 , 1 } y_{i,k}\in\{0,1\} yi,k{0,1}、预测概率 p ^ i , k \hat p_{i,k} p^i,k
C E = − 1 n ∑ i = 1 n ∑ k = 1 K y i , k log ⁡ p ^ i , k \mathrm{CE} = -\frac{1}{n}\sum_{i=1}^n \sum_{k=1}^K y_{i,k}\,\log \hat p_{i,k} CE=n1i=1nk=1Kyi,klogp^i,k
其中

  • y i y_i yi是第 i i i个样本的真实标记
  • p ^ i \hat p_i p^i是第 i i i个样本的模型预测概率
  • K K K代表第 K K K个类别

例如:

m m m个样本、 n n n种类别的交叉熵误差:
KaTeX parse error: Can't use function '$' in math mode at position 82: …log p_{k}^{(i)}$̲
该样本被标记为第 k k k个类别:
y ( i ) = [ 0 1 0 ⋮ 0 ] n × 1 \mathbf{y}^{(i)} = \begin{bmatrix} 0 \\ \textcolor{red}{1}\\ 0 \\ \vdots \\ 0 \end{bmatrix} _{n \times 1} \quad y(i)= 0100 n×1
其中的1代表的是 k k k y k ( i ) y_k^{(i)} yk(i),其余均是0。

多分类问题的交叉熵损失,只与真实类别对应的模型预测概率有关,因为只有真实类别对应的那一项会被计算在内,其他类别的项在求和过程中均为0。

在这里插入图片描述

所以模型对其他类别饿预测概率不准确,但只要对真实类别的预测概率较高,损失函数的值仍然较低。

示例:

假设有以下 3 张水果图像的真实标签和模型预测的概率分布:

图像编号真实标签 y y y预测概率分布 y ^ \hat y y^
1[1,0,0][0.8,0.1,0.1]
2[0,1,0][0.1,0.7,0.2]
3[0,0,1][0.2,0.3,0.5]

计算过程

  • 图像 1L1=−(1×log(0.8)+0×log(0.1)+0×log(0.1))=−log(0.8)≈0.223
  • 图像 2L2=−(0×log(0.1)+1×log(0.7)+0×log(0.2))=−log(0.7)≈0.357
  • 图像 3L3=−(0×log(0.2)+0×log(0.3)+1×log(0.5))=−log(0.5)≈0.693

平均损失为: L a v g = L 1 + L 2 + L 3 3 = 0.223 + 0.357 + 0.693 3 ≈ 0.424 L_{avg}=\frac{L_1+L_2+L_3}{3} = \frac{0.223+0.357+0.693}{3}\approx 0.424 Lavg=3L1+L2+L3=30.223+0.357+0.6930.424

(1)使用场景与作用

  • 多分类神经网络:最后一层softmax + 交叉熵;
  • 多标签分类:常配合 sigmoid 输出。

(1)特点

  • 对不确定预测(概率接近0)有高惩罚;
  • 与 NLLLoss 在 softmax 情况下等价。

5.3 使用方法

(1)调库实现

import torch.nn as nn
criterion = nn.CrossEntropyLoss()
loss = criterion(y_pred, y_true)
print(loss)

(2)手动实现

import numpy as npdef cross_entropy(y_true, y_pred, eps=1e-12):# y_true: one-hot, y_pred: probabilitiesy_pred = np.clip(y_pred, eps, 1. - eps)return -np.mean(np.sum(y_true * np.log(y_pred), axis=1))# 示例:
import torchy_true = torch.tensor([[1, 0, 0], [0, 1, 0], [0, 0, 1]], dtype=torch.float32)
y_pred = torch.tensor([[0.8, 0.1, 0.1], [0.1, 0.7, 0.2], [0.2, 0.3, 0.5]], dtype=torch.float32)# 手动实现交叉熵损失函数
N = len(y_true)
loss = 0
for i in range(N):one = torch.sum(y_true[i] * torch.log(y_pred[i]))loss += -one
print(loss / N)

6. 二元交叉熵损失函数(Binary Cross-Entropy, BCE)

6.1 基本介绍与原理

二元交叉熵是交叉熵在二分类问题上的特例,标签 y ∈ { 0 , 1 } y\in\{0,1\} y{0,1},预测概率 p ^ ∈ ( 0 , 1 ) \hat p\in(0,1) p^(0,1),衡量两类分布差异。

6.2 计算公式

B C E = − 1 n ∑ i = 1 n [ y i log ⁡ p ^ i + ( 1 − y i ) log ⁡ ( 1 − p ^ i ) ] \mathrm{BCE} = -\frac{1}{n}\sum_{i=1}^n \Bigl[y_i\log \hat p_i + (1-y_i)\log(1-\hat p_i)\Bigr] BCE=n1i=1n[yilogp^i+(1yi)log(1p^i)]

其中

  • y i y_i yi是第 i i i个样本的真实标记
  • p ^ i \hat p_i p^i是第 i i i个样本的模型预测概率

(1)使用场景与作用

  • 二分类神经网络:最后一层 sigmoid + BCE;
  • 多标签分类:对每个标签独立计算BCE后求平均。

(1)特点

  • 对罕见类别(小概率)预测误差惩罚高;
  • 易梯度消失,通常配合从 logits 输入的 from_logits=True 实现更稳定。

6.3 使用方法

(1)调库实现(TensorFlow)

import tensorflow as tf
loss_fn = tf.keras.losses.BinaryCrossentropy(from_logits=False)
loss = loss_fn(y_true, y_pred)# 示例
import torch
y_true = torch.tensor([1, 0, 1, 0], dtype=torch.float32)
y_pred = torch.tensor([0.9, 0.1, 0.2, 0.8], dtype=torch.float32)# 使用torch.nn.BCELoss()计算二元交叉熵损失函数
criterion = torch.nn.BCELoss()
loss = criterion(y_pred, y_true)
print(loss)

(2)手动实现

import numpy as npdef binary_cross_entropy(y_true, y_pred, eps=1e-12):y_pred = np.clip(y_pred, eps, 1. - eps)return -np.mean(y_true * np.log(y_pred) + (1-y_true) * np.log(1-y_pred))# 示例
import torch
y_true = torch.tensor([1, 0, 1, 0], dtype=torch.float32)
y_pred = torch.tensor([0.9, 0.1, 0.2, 0.8], dtype=torch.float32)# 手动实现二元交叉熵损失函数
N = len(y_true)
loss = 0
for i in range(N):true_label = y_true[i]pred_label = y_pred[i]one = true_label * torch.log(pred_label) + (1 - true_label) * torch.log(1 - pred_label)loss += -one
print(loss/N)

小Tips:交叉熵损失函数与对数损失函数:从本质上来说,在分类问题中,交叉熵损失函数和对数损失函数是等价的。对数损失函数是交叉熵损失函数在分类问题中的具体应用形式,二者都旨在最小化模型预测与真实标签之间的差异,促使模型学习到更准确的分类模式。

相关文章:

  • IC解析之TPS92682-Q1(汽车LED灯控制IC)
  • Dp通用套路(闫式)
  • 39-算法打卡-二叉树-基础知识-第三十九天
  • 从零开始的python学习(六)P86+P87+P88
  • 有关SOA和SpringCloud的区别
  • MySQL 8.0 OCP 英文题库解析(二)
  • C++ stl中的stack和queue的相关函数用法
  • 23盘古石决赛
  • 前端自学入门:HTML 基础详解与学习路线指引
  • 安装jdk步骤
  • GOC指令
  • [javascript]取消异步请求
  • Linux——MySQL基础
  • SQL进阶:如何把字段中的键值对转为JSON格式?
  • C++进阶--红黑树的实现
  • 报错 <pcl/features/feature_evaluation/feature_evaluation_framework.h> 不存在的解决办法
  • 深入了解 Stable Diffusion:AI 图像生成的奥秘
  • Linux系统入门第十一章 --Shell编程之函数与数组
  • 影刀RPA开发-智能录制
  • Vulfocus靶场-文件上传-2
  • 李在明正式登记参选下届韩国总统
  • 重庆党政代表团在沪考察,陈吉宁龚正与袁家军胡衡华共商两地深化合作工作
  • 暴雨及强对流天气黄色预警已发布!南方进入本轮降雨最强时段
  • 杭温高铁、沪苏湖高铁明起推出定期票和计次票,不限车次执行优惠折扣
  • 央行:将支持资本市场两项货币政策工具的额度合并使用
  • A股三大股指集体高开大涨超1%,券商、房地产涨幅居前