训练分类器为什么要用cross entropy loss(交叉熵损失函数)而不能用mean square error loss(MSE,最小平方差损失函数)?

在一个人工智能群里,有人问起,训练分类器为什么要用cross entropy loss(交叉熵损失函数)而不能用mean square error loss(MSE,最小平方差损失函数)呢?

正好,在我的那本《深度学习之美》(第11章)提及这个问题,于是复制了一部分内容,作为回答,群里的同学觉得通俗易懂,于是,把我的回答贴到这里,算是一个总结:

---------

对于多分类的标签(即教师信号),从本质上看,通过One-hot操作,就是把具体的标签(Label)空间,变换到一个概率测度空间(设为 p),如[1,0,0](表示它是第一个品类)。可以这样理解这个概率,如果标签分类的标量输出为1(即概率为100%),其它值为0(即概率为0%)。


而对于多分类问题,在Softmax函数的“加工”下,神经网络的实际输出值就是一个概率向量,如[0.96, 0.04, 0],设其概率分布为q。现在我们想衡量p和q之间的差异(即损失),一种简单粗暴的方式,自然是可以比较p和q的差值,如MSE(不过效果不好而已)[1]。

一种更好的方式是衡量这二者的概率分布的差异,就是交叉熵,因为它的设计初衷,就是要衡量两个概率分布之间的差异。


图1  Softmax输出层示意图

为什么要用softmax一下呢?exp函数是单调递增的,它能很好地模拟max的行为,而且它能让“大者更大”。其背后的潜台词则是让“小者更小”,这个有点类似“马太效应”,强者愈强、弱者愈弱。这个特性,对于分类来说尤为重要,它能让学习效率更高。


举例来说,在图1中,原始的分类分数(或者说特征值)是[4, 1, -2],其中“4”和“1”的差值看起来没有那么大,但经过Softmax“渲染”之后,前者的分类概率接近于96%,而后者则仅在4%左右。而分值为“-2”的概率就“更惨”了,直接趋近于0。这正是Softmax回归的魅力所在。

这样一来,分类标签可以看做是概率分布(由one-hot变换而来),神经网络输出(经过softmax加工)也是一个概率分布,现在想衡量二者的差异(即损失),自然用交叉熵最好了。

参考文献:

[1] Golik P, Doetsch P, Ney H. Cross-Entropy vs. Squared Error Training: a Theoretical and Experimental Comparison[C]// Interspeech. 2013:1756-1760.


节选自 张玉宏 《深度学习之美》第11章,电子工业出版社,博文视点,2018年6月出版

### CrossEntropyLoss交叉熵损失)的概念及用法 #### 1. 概念解释 交叉熵损失函数是一种常用的多类分类问题中的目标函数,用于衡量预测概率分布与真实标签之间的差异。它通过最大化模型对正确类别的置信度来优化神经网络性能。 在数学上,对于单个样本 \(i\)交叉熵定义如下: \[ H(y_i, \hat{y}_i) = -\sum_{c=1}^{C}{y_{ic}\log(\hat{y}_{ic})} \] 其中, - \(y_{ic}\) 是第 \(i\) 个样本的真实标签向量中类别 \(c\) 的值(通常为 one-hot 编码形式),即如果该样本属于类别 \(c\) 则取值为 1,否则为 0; - \(\hat{y}_{ic}\) 表示模型对该样本属于类别 \(c\) 的预测概率[^1]。 当扩展到整个数据集时,则可以表示为所有样本平均后的总误差: \[ L = \frac{1}{N}\sum_{i=1}^{N}-\sum_{c=1}^{C}{y_{ic}\log(\hat{y}_{ic})}. \] #### 2. PyTorch 中的实现方式 PyTorch 提供了一个内置模块 `torch.nn.CrossEntropyLoss()` 来简化这一操作流程。此模块内部自动完成了 softmax 和负对数似然 (Negative Log Likelihood Loss, NLLLoss) 计算两步工作: ```python import torch import torch.nn as nn # 假设输入张量 shape=(batch_size, num_classes),以及 target 张量 shape=(batch_size,) input_tensor = torch.randn(3, 5, requires_grad=True) # batch_size=3, num_classes=5 target_tensor = torch.empty(3, dtype=torch.long).random_(5) loss_function = nn.CrossEntropyLoss() output_loss = loss_function(input_tensor, target_tensor) print(output_loss.item()) ``` 上述代码片段展示了如何创建并应用 `CrossEntropyLoss` 实例化对象于给定的数据之上[^2]。 #### 3. TensorFlow/Keras 中的应用实例 同样地,在 TensorFlow 或 Keras 库里也有相应的 API 支持此类功能——比如 `tf.keras.losses.CategoricalCrossentropy` 方法适用于已经过 one-hot 处理过的标签情况;而针对整型索引作为标签的情况则推荐使用 `SparseCategoricalCrossentropy`: ```python from tensorflow import keras import numpy as np model_output = tf.random.uniform((3, 5)) # 随机生成形状为 (3, 5) 的浮点数组模拟模型输出 true_labels_one_hot = [[1., 0., 0., 0., 0.], [0., 1., 0., 0., 0.], [0., 0., 1., 0., 0.]] cce = keras.losses.CategoricalCrossentropy(from_logits=False) result = cce(true_labels_one_hot, model_output) print('Result:', result.numpy()) # 如果 true labels 不是一维one-hot编码而是简单整数值的话 scc = keras.losses.SparseCategoricalCrossentropy(from_logits=False) integer_true_labels = [0, 1, 2] another_result = scc(integer_true_labels, model_output) print('Another Result:', another_result.numpy()) ``` 这里需要注意的是,默认情况下这些API假定传入的 logits 并未经过激活层转换成最终的概率分布形式(`from_logits=False`) ,因此需要显式指定参数或者提前完成相应变换。 #### 4. 总结说明 无论是采用 PyTorch 还是 Tensorflow 构建深度学习项目过程中遇到涉及多分类场景下的评估指标设计需求时,都可以考虑选用合适的版本组合起来构建高效的解决方案。具体而言,前者提供了简洁明了且灵活易用接口封装好的工具链路;后者凭借其强大的生态系统支持使得开发者能够更加专注于业务逻辑本身而非底层细节管理事务之中[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值