简简单单了解一下softmax与交叉熵


也看了不少softmax和交叉熵的文章了,不少文章对它们的来龙去脉做了比较清晰地梳理,有些文章讲得过于复杂,从信息量、相对熵(KL散度)讲到交叉熵,对于想要实际应用的同学来说,其实没有必要掌握它的来龙去脉,于是在此,对softmax和交叉熵的概念和公式进行简要说明,辅助以实际例子对它们具体说明。

1. softmax

softmax用于多分类过程中,它将多个神经元的输出,映射到 ( 0 , 1 ) (0,1) (0,1) 区间内,可以看成概率来理解,从而来进行多分类!假设我们有一个数组, V i V_i Vi 表示 V V V 中的第 i i i 个元素,那么这个元素的 softmax 值就是

S i = e V i ∑ j e V j S_i = \frac{e^{V_i}}{\sum_j e^{V_j}} Si=jeVjeVi

举个例子,假设有现在有3个数据,它们为[3,1,-3],经过softmax层之后,处理结果如下:

S 0 = e 3 e 3 + e 1 + e 3 = 0.87887824 S_0 = \frac{e^{3}}{e^{3}+e^{1}+e^{3}}=0.87887824 S0=e3+e1+e3e3=0.87887824
S 1 = e 1 e 3 + e 1 + e − 3 = 0.11894324 S_1= \frac{e^{1}}{e^{3}+e^{1}+e^{-3}}=0.11894324 S1=e3+e1+e3e1=0.11894324
S 2 = e − 3 e 3 + e 1 + e − 3 = 0.00217852 S_2= \frac{e^{-3}}{e^{3}+e^{1}+e^{-3}}=0.00217852 S2=e3+e1+e3e3=0.00217852
实际应用中,使用softmax需要注意数值溢出的问题。因为有指数运算,如果V数值很大,经过指数运算后的数值往往可能有溢出的可能。所以,需要对 V 进行一些数值处理:即V中的每个元素减去V中的最大值。公式如下所示:
D = m a x ( V ) D = max(V) D=max(V)

S i = e V i − D ∑ j e V j − D S_i = \frac{e^{V_i - D}}{\sum_j e^{V_j - D}} Si=jeVjDeViD

softmax实现代码如下所示:

import numpy as np

scores = np.array([3, 1, -3])

#原始函数操作
p = np.exp(scores) / np.sum(np.exp(scores))
print(p)

# 防止溢出操作
scores -= np.max(scores) 
print(scores)
p = np.exp(scores) / np.sum(np.exp(scores))
print(p)

输出:

[0.87887824 0.11894324 0.00217852]
[ 0 -2 -6]
[0.87887824 0.11894324 0.00217852]

为了便于理解,再放一张softmax的计算流程:

在这里插入图片描述

2. 交叉熵

交叉熵(cross entropy)是深度学习中常用的一个概念,一般用来求目标与预测值之间的差距

2.1 线性回归中的损失函数MSN

在线性回归问题中,常常使用MSE(Mean Squared Error)作为loss函数,比如:
在这里插入图片描述

这里的m表示m个样本的,loss为m个样本的loss均值。MSE在线性回归问题中比较好用,那么在逻辑分类问题中还是如此么

  • 为什么线性回归任务中不用MSN方法呢?
  • 答:主要原因是在分类问题中,使用sigmoid/softmx得到概率,配合MSE损失函数时,采用梯度下降法进行学习时,会出现模型一开始训练时(这时候的概率往往很低),学习速率非常慢的情况
  • 因为回归问题要求拟合实际的值,通过MSE衡量预测值和实际值之间的误差,可以通过梯度下降的方法来优化。而不像分类问题,需要一系列的激活函数(sigmoid、softmax)来将预测值映射到0-1之间。
  • 如果分类任务使用sigmoid,当输出是0或1的值时,梯度接近于0,也出现了梯度消失现象

2.2 交叉熵

交叉熵在单分类问题上基本是标配的方法,如下式所示,其中n表示n种类别。
在这里插入图片描述

  • 二分类

在二分类的情况下,模型最后需要预测的结果只有两种情况,对于每个类别我们的预测得到的概率为 p p p 1 − p 1-p 1p,此时表达式为:

