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

回归任务和分类任务损失函数详解

文章目录

  • 回归任务相关损失函数
    • 1.均方误差(Mean Squared Error,MSE)
    • 2.平均绝对误差(Mean Absolute Error,MAE)
    • 3.Huber损失函数
  • 分类任务相关损失函数
    • 1. 交叉熵
    • 2. 信息量
    • 3. 熵
    • 4. 相对熵(KL散度)
    • 5. 交叉熵
    • 6. CrossEntropyLoss
    • 7. 二分类交叉熵binary_cross_entropy

回归任务相关损失函数

1.均方误差(Mean Squared Error,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 yi 是第 i i i 个样本的真实值
  • y ^ i \hat{y}_i y^i 是第 i i i 个样本的预测值

特点

  • 计算简单:只需计算预测值与真实值差值的平方平均
  • 误差放大效应:平方处理放大了较大误差的影响,使模型对显著预测错误更敏感
  • 性能度量:能准确反映预测值与真实值的平均差异程度
  • 应用广泛:回归问题最常用的损失函数之一(又称L2损失)
  • 可微性:处处可微的特性便于梯度下降优化
  • 对异常值敏感:MSE的平方特性使其对异常值敏感,在存在离群点的数据中可能需要考虑其他鲁棒性更强的损失函数。

2.平均绝对误差(Mean Absolute Error,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

特点

  • 鲁棒性强:直接计算绝对误差平均值,对异常值不敏感(相比MSE)
  • 计算特性
    • 未对误差平方,避免过度放大异常值影响
    • 在零点不可导,可能导致某些优化算法收敛较慢
  • 别称:L1损失

3.Huber损失函数

定义
L ( y , y ^ ) = { 1 2 ( y − y ^ ) 2 , ∣ y − y ^ ∣ ≤ δ δ ∣ y − y ^ ∣ − 1 2 δ 2 , ∣ y − y ^ ∣ > δ L(y, \hat{y}) = \begin{cases} \frac{1}{2}(y - \hat{y})^2, & |y - \hat{y}| \leq \delta \\ \delta |y - \hat{y}| - \frac{1}{2}\delta^2, & |y - \hat{y}| > \delta \end{cases} L(y,y^)={21(yy^)2,δyy^21δ2,yy^δyy^>δ

其中 δ \delta δ 是控制误差敏感度的超参数。

特点

  • 混合特性
    • 小误差时( ∣ y − y ^ ∣ ≤ δ |y-\hat{y}| \leq \delta yy^δ)表现类似MSE,保证可导性
    • 大误差时( ∣ y − y ^ ∣ > δ |y-\hat{y}| > \delta yy^>δ)表现类似MAE,增强鲁棒性
  • 别称:Smooth L1损失

注:Huber损失需要手动设置 δ \delta δ值,通常取1.0作为默认值

在这里插入图片描述

分类任务相关损失函数

1. 交叉熵

熵是信息论中的⼀个概念,要想了解交叉熵的本质,需要先从最基本的概念讲起

2. 信息量

⾸先是信息量。假设我们听到了两件事,分别如下:
事件A:巴西队进⼊了2018世界杯决赛圈。
事件B:中国队进⼊了2018世界杯决赛圈。
仅凭直觉来说,显⽽易⻅事件B的信息量⽐事件A的信息量要⼤。究其原因,是因为事件A发⽣的概率很⼤,事件B发⽣的概率很⼩。所以当越不可能的事件发⽣了,我们获取到的信息量就越⼤。越可能发⽣的事件发⽣了,我们获取到的信息量就越⼩。那么信息量⼤⼩应该和事件发⽣的概率是负相关

假设 X X X 是一个离散型随机变量,其取值集合为 χ \chi χ,概率分布函数 p ( x ) = P r ( X = x ) , x ∈ χ p(x) = Pr(X = x), x \in \chi p(x)=Pr(X=x),xχ,则定义事件 X = x 0 X = x_0 X=x0 的信息量为:

I ( x 0 ) = − log ⁡ ( p ( x 0 ) ) I(x_0) = -\log(p(x_0)) I(x0)=log(p(x0))

由于是概率,所以 p ( x 0 ) p(x_0) p(x0) 的取值范围是 [ 0 , 1 ] [0, 1] [0,1]

3. 熵

对于某个事件,有 n n n 种可能性,每一种可能性都有一个概率 p ( x i ) p(x_i) p(xi)。这样就可以计算出某一种可能性的信息量。举一个例子,假设你拿出了你的电脑,按下开关,会有三种可能性,下表列出了每一种可能的概率及其对应的信息量:

序号事件概率 p p p信息量 − log ⁡ ( p ) -\log(p) log(p)
A电脑正常开机0.70.36
B电脑无法开机0.21.61
C电脑爆炸了0.12.30

注:文中的对数均为自然对数

我们现在有了信息量的定义,⽽熵⽤来表⽰所有信息量的期望,即:

H ( X ) = − ∑ i = 1 n p ( x i ) log ⁡ ( p ( x i ) ) H(X) = - \sum_{i=1}^n p(x_i) \log(p(x_i)) H(X)=i=1np(xi)log(p(xi))

其中 n n n 代表所有的 n n n 种可能性,所以上面的问题结果就是:
H ( X ) = − [ p ( A ) log ⁡ ( p ( A ) ) + p ( B ) log ⁡ ( p ( B ) ) + p ( C ) log ⁡ ( p ( C ) ) ] = 0.7 × 0.36 + 0.2 × 1.61 + 0.1 × 2.30 = 0.804 \begin{aligned} H(X) &= -[p(A)\log(p(A)) + p(B)\log(p(B)) + p(C)\log(p(C))] \\ &= 0.7 \times 0.36 + 0.2 \times 1.61 + 0.1 \times 2.30 \\ &= 0.804 \end{aligned} H(X)=[p(A)log(p(A))+p(B)log(p(B))+p(C)log(p(C))]=0.7×0.36+0.2×1.61+0.1×2.30=0.804

4. 相对熵(KL散度)

相对熵又称KL散度。如果我们对于同一个随机变量 x x x 有两个单独的概率分布 P ( x ) P(x) P(x) Q ( x ) Q(x) Q(x),可以使用KL散度(Kullback-Leibler divergence)来衡量这两个分布的差异。

在机器学习中:

  • P P P 表示样本的真实分布(ground truth),如 [ 1 , 0 , 0 ] [1,0,0] [1,0,0] 表示当前样本属于第一类
  • Q Q Q 表示模型预测的分布,如 [ 0.7 , 0.2 , 0.1 ] [0.7, 0.2, 0.1] [0.7,0.2,0.1]

KL散度计算公式:
D K L ( p ∣ ∣ q ) = ∑ i = 1 n p ( x i ) log ⁡ ( p ( x i ) q ( x i ) ) D_{KL}(p||q) = \sum_{i=1}^n p(x_i) \log\left(\frac{p(x_i)}{q(x_i)}\right) DKL(p∣∣q)=i=1np(xi)log(q(xi)p(xi))

其中:

  • n n n 为事件的所有可能性
  • D K L D_{KL} DKL 值越小,表示 q q q 分布越接近 p p p 分布

PyTorch实现:KLDivLoss

5. 交叉熵

对KL散度公式变形可得:
D K L ( p ∣ ∣ q ) = ∑ i = 1 n p ( x i ) log ⁡ ( p ( x i ) ) − ∑ i = 1 n p ( x i ) log ⁡ ( q ( x i ) ) = − H ( p ( x ) ) + [ − ∑ i = 1 n p ( x i ) log ⁡ ( q ( x i ) ) ] \begin{aligned} D_{KL}(p||q) &= \sum_{i=1}^n p(x_i) \log(p(x_i)) - \sum_{i=1}^n p(x_i) \log(q(x_i)) \\ &= -H(p(x)) + \left[-\sum_{i=1}^n p(x_i) \log(q(x_i))\right] \end{aligned} DKL(p∣∣q)=i=1np(xi)log(p(xi))i=1np(xi)log(q(xi))=H(p(x))+[i=1np(xi)log(q(xi))]

在机器学习中:

  • p p p 代表真实值
  • q q q 代表预测值
  • 由于 − H ( p ( x ) ) -H(p(x)) H(p(x)) 是固定值,优化时只需关注交叉熵部分

交叉熵公式:
H ( p , q ) = − ∑ i = 1 n p ( x i ) log ⁡ ( q ( x i ) ) H(p,q) = -\sum_{i=1}^n p(x_i) \log(q(x_i)) H(p,q)=i=1np(xi)log(q(xi))

6. CrossEntropyLoss

PyTorch在计算二分类或者互斥的多分类问题时,使用的是softmax交叉熵损失计算。

  1. 对输入进行softmax

S j = e a j ∑ k = 1 T e a k S_j = \frac{e^{a_j}}{\sum_{k=1}^{T} e^{a_k}} Sj=k=1Teakeaj

假设有一个数组 a a a a i a_i ai 表示 a a a 中的第 i i i 个元素。计算的是元素的指数与所有元素指数的比值。

假设输入 a = [ 0.5 , 1.5 , 0.1 ] a=[0.5,1.5,0.1] a=[0.5,1.5,0.1],那么经过softmax层后就会得到 [ 0.227863 , 0.61939586 , 0.15274114 ] [0.227863, 0.61939586, 0.15274114] [0.227863,0.61939586,0.15274114],这三个数字表示这个样本属于第1,2,3类的概率分别是 0.227863 0.227863 0.227863 0.61939586 0.61939586 0.61939586 0.15274114 0.15274114 0.15274114

NumPy实现示例

import numpy as np
arr = np.array([[0.5,1.5,0.1]])def softmax(x):exp = np.exp(x)sum_exp = np.sum(np.exp(x), axis=1, keepdims=True)softmax = exp / sum_expreturn softmax
print(softmax(arr))
[[0.227863   0.61939586 0.15274114]]

通过pytorch的 softmax ⽅法可以更直接获得结果

import torch
tensor = torch.tensor([[0.5,1.5,0.1]])
print(tensor.softmax(1).numpy())# 或者
from torch import nn
m = nn.Softmax(dim=1)
print(m(tensor).numpy())
[[0.22786303 0.6193959  0.15274116]]
[[0.22786303 0.6193959  0.15274116]]
  1. 计算交叉熵

交叉熵损失函数定义为:

L = − ∑ j = 1 T y j log ⁡ S j L = - \sum_{j=1}^T y_j \log S_j L=j=1TyjlogSj

其中:

  • L L L 是损失值
  • S j S_j Sj 是softmax输出向量 S S S的第 j j j个值,表示样本属于第 j j j个类别的概率
  • y j y_j yj 是真实标签的one-hot编码( 1 × T 1 \times T 1×T向量,只有一个位置为1,其余为0)

由于 y y y中只有一个值为1,公式可简化为:

L = − log ⁡ S j L = -\log S_j L=logSj

即只需计算真实类别对应的概率的对数值。

PyTorch实现示例

tensor = torch.tensor([[0.5,1.5,0.1]])
print(tensor.log_softmax(dim=1).numpy())# 或
m = nn.LogSoftmax(dim=1)
print(m(tensor).numpy())
[[-1.4790106  -0.47901064 -1.8790107 ]]
[[-1.4790106  -0.47901064 -1.8790107 ]]

由于损失函数要求得到是⼀个值,通常计算得到的,是对数平均损失。pytorch中的NLLLoss (negative log likelihood loss)完成的就是对数平均损失的计算。

tensor = torch.tensor([[0.5,1.5,0.1]])
m = tensor.log_softmax(dim=1)
loss = torch.nn.NLLLoss()
target = torch.empty(1, dtype=torch.long).random_(0, 3)
print(loss(m, target))
tensor(1.8790)

当然,最后回到我们文章开头提到的交叉熵损失 —— cross_entropy

PyTorch中的 cross_entropy 会自动调用上面介绍的 log_softmaxnll_loss 来计算交叉熵,其计算公式如下:

l o s s ( x , c l a s s ) = − log ⁡ ( exp ⁡ ( x [ c l a s s ] ) ∑ j exp ⁡ ( x [ j ] ) ) loss(x, class) = -\log\left(\frac{\exp(x[class])}{\sum_j \exp(x[j])}\right) loss(x,class)=log(jexp(x[j])exp(x[class]))

tensor = torch.tensor([[0.5,1.5,0.1]])
loss = nn.CrossEntropyLoss()
target = torch.randint(3,(1,), dtype=torch.int64)
print(loss(tensor, target).numpy())
0.47901064

7. 二分类交叉熵binary_cross_entropy

binary_cross_entropy 是二分类的交叉熵,实际上是 CrossEntropyLoss 的一种特殊情况。当多分类中类别只有两类时(即 0 或 1),就变成了二分类问题,这也是逻辑回归问题,可以使用相同的损失函数。

target = torch.tensor([[1., 0.], [0., 1.]])
pred = torch.tensor([[0.8,0.2], [0.4,0.6]])
loss = nn.functional.binary_cross_entropy(pred, target, reduction="mean")
print(loss.numpy())
0.36698458

注意:如果使用 BCEWithLogitsLoss,则不需要预先进行 softmax 处理。

相关文章:

  • 采用 Docker GPU 部署的 Ubuntu 或者 windows 桌面环境
  • el-table 树形数据,子行数据可以异步加载
  • 录制mp4
  • 【设计模式-4.8】行为型——中介者模式
  • OPENCV重点结构体Mat的讲解
  • C语言数据结构笔记3:Union联合体+结构体取8位Bool量
  • CentOS7关闭防火墙、Linux开启关闭防火墙
  • WebFuture:Ubuntu 系统上在线安装.NET Core 8 的步骤
  • OpenCV 键盘响应来切换图像
  • 实现C语言中srand()和rand()函数
  • .NET Core接口IServiceProvider
  • iptables实战案例
  • 【.net core】【watercloud】树形组件combotree导入及调用
  • Asp.net Core 通过依赖注入的方式获取用户
  • itop-3568开发板机器视觉opencv开发手册-图像绘制-画线
  • 【p2p、分布式,区块链笔记 MESH】 论文阅读 Thread/OpenThread Low-Power Wireless Multihop Net
  • Mac/iOS 如何解压 RAR 格式压缩包:常用工具与详细操作步骤
  • 【vue3学习】vue3入门
  • Flink进阶之路:解锁大数据处理新境界
  • iOS上传应用包错误问题 “Invalid bundle. The “UIInterfaceOrientationPortrait”“
  • 国外免费做网站软件/电脑编程培训学校哪家好
  • dede58织梦模板/河南seo关键词排名优化
  • wordpress多文件传递变量/搜索引擎优化方法案例
  • app跟网站的区别是什么/友情链接平台网站
  • 均安公司网站建设/百度网址浏览大全
  • 东莞网站推广衣裙/对网站进行seo优化