机器学习/深度学习中的常用损失函数公式、原理与代码实践(持续更新ing...)

诸神缄默不语-个人CSDN博文目录

本文的结构是首先介绍一些常见的损失函数,然后介绍一些个性化的损失函数实例。

1. 分类 - 交叉熵

讲解博文:

  1. 损失函数|交叉熵损失函数 - 知乎
  2. 损失函数:交叉熵详解 - 知乎
  3. 交叉熵 - 维基百科,自由的百科全书
  4. softmax loss详解,softmax与交叉熵的关系 - 知乎

1.1 二分类 - BCELoss系

二分类可以使用BCELoss,比如链路预测任务预测某条边是否存在,或者多标签分类中将每个类作为一个二分类任务(但是一般来说这样效果会很差),就用BCELoss。
torch.nn.BCEWithLogitsLoss=sigmoid (torch.special.expit) +torch.nn.BCELoss
BCEWithLogitsLoss — PyTorch 1.12 documentation

直接使用torch.nn.BCEWithLogitsLoss在数学上更稳定。
torch.nn.BCEWithLogitsLoss(weight=None, size_average=None, reduce=None, reduction='mean', pos_weight=None)

单标签二分类(一般都是这样的):

loss = nn.BCEWithLogitsLoss()
input = torch.randn(3, requires_grad=True)
target = torch.empty(3).random_(2)
output = loss(input, target)
output.backward()

BCELoss和sigmoid分开的写法:(这个标签和预测结果就是多标签二分类,只是展开了)

loss_func=nn.BCELoss()
logp=torch.special.expit(logits)
loss=loss_func(logp.view(-1),train_label.view(-1))

多标签二分类:

target = torch.ones([10, 64], dtype=torch.float32)  # 64 classes, batch size = 10
output = torch.full([10, 64], 1.5)  # A prediction (logit)
pos_weight = torch.ones([64])  # All weights are equal to 1
criterion = torch.nn.BCEWithLogitsLoss(pos_weight=pos_weight)
criterion(output, target)  # -log(sigmoid(1.5))

输出:tensor(0.2014)

其他相关参考资料:

  1. 细数nn.BCELoss与nn.CrossEntropyLoss的区别_python_脚本之家
  2. nn.BCELoss与nn.CrossEntropyLoss的区别_耐耐~的博客-CSDN博客_bceloss和crossentropy
  3. nn.BCELoss()与nn.CrossEntropyLoss()的区别_Offer.harvester的博客-CSDN博客
  4. 【基础知识】多标签分类CrossEntropyLoss 与 二分类BCELoss_All_In_gzx_cc的博客-CSDN博客_bceloss crossentropy
  5. pytorch BCELoss和BCEWithLogitsLoss - 那抹阳光1994 - 博客园
  6. Pytorch nn.BCEWithLogitsLoss()的简单理解与用法_xiongxyowo的博客-CSDN博客_nn.bcewithlogitsloss

1.2 多分类

CrossEntropyLoss

CrossEntropyLoss(等于softmax+NLLLoss)

CrossEntropyLoss的入参:

  • weight:权重(Tensor对象,且要么该对象和CrossEntropyLoss对象的Tensor对象入参在同样的设备上,要么将整个CrossEntropyLoss对象放到入参所在的设备上,否则会报错)
    示例:weight=torch.from_numpy(np.array([0.1,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0])).float()),然后weight=weight.to(cuda_device)criterion=nn.CrossEntropyLoss(weight=weight),或者先criterion=nn.CrossEntropyLoss(weight=weight)criterion.to(cuda_device)

代码用法:

torch.nn.CrossEntropyLoss()(标签,预测出的logits)

注意,这里的标签可以是每个样本对应的标签向量(值为1的标签是ground-truth),也可以是每个样本对应的标签索引(取值为0至(标签数-1))

softmax + NLLLoss

有些情况下,在nn.Module的forward()中就已经对logits进行了归一化。在这种情况下就直接对输出用NLLLoss即可:

criterion=nn.NLLLoss()

loss=criterion(torch.log(logits + 1e-8),labels)

完整代码可参考:https://github.com/PolarisRisingWar/LJP_Collection/blob/master/models/MPBFN/train_and_test.py

1.3 sparse softmax

参考论文:

  1. (2016) From Softmax to Sparsemax: A Sparse Model of Attention and Multi-Label Classification
  2. (2019 ACL) Sparse Sequence-to-Sequence Models
    1. 论文笔记:稀疏序列到序列模型 - 知乎

