PyTorch的 nn.CrossEntropyLoss() 方法详解

本文通过图片直观展示了LogSoftmax与NLLLoss在PyTorch中的应用方法,这两种技术是神经网络中常见的损失函数组成部分,对于理解深度学习模型的训练过程至关重要。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

由于该方法的详细解释我已在jupyter中写好了,所以我就直接上图吧。
该方法可由nn.LogSoftmax(),nn.NLLLoss()两个方法组合而成.
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
参考文章:
https://zhuanlan.zhihu.com/p/98785902

<think>我们正在讨论PyTorch中的nn.CrossEntropyLoss()函数。根据用户的问题,他们想了解该函数的返回值。结合之前的对话历史,用户已经询问过函数原型,现在需要更详细地了解返回值的具体含义。 根据引用[1]:“多分类任务的标准损失函数。在PyTorch中,torch.nn.CrossEntropyLoss结合了LogSoftmax和NLLLoss。” 这意味着该函数实际上是在内部先进行LogSoftmax操作,然后应用负对数似然损失(NLLLoss)。因此,它的返回值是一个标量(如果reduction='mean'或'sum')或一个向量(如果reduction='none'),表示每个样本的损失。 具体来说: 1. 当reduction='none'时,返回一个形状为[batch_size]的张量,每个元素是对应样本的损失值。 2. 当reduction='mean'(默认值)时,返回所有样本损失的平均值(一个标量)。 3. 当reduction='sum'时,返回所有样本损失的总和(一个标量)。 此外,引用[1]还提到:“对于体素级别的分割,它独立计算每个体素的损失。” 这说明了在分割任务中,每个空间位置(体素)都被视为一个独立的样本,因此损失是在每个体素上独立计算的。 现在,我们根据这些信息来组织回答:</think>### PyTorch `nn.CrossEntropyLoss()` 返回值详解 `nn.CrossEntropyLoss()` 的返回值取决于参数 `reduction` 的设置,具体可分为三种情况: #### 1. **`reduction='none'`(不聚合)** - **返回值**:形状为 `(batch_size,)` 的张量 - **含义**:返回每个样本的独立损失值 - **数学表达**: $$ \text{loss}[i] = -\log\left( \frac{\exp(\text{input}[i][\text{target}[i]])}{\sum_{j=1}^{C} \exp(\text{input}[i][j])} \right) $$ - **示例**: ```python loss_fn = nn.CrossEntropyLoss(reduction='none') loss = loss_fn(logits, labels) # 形状: [3] ``` #### 2. **`reduction='mean'`(默认值,求平均)** - **返回值**:标量(0维张量) - **含义**:计算批次内所有样本损失的平均值 - **数学表达**: $$ \text{loss} = \frac{1}{N} \sum_{i=1}^{N} \text{loss}[i] $$ 其中 $N$ 为有效样本数(忽略 `ignore_index` 的样本)[^1] - **示例**: ```python loss_fn = nn.CrossEntropyLoss() # 默认reduction='mean' loss = loss_fn(logits, labels) # 标量值 ``` #### 3. **`reduction='sum'`(求和)** - **返回值**:标量(0维张量) - **含义**:计算批次内所有样本损失的总和 - **数学表达**: $$ \text{loss} = \sum_{i=1}^{N} \text{loss}[i] $$ - **示例**: ```python loss_fn = nn.CrossEntropyLoss(reduction='sum') loss = loss_fn(logits, labels) # 标量值 ``` ### 返回值特性说明 1. **数值类型**: - 始终返回 `torch.Tensor` 类型 - 可通过 `.item()` 方法获取 Python 浮点数 ```python loss_value = loss.item() # 转换为float ``` 2. **梯度支持**: ```python loss.backward() # 自动计算梯度 ``` 3. **类别权重影响**: 当设置 `weight` 参数时,损失计算会加权: $$ \text{loss}[i] = w_{\text{target}[i]} \cdot \text{原始损失}[i] $$ 其中 $w_c$ 是类别 $c$ 的权重[^1] 4. **标签平滑影响**: 当 `label_smoothing > 0` 时,损失计算基于平滑后的标签分布: $$ y_{\text{smooth}} = (1-\epsilon) \cdot y_{\text{true}} + \frac{\epsilon}{C} $$ 其中 $\epsilon$ 为平滑系数 ### 典型输出示例 ```python import torch import torch.nn as nn # 输入数据 (batch_size=2, classes=3) logits = torch.tensor([[1.2, -0.5, 2.1], [0.3, 2.1, -1.0]]) labels = torch.tensor([2, 1]) # 真实类别索引 # 不同reduction模式对比 print("None:", nn.CrossEntropyLoss(reduction='none')(logits, labels)) # 输出: tensor([0.3567, 0.2984]) print("Mean:", nn.CrossEntropyLoss()(logits, labels)) # 输出: tensor(0.3276) print("Sum:", nn.CrossEntropyLoss(reduction='sum')(logits, labels)) # 输出: tensor(0.6551) ``` ### 训练中的典型用法 ```python model = nn.Linear(10, 3) # 简单分类模型 optimizer = torch.optim.SGD(model.parameters(), lr=0.1) loss_fn = nn.CrossEntropyLoss() for x, y in dataloader: pred = model(x) loss = loss_fn(pred, y) # 获取损失值 optimizer.zero_grad() loss.backward() # 反向传播 optimizer.step() print(f"Batch loss: {loss.item():.4f}") ```
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值