softmax与CrossEntropyLoss(),log_softmax与 NLLLoss()

LogSoftmax与NLLLoss详解

我们在处理单标签多分类问题时,若考虑用softmax来对模型最后输出作计算以得到各标签的概率分布,那之后可以通过crossentropy做一个似然估计,求得误差
但softmax求出来的概率分布中,每个标签的概率p∈(0,1),当有些标签的概率过小时就会导致下溢出(实数在计算机内用二进制表示,所以不是一个精确值,当数值过小的时候,被四舍五入为0,这就是下溢出。此时如果对这个数再做某些运算(例如除以它)就会出问题。)。
考虑softmax和crossentropy这个组合方案,crossentropy的计算是在概率分布外面套一个log 来似然,也就是做Log(Softmax(x))这个一个工作。那么直接在计算概率分布的时候加上log,把概率从(0,1)变为(-∞,0),这样就可以防止中间的计算中出现下溢出。 所以log_softmax说白了就是将本来应该由crossentropy做的套log的工作提前到预测概率分布这里来,跳过了中间的存储步骤,防止中间数值会有下溢出,使得数据更加稳定。
正是由于把log这一步从计算误差提到前面,所以用log_softmax之后就可以直接用NLLLoss来计算误差(它没有套log这一步,直接将输入取反,然后计算和label的乘积求和平均)。

在实践过程中出现了这段报错

nn.CrossentropyLoss(predictions, labels)

RuntimeError: Boolean value of Tensor with more than one value is ambiguous
虽然不知道什么原因,但只要改成这样就好了


                
在Python深度学习中,`softmax`和`cross_entropy_error`函数是构建分类模型时常用的关键组件。这些函数通常用于多类别分类任务中,其中`softmax`将输出转换为概率分布,而`cross_entropy_error`则衡量预测实际标签之间的差异。 ### `softmax` 函数 `softmax`函数的作用是将一个向量的每个元素转换为介于0和1之间的值,并且所有值的总和等于1,这样就可以解释为概率分布。其数学表达式如下: $$ \text{softmax}(z_i) = \frac{e^{z_i}}{\sum_{j} e^{z_j}} $$ 在 Python 中,可以使用 NumPy 或 TensorFlow 等库来实现该函数。以下是一个使用 NumPy 的简单实现示例: ```python import numpy as np def softmax(z): exp_z = np.exp(z - np.max(z)) # 防止数值溢出 return exp_z / np.sum(exp_z, axis=0) ``` ### `cross_entropy_error` 函数 交叉熵误差(Cross Entropy Error)用于衡量两个概率分布之间的差异。在深度学习中,它通常用来比较模型输出的概率分布真实标签的分布。对于多类别分类问题,交叉熵损失函数的公式为: $$ \text{CrossEntropy}(y, \hat{y}) = -\sum_{i} y_i \log(\hat{y}_i) $$ 以下是使用 NumPy 实现的一个版本: ```python def cross_entropy(y_true, y_pred): epsilon = 1e-15 # 防止log(0)错误 y_pred = np.clip(y_pred, epsilon, 1. - epsilon) return -np.sum(y_true * np.log(y_pred)) ``` ### 深度学习框架中的实现 #### TensorFlow TensorFlow 提供了多种交叉熵损失函数的实现,适用于不同的分类任务场景: - **`tf.nn.softmax_cross_entropy_with_logits`**:适用于多类分类问题,输入需要经过 softmax 层。 - **`tf.nn.sparse_softmax_cross_entropy_with_logits`**:前者类似,但标签不需要进行 one-hot 编码。 - **`tf.nn.sigmoid_cross_entropy_with_logits`**:适用于二分类或多标签分类问题。 - **`tf.nn.weighted_cross_entropy_with_logits`**:适用于正负样本不平衡的二分类问题 [^3]。 这些函数已经内置了数值稳定性处理,推荐在实际训练过程中使用它们而不是手动实现 [^2]。 #### PyTorchPyTorch 中,也可以找到类似的函数: - **`torch.nn.CrossEntropyLoss`**:结合了 `log_softmax` 和 `nll_loss`,适用于多类分类问题。 - **`torch.nn.BCELoss`**:适用于二分类问题,输入应为 sigmoid 输出。 - **`torch.nn.BCEWithLogitsLoss`**:结合了 sigmoid 和 BCELoss,推荐使用此函数以提高数值稳定性。 ### 示例:使用 PyTorch 计算交叉熵损失 ```python import torch import torch.nn as nn # 假设有3个样本,4个类别 output = torch.randn(3, 4, requires_grad=True) target = torch.tensor([1, 2, 3]) # 标签不需要one-hot编码 # 定义损失函数 criterion = nn.CrossEntropyLoss() loss = criterion(output, target) print("Cross Entropy Loss:", loss.item()) ``` ### 总结 - 对于简单的实验或教学目的,可以使用 NumPy 手动实现 `softmax` 和 `cross_entropy_error`。 - 在实际项目中,推荐使用 TensorFlow 或 PyTorch 提供的内置函数,因为它们不仅高效,而且具有良好的数值稳定性 [^2]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

联邦学习小白

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

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

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

打赏作者

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

抵扣说明:

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

余额充值