通用参考资料:

  1. GLU, sparsemax, GELU激活函数_glu激活函数_rosefunR的博客-CSDN博客
  2. sparsemax和softmax - 知乎

苏神版:
总之大致来说就是仅用概率最高的k个类别的概率来通过softmax和交叉熵

  1. 原博文:SPACES:“抽取-生成”式长文本摘要(法研杯总结) - 科学空间|Scientific Spaces
  2. 稀疏Softmax(Sparse Softmax) - mathor

2. 分类 - hinge loss

2.1 二分类

真实标签 t = ± 1 t=±1 t=±1,分类器预测得分 y y y,损失函数: l ( y ) = max ⁡ ( 0 , 1 − t ⋅ y ) l(y)=\max(0,1-t\cdot y) l(y)=max(0,1ty)(1是margin)

hinge loss图像(图中蓝色线),以 t y ty ty为横轴, l l l为纵轴:
在这里插入图片描述
(图中绿色线是zero-one loss)

hinge loss要求 t y ≥ 1 ty≥1 ty1,就是要求分类正确的节点离分类界线尽量远。也就是模型需要将节点正确划分到超过阈值的程度。

在SVM中使用。

参考资料:

  1. Hinge loss - Wikiwand:这篇写得有问题
  2. 怎么样理解SVM中的hinge-loss? - 知乎:这里面的回答太进阶了,没看懂。

2.2 多分类

在这里插入图片描述
(图源:Hinge loss - Wikipedia,所谓 w x wx wx就是指分类器的预测得分)

3. 分类 - 不平衡问题 - focal loss

原论文:Focal Loss for Dense Object Detection

找了个解释的博文,但是没看懂:Focal loss论文详解 - 知乎

3. 回归 - MSE

https://pytorch.org/docs/stable/generated/torch.nn.MSELoss.html

import torch
import torch.nn as nn

loss = nn.MSELoss()
input = torch.randn(3, 5, requires_grad=True)
target = torch.randn(3, 5)
output = loss(input, target)
output.backward()

关于用MSE还是RMSE进行梯度下降,可以参考这个帖子:Why do we use RMSE instead of MSE? - PyTorch Forums 也没有给出具体的回答,回复者只说他个人倾向于用MSE,具体的解释我没有看懂

4. 对比学习/度量学习

4.1 triplet (ranking) loss

这是给出一个三元组,原样本-相似样本-不相似样本,然后用损失函数诱使相似样本对靠近,不相似样本对离远:
在这里插入图片描述

另一种写法(应该是等价的吧)就写成这样:

FaceNet: A Unified Embedding for Face Recognition and Clustering:
在这里插入图片描述

4.2 pairwise ranking loss

给出一对样本,将正样本对(相似样本)之间的距离拉小,负样本对之间的距离拉大。

在这里插入图片描述
(m是margin)

在这里插入图片描述
(y是样本对的正负性标签)

当样本对是正例时,其样本对的距离越大则L值越大;当是负例时则反之,但距离越大越好,但若超过一定阈值m,则该样本对对模型带来的影响就微乎其微,因此直接设置为零。

在这里插入图片描述
n(negative)样本可以分布在图中的任意区域,与a(anchor样本)的距离代表二者的相似度,距离越远相似度越小,模型的目标就是让正样例样本对p-a之间的距离变小,负样例样本对n-1的距离变大。

4.3 InfoNCE loss

希望从一个正样本对和n-1个负样本对中间使得正样本对之间的embedding距离拉得更近

5. 罚项

参考资料:

  1. 这篇看了一遍,没太学好:Intuitions on L1 and L2 Regularisation | by Raimi Karim | Towards Data Science
  2. ML 入门:归一化、标准化和正则化 - 知乎:这篇写得挺清晰的,我主要简单看了一下LP范数/正则项的部分

6. 魔改损失函数的示例

  1. 多任务:一般来说就是直接加起来
    1. 我之前写过:用huggingface.transformers在文本分类任务(单任务和多任务场景下)上微调预训练模型
    2. SPACES模型,示例损失函数部分TensorFlow1+Keras代码:SPACES/seq2seq_model.py at main · bojone/SPACES
  2. 自定义:图神经网络节点表征模型PTA,PyTorch代码,我参考原始项目复现出来的。损失函数分成2部分,一部分在模型中直接定义随epoch变化的损失函数:rgb-experiment/pta.py at master · PolarisRisingWar/rgb-experiment,一部分在训练和测试的时候额外增加设定的超参:rgb-experiment/itexperiments.py at master · PolarisRisingWar/rgb-experiment
  3. 多任务+自定义:legal judgment prediction模型EPM:在train()函数中,又是多任务,又加了mask(在原论文中定义为“constraint”):EPM/model.py at main · WAPAY/EPM

