交叉熵损失原理和手动实现

机器学习--- 交叉熵损失(CrossEntropy Loss)--(附代码) 文章目录 阅读详情

PyTorch中交叉熵损失(Cross Entropy Loss)的三种计算方式详解

在深度学习分类任务中,交叉熵损失是最常用的损失函数之一。PyTorch的torch.nn.functional模块提供了便捷的API,同时我们也可以手动拆解计算过程。本文将结合代码示例,详细讲解三种等价的交叉熵损失计算方式,帮助理解其底层逻辑。

一、核心背景知识

交叉熵损失用于衡量模型输出的概率分布与真实标签分布的差异,对于分类任务(类别索引形式的标签),其计算公式为:
C r o s s E n t r o p y = − 1 N ∑ i = 1 N l o g ( p y i ) CrossEntropy = -\frac{1}{N}\sum_{i=1}^N log(p_{y_i}) CrossEntropy=−N1​i=1∑N​log(pyi​​)
其中:

  • N N N 是样本数量
  • p y i p_{y_i} pyi​​ 是模型对第 i i i个样本真实类别 y i y_i yi​的预测概率
  • 模型输出的logits(原始得分)需先通过softmax转换为概率,再取对数计算
二、完整代码示例(带详细注释)
import torch
import torch.nn.functional as F

# ===================== 1. 构造测试数据 =====================
# 模拟模型输出的logits:未经过softmax的原始得分
# batch_size=2(2个样本),num_classes=3(3个类别:0/1/2)
logits = torch.tensor([[2.0, 1.0, 0.1],  # 样本1:0类得分最高
                       [0.5, 3.0, 0.2]]) # 样本2:1类得分最高
# 真实标签:类别索引形式(非独热编码),这是F.cross_entropy要求的格式
targets = torch.tensor([0, 1])  # 样本1真实类别0,样本2真实类别1

print("===== 基础数据 =====")
print(f"模型输出logits(shape: {logits.shape}):")
print(logits)
print(f"\n真实标签:{targets}")

# ===================== 方式1:直接使用F.cross_entropy(推荐) =====================
# 方式1.1:reduction="none" → 输出每个样本的损失值
loss_none = F.cross_entropy(logits, targets, reduction="none")
# 方式1.2:reduction="mean" → 输出所有样本损失的平均值(默认方式)
loss_mean = F.cross_entropy(logits, targets, reduction="mean")

print("\n===== 方式1:直接调用F.cross_entropy =====")
print(f"每个样本的交叉熵损失:{loss_none}")
print(f"所有样本的平均交叉熵损失:{loss_mean}")

# ===================== 方式2:拆解为log_softmax + nll_loss =====================
# step1: log_softmax = log(softmax(logits)) → 先转概率再取对数
log_probs = F.log_softmax(logits, dim=-1)  # dim=-1表示对最后一维(类别维度)计算
# step2: nll_loss(负对数似然损失)→ 取真实类别对应的负对数概率
nll_loss = -log_probs[range(len(targets)), targets]  # 按索引取对应位置的值
manual_loss_none = nll_loss  # 对应reduction="none"
manual_loss_mean = nll_loss.mean()  # 对应reduction="mean"

print("\n===== 方式2:log_softmax + nll_loss(手动拆解) =====")
print(f"log_softmax结果:\n{log_probs}")
print(f"每个样本的交叉熵损失:{manual_loss_none}")
print(f"所有样本的平均交叉熵损失:{manual_loss_mean}")

# ===================== 方式3:完全手动实现(softmax + log + 负对数) =====================
# step1: softmax将logits转为概率分布
probs = F.softmax(logits, dim=-1)
# step2: 对概率取自然对数
log_probs_manual = torch.log(probs)
# step3: 取真实类别对应的负对数概率
manual_loss_none_v2 = -log_probs_manual[range(len(targets)), targets]
manual_loss_mean_v2 = manual_loss_none_v2.mean()

print("\n===== 方式3:完全手动实现(softmax → log → 负对数) =====")
print(f"softmax概率分布:\n{probs}")
print(f"概率取对数结果:\n{log_probs_manual}")
print(f"每个样本的交叉熵损失:{manual_loss_none_v2}")
print(f"所有样本的平均交叉熵损失:{manual_loss_mean_v2}")

