机器学习周报(11.18-11.24)

文章目录

  • [1 Corss Entropy Loss](#1 Corss Entropy Loss)
    • [1.1 介绍](#1.1 介绍)
    • [1.2 代码举例](#1.2 代码举例)
  • [2 Negative Log Likelihood loss (NLL loss)](#2 Negative Log Likelihood loss (NLL loss))
    • [2.1 介绍](#2.1 介绍)
    • [2.2 代码举例](#2.2 代码举例)
  • [3 Kullback-Leibler divergence loss (KL loss)](#3 Kullback-Leibler divergence loss (KL loss))
    • [3.1 介绍](#3.1 介绍)
    • [3.2 代码举例](#3.2 代码举例)
  • [4 验证 D K L ( P ∣ ∣ Q ) = H ( p , q ) − H ( p ) D_{KL}(P||Q)=H(p,q)-H(p) DKL(P∣∣Q)=H(p,q)−H(p)](#4 验证 D K L ( P ∣ ∣ Q ) = H ( p , q ) − H ( p ) D_{KL}(P||Q)=H(p,q)-H(p) DKL(P∣∣Q)=H(p,q)−H(p))
    • [4.1 介绍](#4.1 介绍)
    • [4.2 代码验证](#4.2 代码验证)
  • [5 Binary Cross Entropy loss (BCE loss)](#5 Binary Cross Entropy loss (BCE loss))
  • [6 Cosine Similarity Loss](#6 Cosine Similarity Loss)
    • [6.1 介绍](#6.1 介绍)
    • [6.2 代码举例](#6.2 代码举例)
    • 总结

摘要

本文总结了 PyTorch 中常见的损失函数与相似度度量的理论基础和实现方法,重点分析了交叉熵、信息熵、负对数似然(NLL)、KL 散度和余弦相似度的数学原理及其在深度学习中的应用场景。通过示例代码详细阐述了这些概念的 PyTorch 实现方式,帮助读者在理论与实践之间建立联系。

Abstract

This article summarizes the theoretical foundations and implementation methods of commonly used loss functions and similarity metrics in PyTorch, focusing on the mathematical principles of cross-entropy, entropy, negative log-likelihood (NLL), KL divergence, and cosine similarity, as well as their applications in deep learning. By presenting detailed example code, the article bridges the gap between theory and practice, helping readers gain a comprehensive understanding.

1 Corss Entropy Loss

1.1 介绍

参数:

  • weight:指定权重,(dim),可选参数,可以给每个类指定一个权重。通常在训练数据中不同类别的样本数量差别较大时,可以使用权重来平衡。
  • ignore_index:指定忽略一个真实值,(int),也就是手动忽略一个真实值。
  • reduction:在[none, mean, sum]中选,string型。none表示不降维,返回和target相同形状;mean表示对一个batch的损失求均值;sum表示对一个batch的损失求和

输入:

可以看到对于Target,是有两种情况的。如果Target是类别的索引,那么Target的shape是比Input的shape少了通道维;如果Target是类别的概率值,那么Target的shape是与Input的shape相同。具体可以看官网。

1.2 代码举例

python 复制代码
import torch
import torch.nn as nn
import torch.nn.functional as F

# logits shape:[BS, NC]
batch_size = 2
num_class = 7

logits = torch.randn(batch_size, num_class)  # input unnormalized score
target_indices = torch.randint(num_class, size=(batch_size,))  # delta目标分布,是整形的索引 shape:(2,)
target_logits = torch.randn(batch_size, num_class)  # 非delta目标分布,概率分布 shape:[2,7]


ce_loss_fn = nn.CrossEntropyLoss()  # 实例化

## method 1 for CE loss
ce_loss = ce_loss_fn(logits, target_indices) 
print(f"cross entropy loss1: {ce_loss}")

## method 2 for CE loss
ce_loss = ce_loss_fn(logits, torch.softmax(target_logits, dim=-1))  
# 将target_logits 进行softmax在通道维上进行归一化成概率分布,和为1
print(f"cross entropy loss2: {ce_loss}")

输出结果均为标量:

python 复制代码
cross entropy loss1: 3.269336700439453
cross entropy loss2: 2.0783615112304688

2 Negative Log Likelihood loss (NLL loss)

2.1 介绍

对于负对数似然Negative Log Likelihood loss(NLL loss)来说,input是每个类别的log-probabilities,而target只能为类别索引。实际上,能用cross entropy loss的地方就能用negative log-likelihood loss,这在后面的代码部分进行进一步验证。

2.2 代码举例

python 复制代码
nll_fn = nn.NLLLoss()
nll_loss = nll_fn(torch.log(torch.softmax(logits, dim=-1)), target_indices)
print(f"negative log-likelihood loss: {nll_loss}")

​沿用上面初始化的logits,对其在通道维上进行softmax得到归一化概率值,再取对数,从而获得batch_size个样本的每个class的log-probabilities。target_indices是类别索引。

输出结果为标量:

python 复制代码
negative log-likelihood loss: 3.269336700439453

​ 如果沿用上面CELoss的logitstarget_indices的初始化值,可以看到cross entropy loss1和negative log-likelihood loss的输出结果是相同的。说明cross entropy loss = s o f t m a x + l o g + n l l l o s s =softmax+log+nll loss =softmax+log+nllloss

3 Kullback-Leibler divergence loss (KL loss)

3.1 介绍

P、Q相当于两个系统,KL距离的定义为:

D K L ( P ∣ ∣ Q ) = ∑ x ∈ X P ( x ) l o g ( P ( x ) Q ( x ) ) D_{KL}(P||Q)=\sum_{x\in X}P(x)log(\frac{P(x)}{Q(x)}) DKL(P∣∣Q)=x∈X∑P(x)log(Q(x)P(x))

其中,P在前,即以P为基准,衡量Q相对于P来说的差距。如果P、Q两个系统分布相同,则 D K L ( P ∣ ∣ Q ) = 0 D_{KL}(P||Q)=0 DKL(P∣∣Q)=0。所以KL散度具有非负性。

​ 对于官网上的公式来说,P等价于 y t r u e y_{true} ytrue,Q等价于 y p r e d y_{pred} ypred

这里需要注意的是inputtarget的shape应该相同。而且,为了避免下溢的一些问题,期望 input是在log的空间传入进来的,而target可以是 log 空间,也可以是线性空间。

3.2 代码举例

python 复制代码
kld_loss_fn = nn.KLDivLoss(reduction='mean')
kld_loss = kld_loss_fn(torch.log(torch.softmax(logits, dim=-1)), torch.softmax(target_logits, dim=-1))
print(f"Kullback-Leibler divergence loss : {kld_loss}")

输出结果为标量:

python 复制代码
Kullback-Leibler divergence loss : 0.07705999910831451

4 验证 D K L ( P ∣ ∣ Q ) = H ( p , q ) − H ( p ) D_{KL}(P||Q)=H(p,q)-H(p) DKL(P∣∣Q)=H(p,q)−H(p)

4.1 介绍

​ 首先从公式的角度来说明这个式子的正确性:

​ 这个公式的意思是p、q的KL散度=p、q的交叉熵 - p的信息熵。其中 p 的信息熵就是目标分布的信息熵。

4.2 代码验证

python 复制代码
# 4.验证 CE = IE + KLD  交叉熵=信息熵+KL散度
# 交叉熵
ce_loss_fn_smaple = nn.CrossEntropyLoss(reduction="none")  # 能够输出每一个样本的loss,不进行平均
ce_loss_sample = ce_loss_fn_smaple(logits, torch.softmax(target_logits, dim=-1))  # (b,)
print(f"cross entropy loss sample: {ce_loss_sample}")

# KL散度
kld_loss_fn_sample = nn.KLDivLoss(reduction="none")
kld_loss_sample = kld_loss_fn_sample(torch.log(torch.softmax(logits, dim=-1)), torch.softmax(target_logits, dim=-1)).sum(-1)
print(f"Kullback-Leibler divergence loss sample: {kld_loss_sample}")

# 计算目标分布的信息熵
target_information_entropy = torch.distributions.Categorical(probs=torch.softmax(target_logits, dim=-1)).entropy()
print(f"information entropy sample: {target_information_entropy}")  # IE为常数,如果目标分布是delta分布,IE=0

# 验证 CE = IE + KLD 是否成立
print(torch.allclose(ce_loss_sample, kld_loss_sample + target_information_entropy))  # 比较两个浮点数

​ 输出结果如下

python 复制代码
cross entropy loss sample: tensor([1.7736, 2.5585])
Kullback-Leibler divergence loss sample: tensor([0.1108, 1.1138])
information entropy sample: tensor([1.6628, 1.4447])
True

​可以看到,最终的输出结果为True,说明公式成立。值得一提的是,由于在数据集中的target是确定的,所以其信息熵也是确定的,为常数。所以优化交叉熵损失和KL散度损失是等价的,只是在数值上相差一个常数。

5 Binary Cross Entropy loss (BCE loss)

5.1 介绍

​以上所介绍的都常使用于多分类问题,BCE loss二项交叉熵适用于二分类问题。API中的公式如下:

l n = − w n [ y n ⋅ l o g ( x n ) + ( 1 − y n ) ⋅ l o g ( 1 − x n ) ] l_n = -w_n[y_n·log(x_n)+(1-y_n)·log(1-x_n)] ln=−wn[yn⋅log(xn)+(1−yn)⋅log(1−xn)]

要求TargetInput是相同的维度,对于target,数值应该在0-1之间。

5.2代码举例

python 复制代码
# 5.调用Binary Cross Entropy loss (BCE loss) 二分类的损失函数

bce_loss_fn = nn.BCELoss()
logits = torch.randn(batch_size)
prob_1 = torch.sigmoid(logits)  # 使用sigmoid求出概率值
target = torch.randint(2, size=(batch_size,))  # 二分类,只有0和1
bce_loss = bce_loss_fn(prob_1, target.float())
print(f"binary Cross Entropy loss: {bce_loss}")


# 1) BCEWithLogitsLoss = sigmoid + BCELoss ,传入的未归一化的logits
bce_logits_loss_fn = nn.BCEWithLogitsLoss()
bce_logits_loss = bce_logits_loss_fn(logits, target.float())
print(f"binary Cross Entropy with logits loss: {bce_logits_loss}")
print(torch.allclose(bce_logits_loss, bce_loss))  # 比较两个浮点数


# 2) BCE Loss 是特殊的 NLL Loss
nll_fn = nn.NLLLoss()
prob_0 = 1 - prob_1.unsqueeze(-1)  # 在通道维升维 [BS, 1]
prob = torch.cat([prob_0, prob_1.unsqueeze(-1)], dim=-1)  # [BS, 2]
nll_loss_binary = nll_fn(torch.log(prob), target)
print(f"negative likelihood loss binary: {nll_loss_binary}")
print(torch.allclose(bce_loss, nll_loss_binary))  # 比较两个浮点数

输出结果如下:

python 复制代码
binary Cross Entropy loss: 0.963399350643158
binary Cross Entropy with logits loss: 0.963399350643158
True
negative likelihood loss binary: 0.963399350643158
True

从输出结果中可以看出:

1)BCEWithLogitsLoss = sigmoid+BCELoss;

2)BCE Loss 是特殊的 NLL Loss,NLL Loss可以处理多分类问题,当目标只有0、1两个索引时,也可以处理二分类的情况。

6 Cosine Similarity Loss

6.1 介绍

Cosine Embedding Loss基于余弦相似度,从而评估两个输入的量是相似的还是不相似的。在对比学习、自监督学习、学习图片或文本的相似度、搜索引擎图片搜索等中大量应用。

​ 要求input1input2的shape相同,target的值为1或者-1。

6.2 代码举例

python 复制代码
cosine_loss_fn = nn.CosineEmbeddingLoss()
v1 = torch.randn(batch_size, 512)
v2 = torch.randn(batch_size, 512)
target = torch.randint(2, size=(batch_size, )) * 2 - 1  # 只能是-1~1
cosine_loss = cosine_loss_fn(v1, v2, target)
print(f"cosine similarity loss: {cosine_loss}")

​ 输出结果为标量:

python 复制代码
cosine similarity loss: 0.07631295919418335

总结

交叉熵 是多分类任务中最常用的损失函数,其核心是评估真实分布和预测分布的匹配程度。信息熵 衡量了分布的不确定性,通常用于分析概率分布的性质。负对数似然 专注于正确类别的预测概率,是交叉熵的重要组成部分,常与 log_softmax 配合使用。KL 散度 是两个分布之间的相对熵,用于知识蒸馏或分布匹配,能够有效衡量目标分布与预测分布的差异。余弦相似度 关注向量间的方向相似性,适用于特征匹配和相似性计算任务

相关推荐
Coding茶水间5 分钟前
基于深度学习的水果检测系统演示与介绍(YOLOv12/v11/v8/v5模型+Pyqt5界面+训练代码+数据集)
图像处理·人工智能·深度学习·yolo·目标检测·机器学习·计算机视觉
檐下翻书1738 分钟前
算法透明度审核:AI 决策的 “黑箱” 如何被打开?
人工智能
undsky_10 分钟前
【RuoYi-SpringBoot3-Pro】:接入 AI 对话能力
人工智能·spring boot·后端·ai·ruoyi
网易伏羲21 分钟前
网易伏羲受邀出席2025具身智能人形机器人年度盛会,并荣获“偃师·场景应用灵智奖
人工智能·群体智能·具身智能·游戏ai·网易伏羲·网易灵动·网易有灵智能体
搬砖者(视觉算法工程师)25 分钟前
什么是无监督学习?理解人工智能中无监督学习的机制、各类算法的类型与应用
人工智能
西格电力科技31 分钟前
面向工业用户的绿电直连架构适配技术:高可靠与高弹性的双重设计
大数据·服务器·人工智能·架构·能源
TextIn智能文档云平台35 分钟前
图片转文字后怎么输入大模型处理
前端·人工智能·python
Hy行者勇哥35 分钟前
从零搭建小智 AI 音箱 MCP 开发环境:自定义智能家居控制技能实战指南
人工智能·嵌入式硬件·硬件工程·智能家居
leaf_leaves_leaf35 分钟前
强化学习奖励曲线
人工智能
数据的世界0136 分钟前
重构智慧书-第18条:实力与实干
人工智能