7. 代码撰写常见问题

  1. PyTorch的:python - Bool value of Tensor with more than one value is ambiguous in Pytorch - Stack Overflow:一般就是在损失函数类后面少写了一个括号
  2. 对于NaN现象的解决方案
    1. 梯度裁剪
      1. 梯度剪裁: torch.nn.utils.clip_grad_norm_()_torch 梯度裁剪_Mikeyboi的博客-CSDN博客
      2. 详解torch.nn.utils.clip_grad_norm_ 的使用与原理_iioSnail的博客-CSDN博客
      3. 详讲torch.nn.utils.clip_grad_norm__Litra LIN的博客-CSDN博客
      4. Pytorch梯度截断:torch.nn.utils.clip_grad_norm_ - 知乎
      5. python - How to do gradient clipping in pytorch? - Stack Overflow
      6. Python Examples of torch.nn.utils.clip_grad_norm_
    2. 【PyTorch】梯度爆炸、loss在反向传播变为nan - 知乎
    3. 【解决方案】pytorch中loss变成了nan | 神经网络输出nan | MSE 梯度爆炸/梯度消失_pytorch中loss中log除0_枇杷鹭的博客-CSDN博客
    4. 警惕!损失Loss为Nan或者超级大的原因 - Oldpan的个人博客

8. 其他文中未提及的参考资料

  1. ranking loss_大猫子的博客-CSDN博客_rankingloss
  2. 图对比学习的最新进展 - 知乎
  3. 卷积神经网络 + 机器视觉: L3_Loss Functions and Optimization (斯坦福CS231n)_CHUNLIN GO的博客-CSDN博客_l3 loss:只看了前面的一小部分
  4. pytorch中交叉熵函数torch.nn.CrossEntropyLoss()怎么加入权重_交叉熵权重设置_to do 1+1的博客-CSDN博客