在这里插入图片描述
其中:

  • y i y_i yi:表示样本 i i i的label,正类为1,负类为0。
  • p i p_i pi:表示样本 i i i预测为正类的概率。
  • 多分类

多分类的情况实际上就是对二分类的扩展:
在这里插入图片描述
其中:

  • M M M: 类别的数量
  • y i c y_{ic} yic:符号函数0或1,如果样本 i i i的真实类别等于 c c c取1,否则取0。
  • p i c p_{ic} pic:观测样本 i i i属于类别 c c c的预测概率

现在我们利用这个表达式计算下面例子中的损失函数值:

预测真实是否正确
0.3 0.3 0.40 0 1 (猪)正确
0.3 0.4 0.30 1 0 (狗)正确
0.1 0.2 0.71 0 0 (猫)错误

在这里插入图片描述

对所有样本的loss求平均:
在这里插入图片描述

预测真实是否正确
0.1 0.2 0.70 0 1 (猪)正确
0.1 0.7 0.20 1 0 (狗)正确
0.3 0.4 0.31 0 0 (猫)错误

在这里插入图片描述
对所有样本的loss求平均:
在这里插入图片描述
可以发现,虽然上面两个模型的预测值一样,但是交叉熵差别还挺大,所以我们通常使用交叉熵来计算多分类任务。

  • softmax与交叉熵联合使用如下

在这里插入图片描述


参考:https://zhuanlan.zhihu.com/p/35709485

### Softmax交叉熵损失的应用 在机器学习领域,尤其是神经网络中,Softmax 函数通常交叉熵损失一起使用来处理多分类问题。下面是一个简单的 Python 实现示例,展示了如何计算 softmax 输出以及应用交叉熵损失。 #### 计算 Softmax 的输出 给定一组未归一化的预测分数(logits),可以利用以下公式将其转换成概率分布: \[ \text{softmax}(z_i) = \frac{\exp(z_i)}{\sum_j \exp(z_j)} \] ```python import numpy as np def softmax(logits): exp_logits = np.exp(logits - np.max(logits)) # 数值稳定性考虑 return exp_logits / np.sum(exp_logits) logits_example = [2.0, 1.0, 0.1] print(f"Logits: {logits_example}") probabilities = softmax(logits_example) print(f"Probabilities after applying softmax: {probabilities.tolist()}") ``` 此代码片段定义了一个 `softmax` 函数并对其进行了测试[^1]。 #### 定义交叉熵损失函数 对于单个样本而言,如果已知真实的类别标签 y (one-hot 编码形式),那么可以通过下述方式定义交叉熵损失: \[ H(y,p)=-\sum_{i}y_ilog(p_i)\] 其中 \(p\) 表示由 softmax 得到的概率向量;\(y\) 是实际的目标分布,在这里是 one-hot 向量表示的真实标签。 ```python def cross_entropy_loss(true_labels, predicted_probs): true_class_indices = np.argmax(true_labels, axis=1) log_likelihoods = [] for i in range(len(predicted_probs)): prob_for_true_label = predicted_probs[i][true_class_indices[i]] log_likelihoods.append(-np.log(prob_for_true_label)) average_loss = sum(log_likelihoods)/len(log_likelihoods) return average_loss # 假设我们有三个类别的数据集 num_classes = 3 batch_size = 4 # 创建一些随机的 logits 数据作为输入 random_logits = np.random.rand(batch_size, num_classes) # 应用 softmax 获得预测概率 predicted_probabilities = softmax(random_logits).reshape((batch_size, num_classes)) # 构造一批假的一热编码真实标签 fake_ground_truth = [[1., 0., 0.], [0., 1., 0.], [0., 0., 1.], [1., 0., 0.]][:batch_size] loss_value = cross_entropy_loss(fake_ground_truth, predicted_probabilities) print(f"The computed Cross Entropy Loss is approximately: {loss_value:.4f}") ``` 这段代码实现了手动计算交叉熵损失的过程,并打印出了最终的结果[^2]。 通过上述两个部分可以看出,当面对一个多分类的任务时,先采用 softmax 将原始得分映射至合法的概率空间内,再借助于交叉熵度量模型给出的答案同实际情况间的差距大小,从而指导参数调整过程以优化性能表现[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

非晚非晚

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

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

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

打赏作者

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

抵扣说明:

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

余额充值