# ===================== 验证三种方式等价性 =====================
print("\n===== 等价性验证 =====")
print(f"方式1与方式2结果是否一致:{torch.allclose(loss_none, manual_loss_none)}")
print(f"方式1与方式3结果是否一致:{torch.allclose(loss_none, manual_loss_none_v2)}")
三、三种计算方式详解
1. 方式1:直接调用F.cross_entropy(工程首选)
  • 核心逻辑:PyTorch封装了完整的交叉熵计算流程,内部自动完成softmax→log→负对数似然的全过程。
  • 优点:简洁高效,避免手动计算的误差(如torch.log(F.softmax())可能出现数值不稳定),是实际项目中最推荐的方式。
  • 关键参数:
    • reduction="none":返回每个样本的损失值,适用于需要对样本损失加权/筛选的场景;
    • reduction="mean":返回所有样本损失的平均值(默认),适用于常规批量训练;
    • reduction="sum":返回所有样本损失的总和。
2. 方式2:log_softmax + nll_loss(理解底层逻辑)
  • 核心逻辑:将交叉熵拆解为两个步骤:
    • F.log_softmax:先对logits做softmax得到概率,再取对数(数值稳定性优于单独调用torch.log(F.softmax()));
    • nll_loss(Negative Log Likelihood Loss):取真实类别对应的负对数概率,即交叉熵的核心计算。
  • 适用场景:需要单独获取“对数概率”的场景(如多标签分类、自定义损失函数)。
3. 方式3:完全手动实现(深入理解原理)
  • 核心逻辑:完全拆解为三个独立步骤,直观展示交叉熵的数学定义:
    1. F.softmax(logits):将logits转换为0-1之间的概率分布;
    2. torch.log(probs):对概率取自然对数;
    3. 取真实类别对应的负对数概率,得到每个样本的交叉熵损失。
  • 注意点:这种方式可能存在数值不稳定问题(如概率接近0时,torch.log会得到极大的负数),因此不推荐在工程中使用,仅用于学习理解。
四、输出结果说明

运行上述代码后,输出结果如下(数值略有浮点误差属正常):

===== 基础数据 =====
模型输出logits(shape: torch.Size([2, 3])):
tensor([[2.0000, 1.0000, 0.1000],
        [0.5000, 3.0000, 0.2000]])

真实标签:tensor([0, 1])

===== 方式1:直接调用F.cross_entropy =====
每个样本的交叉熵损失:tensor([0.4170, 0.1249])
所有样本的平均交叉熵损失:tensor(0.2710)

===== 方式2:log_softmax + nll_loss(手动拆解) =====
log_softmax结果:
tensor([[-0.4170, -1.4170, -2.3170],
        [-2.5498, -0.1249, -2.8498]])
每个样本的交叉熵损失:tensor([0.4170, 0.1249])
所有样本的平均交叉熵损失:tensor(0.2710)

===== 方式3:完全手动实现(softmax → log → 负对数) =====
softmax概率分布:
tensor([[0.6590, 0.2424, 0.0986],
        [0.1131, 0.8668, 0.0201]])
概率取对数结果:
tensor([[-0.4170, -1.4170, -2.3170],
        [-2.5498, -0.1249, -2.8498]])
每个样本的交叉熵损失:tensor([0.4170, 0.1249])
所有样本的平均交叉熵损失:tensor(0.2710)

===== 等价性验证 =====
方式1与方式2结果是否一致:True
方式1与方式3结果是否一致:True

总结

  1. 工程实践首选方式1:F.cross_entropy简洁、高效且数值稳定,满足绝大多数分类任务需求;
  2. 学习理解选方式2/3:方式2(log_softmax + nll_loss)兼顾可读性和稳定性,方式3完全手动拆解,适合理解交叉熵的数学本质;
  3. 核心等价关系:F.cross_entropy(logits, targets) = F.nll_loss(F.log_softmax(logits, dim=-1), targets),三种方式最终结果完全一致。

