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

463 阅读4分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 26 天,点击查看活动详情

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

最近更新时间:2022.12.6 最早更新时间:2022.6.12

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

@[toc]

1. 分类 - 交叉熵

讲解博文:损失函数|交叉熵损失函数 - 知乎

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)

多分类用CrossEntropyLoss(等于softmax+NLLLoss)

其他相关参考资料:

  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

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

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

2. 二分类 - hinge loss

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

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

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

在SVM中使用。

参考资料:

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

3. 回归 - 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. 罚项

这篇看了一遍,没太学好:Intuitions on L1 and L2 Regularisation | by Raimi Karim | Towards Data Science

5. 魔改损失函数的示例

  1. 多任务
    1. 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

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

  1. ranking loss_大猫子的博客-CSDN博客_rankingloss
  2. 图对比学习的最新进展 - 知乎