<think>嗯,我现在要理解偏差和方差的区别。先回忆一下,这两个术语听起来都是统计学里的概念,可能和模型预测有关吧。偏差,可能是指预测值和真实值之间的差距?而方差,可能是指模型预测的波动情况?不过具体怎么区分呢? 首先,我好像记得偏差-方差分解,就是说模型的泛化误差可以分解为偏差、方差和噪声。这个分解可能帮助我们理解模型的问题所在。比如,如果一个模型在训练数据上表现很好,但在测试数据上差,可能方差太大,也就是过拟合了。相反,如果模型在训练和测试上都表现不好,可能是偏差太高,欠拟合了。 那偏差具体是什么呢?假设真实的关系是$f(x)$,模型预测的是$\hat{f}(x)$,那么偏差可能是指$\hat{f}(x)$的期望预测和真实值$f(x)$之间的差异。数学上可能表示为$\text{Bias} = E[\hat{f}(x)] - f(x)$。如果模型的偏差高,说明模型可能过于简单,无法捕捉数据中的真实关系,比如用线性模型去拟合非线性数据,导致系统性的预测偏离。 方差呢,应该是模型预测的变化范围,即模型对于不同训练集的敏感程度。方差大意味着模型对训练数据中的随机噪声过于敏感,导致预测结果波动大。数学上可能表示为$\text{Variance} = E[(\hat{f}(x) - E[\hat{f}(x)])^2]$。比如,一个高方差的模型可能非常复杂,比如深度很深的决策树,容易记住训练数据中的噪声,从而在新数据上表现不稳定。 那么偏差和方差的权衡(Bias-Variance Tradeoff)是怎么回事呢?好像是在模型复杂度增加时,偏差会减少(因为模型能更好地拟合数据),但方差会增加(因为模型对数据变动更敏感)。反之,模型简单时,偏差大,方差小。所以需要找到一个平衡点,使得总误差最小。 举个例子可能更好理解。比如用线性回归模型,假设数据实际上是非线性的,这时候模型可能偏差高,因为它无法捕捉非线性关系,而方差低,因为模型简单,参数变化不会太大。如果用高阶多项式回归,可能偏差低,但方差高,尤其是当数据有噪声时,模型会过拟合。 那如何解决高偏差或高方差的问题呢?对于高偏差,可能需要用更复杂的模型,增加特征,或者减少正则化。而对于高方差,可能需要简化模型,增加训练数据,或者使用正则化、交叉验证等方法。 不过,有没有可能同时存在高偏差和高方差的情况?比如模型既不够灵活,又在某些地方对噪声敏感?或者这通常不会同时发生?可能需要更深入理解分解公式。总误差是偏差平方、方差加上噪声项,所以一般来说,如果模型在偏差和方差中有一个很高,另一个可能不会同时很高,但具体情况可能取决于数据和模型的选择。 再想想,噪声项指的是数据本身的不可约误差,这部分无法通过模型优化来减少。所以总误差=偏差² + 方差 + 噪声²。所以优化模型的时候,只能控制偏差和方差,噪声无法控制。 总结一下,偏差是模型预测的平均误差,即系统性偏离真实值的程度;方差是预测值的波动性,即模型对训练数据变化的敏感度。两者之间存在权衡关系,模型复杂度的选择需要平衡这两个因素,以达到最小的总误差。</think>偏差(Bias)和方差(Variance)是机器学习中描述模型预测误差的两个核心概念,它们的区别和权衡直接影响模型的泛化能力。以下分步说明: --- ### 1. **定义数学表达** - **偏差**:模型预测值的期望真实值之间的系统性差异。 数学表示为: $$\text{Bias}[\hat{f}(x)] = E[\hat{f}(x)] - f(x)$$ - 高偏差:模型过于简单(如线性模型拟合非线性数据),无法捕捉数据规律,导致欠拟合。 - 低偏差:复杂模型能更贴近真实关系(如高阶多项式回归)。 - **方差**:模型预测值自身的波动性,反映对训练数据变化的敏感度。 数学表示为: $$\text{Variance}[\hat{f}(x)] = E\left[\left(\hat{f}(x) - E[\hat{f}(x)]\right)^2\right]$$ - 高方差:模型过于复杂(如过深的决策树),过度拟合训练噪声,导致过拟合。 - 低方差:简单模型对数据扰动不敏感,但可能忽略真实模式。 --- ### 2. **偏差-方差分解** 总泛化误差可分解为三部分: $$E[(y - \hat{f}(x))^2] = \text{Bias}^2[\hat{f}(x)] + \text{Variance}[\hat{f}(x)] + \sigma^2$$ 其中: - $\text{Bias}^2$:偏差平方(系统性误差) - $\text{Variance}$:方差(模型稳定性) - $\sigma^2$:数据噪声(不可约误差) --- ### 3. **直观理解** - **高偏差模型** - 示例:用直线拟合正弦曲线。 - 表现:训练集和测试集误差均高(欠拟合)。 - **高方差模型** - 示例:高阶多项式拟合带噪声数据。 - 表现:训练集误差低,测试集误差高(过拟合)。 --- ### 4. **偏差-方差权衡(Bias-Variance Tradeoff)** - **模型复杂度误差关系** - 简单模型 ➔ 高偏差,低方差 - 复杂模型 ➔ 低偏差,高方差 - 目标:选择复杂度使总误差最小(平衡点见下图)。 ![Bias-Variance Tradeoff](https://miro.medium.com/v2/resize:fit:720/format:webp/1*RQ6ICt_FBSx6mkAsGVwx8g.png) --- ### 5. **解决方法** - **高偏差问题(欠拟合)** - 增加模型复杂度(如更多层、非线性激活函数)。 - 添加更多特征或减少正则化强度。 - **高方差问题(过拟合)** - 简化模型(如减少参数、剪枝决策树)。 - 增加训练数据或使用正则化(L1/L2)。 - 交叉验证、早停法(Early Stopping)。 --- ### 6. **总结对比表** | **特征** | **偏差(Bias)** | **方差(Variance)** | |----------------|--------------------------------|------------------------------| | **定义** | 预测值真实值的系统性偏离 | 预测值自身的波动性 | | **模型复杂度** | 低时高,高时低 | 低时低,高时高 | | **典型问题** | 欠拟合 | 过拟合 | | **优化方向** | 复杂化模型、增加特征 | 简化模型、正则化、更多数据 | --- 通过理解偏差和方差的区别,可以更有针对性地调整模型,提升预测性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

诸神缄默不语

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值