通过这三种方式的对比,不仅能掌握交叉熵损失的使用方法,更能深入理解其底层计算逻辑,为自定义损失函数、排查训练问题打下基础。

PyTorch实战:用加权交叉熵解决图像分类中的样本不平衡问题(附完整代码) 本文详细介绍了如何使用PyTorch中的加权交叉熵损失函数解决图像分类中的样本不平衡问题。通过数学原理分析、完整代码实现及真实数据集应用示例,展示了加权交叉熵如何有效提升少数类识别能力,并提供了动态权重调整、类别平衡采样器等进阶优化策略。 阅读详情

相关推荐

nn.CrossEntropyLoss细谈

nn.CrossEntropyLoss细谈 nn.CrossEntropyLoss的官方定义 This criterion combines LogSoftmax and NLLLoss in one single class. https://pytorch.org/docs/stable/nn.html CrossEntropyLoss代码实例 import torch y = torch.LongTensor([0]) z = torch.Tensor([[0.2,0.1,-0.1]]) crit

weixin_43918691的博客 554

交叉熵损失代码讲解

前言 在计算交叉熵时,有两种形式,一是输入labels的数字编码,二是labels对应的onehot编码。 1.引入库 代码如下(示例): import torch import torch.nn as nn 2.读入数据 代码如下(示例): loss_fn = nn.CrossEntropyLoss() pred = torch.tensor([[0.1,0.8,0.1],[0.2,0.1,0.7]],dtype=torch.float32) labels = torch.tensor([[0,1,0

weixin_47707533的博客 1333

从零实现深度学习框架——动手实现Softmax回归

上篇文章对Softmax回归进行了简单的介绍,本文我们就来从零实现Softmax回归。

日积月累,天道酬勤 2293

交叉熵损失的代码理解

交叉熵原理

qq_43733107的博客 1056

基于FreeRTOS与MQTT的物联网技术应用系列——步进电机控制(三)SD卡驱动、FatFS等的移植和ini配置文件读取的实现

本文实现了基于STM32F107VC的金牛开发板的基于SPI模式的SD卡驱动和FatFS的移植,以及利用minini库对ini配置信息文件进行读取。

sqshining的专栏 2131

西门子PLC1200 1214C DC/DC/DC 驱动步进电机

控制电机旋转的指令在“指令”中的“工艺”下的“Motion Control”(若出现程序块无法调用情况,则看备注3的第4条),本篇只介绍常用指令(若想学习详细与更多指令,请参考指令手册)。

2301_79553921的博客 1万+

交叉熵损失函数从原理到代码

讨论了交叉熵的定义和公式理解,并给出了pytorch中的API接口。

FFTang的博客 1468

用Python模拟随机游走:从一维到三维,直观理解马尔可夫链的常返性

本文通过Python模拟一维到三维的随机游走,直观展示马尔可夫链的常返性特性。使用NumPy和Matplotlib构建模拟器,揭示不同维度下随机游走的返回概率差异,帮助读者理解为什么一维和二维游走具有常返性,而三维游走可能永远迷失。文章包含完整的代码示例和可视化技巧,适合概率论和Python编程爱好者学习实践。

weixin_28694295的博客 391

【pytorch损失函数(2)】CrossEntropyLoss交叉熵CE

基于Pytorch实现,nn.CrossEntropyLoss(),是nn.logSoftmax()和nn.NLLLoss()的整合,可以直接使用它来替换网络中的这两个操作(此标准将LogSoftMax和NLLLoss集成到一个类中)。sigmoid对应的CE函数的反向传播就是在看我们预测值与真实值之间的差异,因此,sigmoid+CE也可以用于做数值的回归,因为反向传播本身,就是计算这两者的差异。x向量(预测)和目标分布(在错误类上为0,在正确类上为1的 one-hot 向量)表示。

AbiUni(YY熊) 2952

PLC与变频器联动控制:从开关量、模拟量到通讯的接线与编程实战

在工业自动化系统中,电机调速控制是核心需求之一,其关键在于实现可编程逻辑控制器(PLC)与变频器之间的可靠联动。其基本原理是通过PLC输出控制信号,由变频器接收并驱动电机按设定速度运行。这项技术的核心价值在于实现电机的软启停、精确调速与节能控制,广泛应用于风机、水泵、传送带及精密张力控制等场景。其中,开关量控制以其接线简单、抗干扰能力强的特点,成为基础且可靠的方案;而模拟量控制则能实现无级平滑调速,满足更高精度的工艺要求。本文以西门子、三菱等主流品牌为例,深入解析了这两种主流控制方式的硬件接线、参数设置与梯

1254

EPLAN 设备接线图模板制作

属性摆放 设备连接图设置(选项 - - 设置) 连接图生成

weixin_36447711的博客 7854

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

在机器学习和深度学习中,损失函数(Loss Function)是衡量模型预测值与真实值之间差异的函数,指示模型在当前参数下的“代价”或“错误”程度,其最小化过程即是模型训练的核心目标。损失函数通常位于模型的输出端、反向传播前,用来指导梯度下降等优化算法更新模型参数。

2301_76901778的博客 2393

【四足机器人实战】四足机器人运动学、动力学模型

认知有限,望大家多多包涵,有什么问题也希望能够与大家多交流,共同成长!四足机器人的运动学和动力学模型是其设计和控制的基础,涉及到如何精确描述和预测机器人在不同条件下的运动状态和行为本文先对四足机器人运动学、动力学模型做个简单的介绍,具体内容后续再更,其他模块可以参考去我其他文章运动学模型主要关注四足机器人的几何形态和时间序列下的运动特性,而动力学模型则进一步考虑了引起这些运动的力和扭矩的作用效果。运动学模型:运动学模型描述了四足机器人在没有考虑力的影响下的运动特性。

qq_35635374的博客 1051

pytorch学习笔记——手动实现loss函数

这里写目录标题1. 手动实现BCELoss损失函数2.手动实现CrossEntropyLoss损失函数 1. 手动实现BCELoss损失函数 BCELoss损失函数,又称 “二元交叉熵损失函数(binary cross entropy loss)” 计算公式: loss(x,class)=−logp(xclass).(class为x的真实类别标签) loss(x,class) = -{log {p(x_{class})}}. (class为x的真实类别标签) loss(x,class)=−logp(xcla

前进!前进!! 3923

Pointnet++环境配置(Windows11和ubuntu)及训练教程

PS:前两行命令是数据处理的命令,主要是进行数据读取和生成相应的训练数据格式,在Ubuntu上是正常运行的,在Windows上运行会失败,无法生成训练用的数据格式,所以最好在Ubuntu上训练,如果一定要用Windows,可以ubuntu上生成数据格式在导到Windows上,数据生成不需要安装torch。通过anaconda配置的环境,在官网找的命令安装的,版本是2.1.0+cu118。训练命令:我使用的pycharm,直接在pycharm中打开终端,运行命令。Python版本:3.7。

AIcurator的博客 2556

踩过20+工控视觉项目的坑后,我用C# + 海康相机 + YOLOv11实现了零依赖产线缺陷检测

触发式检测:只有光电传感器检测到零件到位,才触发相机拍照和算法检测,不是持续推理,减少工控机性能占用;全链路本地运行:从图像采集、算法推理到不良品剔除,所有逻辑全在本地工控机运行,不需要外网、不需要云端服务,哪怕产线断网也能正常运行;异常降级机制:算法推理异常时,系统自动触发产线缓停,同时声光告警,不会让不良品流到下工序,满足汽车行业IATF16949质量要求;模块化解耦:算法核心层和业务逻辑层完全分离,后续更换YOLO模型、新增缺陷类型,只需要替换模型文件,不需要修改业务逻辑;全链路可追溯。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 146

交叉熵:pytorch版本 vs 日常版本

首先看下平时我们所说的交叉熵: 传送门 在信息论中,交叉熵可认为是对预测分布q(x)用真实分布p(x)来进行编码时所需要的信息量大小。而在机器学习的分类问题中,真实分布p(x)是one-hot形式,表明独属于one-hot中1对应的角标的那个类,因此这也是为什么交叉熵常用于做分类问题的损失函数。 H(p,q)=∑xp(x)log⁡1q(x)=−∑xp(x)log⁡q(x)\begin{aligned} H(p, q) &=\sum_{x} p(x) \log \frac{1}{q(x)} \\ &a

随笔 1292

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

softmax回归的实现

softmax回归是logistic回归在多分类问题上的推广

sylviiiiiia的博客 510

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

损失函数总结

cross entropy loss 具体交叉熵的理论网络上有很多,这里就看下pytorch内部的计算方式 import torch import torch.nn as nn # 网络的输出数据,数据取自深度之眼pytorch入门lesson-15人民币二分类 # BATCH改为5,CLASS = 2 out = torch.tensor( [[-0.0223, 0.2420], [0.1782, 0.6221], [0.0887, 0.4575], [0.3041

terry_jt的博客 550

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

Pytorch手动实现softmax回归

【代码】softmax回归手动实现例子。

要把所有那些负面的信息当做对自身行为的评价,而不是对自身价值的评判。 307

李沐老师 PyTorch版——线性回归 + softmax回归的简洁实现(3)

可以看出,NLLLoss 帮我们对 target 进行了独热编码,我们仅需要传入一个分类标签的下标向量,并且公式这里是对应 reduction=‘none’ 的情况,也就是计算的结果是一个向量。首先,对这个损失函数最直观的介绍,在官方文档中说的很清楚,该函数计算 input 和 target 之间的交叉熵损失。的取值范围,如果传入的是一个 batch 的样本,batch_number = N,那么我们的 target 应该是一个大小为 N 的向量。net.apply 方法典型用途包括:初始化模型的参数。..

Mr_Yuwen_Yin的博客 1345

2022机器学习实战课内容笔记 - Lesson 4.6 逻辑回归的手动实现

Lesson 4.6 逻辑回归的手动实现   讨论完梯度下降的相关内容之后,接下来我们尝试使用梯度下降算法求解逻辑回归损失函数,并且通过一系列实验来观察逻辑回归的模型性能。 # 科学计算模块 import numpy as np import pandas as pd # 绘图模块 import matplotlib as mpl import matplotlib.pyplot as plt # 自定义模块 from ML_basic_function import * 一、逻辑回归损失函数的梯度计

m0_57446978的博客 1770

【人工智能】从零开始实现逻辑回归:Python代码与算法原理全解析

本文详细讲解如何使用 Python 从零实现逻辑回归模型,包括数学原理推导和代码实现。逻辑回归是一种常用于二分类问题的机器学习算法,其关键在于利用交叉熵损失函数和梯度下降优化方法。文章包含了逻辑回归的数学推导、梯度下降的具体步骤,并展示如何在 Python 中手动构建一个逻辑回归模型。详细的代码注释帮助读者理解模型实现的每一步,为今后深入学习更复杂的机器学习算法奠定坚实的基础。

一个被知识诅咒的人 1358

PyTorch编程基础06--训练模型的接口与使用

训练模型的接口与使用

weixin_44288092的博客 1397

详解逻辑回归(Logistic Regression):原理、推导、实现与实战

逻辑回归是一种经典的二分类算法,通过Sigmoid函数将线性回归输出转化为概率值。本文系统介绍了逻辑回归的核心原理,包括Sigmoid函数特性、交叉熵损失函数设计、梯度下降参数求解过程,并通过Python手动实现与sklearn库调用进行对比验证。文章还详细讲解了正则化处理、多分类策略等进阶内容,分析了模型的优缺点和典型应用场景。最后提供了特征工程、类别不平衡处理等实战技巧,帮助读者全面掌握逻辑回归的理论基础和实践应用。

m0_69585895的博客 2840

逻辑回归:原理+三框架代码实现

PyTorch 更灵活,适合自定义模型和训练流程,能清晰看到每一步训练细节。

SimpleLearning 489
上一篇: pytorch函数使用规律-不必再死记硬背
下一篇: 梯度计算 反向传播会不会缓存loss的求导公式
victory0431
博客等级 码龄6年 271粉丝 240原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值