【机器学习基础】对 softmax 和 cross-entropy 求导

softmax与cross-entropy求导
本文详细解析了softmax函数和cross-entropy损失函数的求导过程,包括softmax函数的导数、cross-entropy的导数,以及两者结合求导的方法。通过数学推导,解释了softmax和cross-entropy在神经网络中的应用。

在论文中看到对 softmax 和 cross-entropy 的求导,一脸懵逼,故来整理整理。

以 softmax regression 为例来展示求导过程,softmax regression 可以看成一个不含隐含层的多分类神经网络,如 Fig. 1 所示。

1351564-20190429093302184-690937183.png
Fig. 1 Softmax Regression.

softmax regression 的矩阵形式如 Fig. 2 所示:


1351564-20190429092636696-1683586564.png

Fig. 2 Matrix Form.

符号定义

如 Fig. 1 所示,\(\bm x = [x_1, x_2, x_3]^{\top}\) 表示 softmax regression 的输入,\(\bm y = [y_1, y_2, y_3]^{\top}\) 表示 softmax regression 的输出,\(\bm W\) 为权重,\(\bm b = [b_1, b_2, b_3]^{\top}\) 为偏置。

令 Fig. 2 中 softmax function 的输入为 \(z_i = W_{i, 1}x_1 + W_{i, 2}x_2 + W_{i, 3}x_3 + b_i = W_{i}\bm x + b_i\),其中 \(i= 1, 2, 3\)\(W_{i}\) 表示权重矩阵 \(\bm W\) 的第 \(i\) 行;softmax function 的输出就是整个网络的输出,即 \(\bm y\)

Note: Fig. 1 和 Fig.2 中权重 \(W_{i, j}\) 表示第 \(i\) 个输出和第 \(j\) 个输入之间的联系,和一般的记法(即 \(W_{i, j}\) 表示第 \(i\) 个输入和第 \(j\) 个输出之间权重)相差一个转置。

\(m\) 表示输出的类别数,本文中 \(m = 3\)

Note: softmax regression 指的是整个网络,softmax function 仅仅指的是激活函数。本文默认 softmax 代指激活函数,当表示整个网络时会明确说明 softmax regression。

对 softmax 求导

softmax 函数的表达式为:
\[ y_i = \frac{e^{z_i}}{\sum_{t = 1}^m e^{z_t}} \tag{1} \]

其中 \(i= 1, 2, 3\)。由式(1)可知,\(y_i\) 与 softmax function 所有的输入 \(z_j, j = 1,2,3.\) 都有关。
softmax function 的输出对其输入求偏导:
\[ \frac{\partial y_i}{\partial z_j} = \frac{\partial \frac{e^{z_i}}{\sum_{t = 1}^m e^{z_t}}}{\partial z_j} \tag{2} \]

需要对式(2)中 \(i = j\)\(i \not = j\) 的情况进行分别讨论。因为式(1)分子中仅含第 \(i\) 项,式(2)中如果 \(i = j\),那么导数 \(\frac{\partial e^{z_i}}{\partial z_j} = e^{z_i}\),不为 0;如果 \(i \not = j\),那导数 \(\frac{\partial e^{z_i}}{\partial z_j} = 0\)

  • \(i = j\),则式(2)为:
    \[ \begin{split} \frac{\partial y_i}{\partial z_j} &= \frac{\partial \frac{e^{z_i}}{\sum_{t = 1}^m e^{z_t}}}{\partial z_j} \\ &= \frac{e^{z_i} \cdot \sum_{t = 1}^m e^{z_t} - e^{z_i} \cdot e^{z_j} }{(\sum_{t = 1}^m e^{z_t})^2} \\ &= \frac{e^{z_i}}{\sum_{t = 1}^m e^{z_t}} - \frac{e^{z_i}}{\sum_{t = 1}^m e^{z_t}} \cdot \frac{e^{z_j}}{\sum_{t = 1}^m e^{z_t}} \\ &=y_i(1 - y_j) \end{split} \tag{3} \]

当然,式(3)也可以写成 \(y_i(1 - y_i)\) 或者 \(y_j(1 - y_j)\),因为这里 \(i = j\)

  • \(i \not = j\),则式(2)为:
    \[ \begin{split} \frac{\partial y_i}{\partial z_j} &= \frac{\partial \frac{e^{z_i}}{\sum_{t = 1}^m e^{z_t}}}{\partial z_j} \\ &= \frac{0\cdot \sum_{t = 1}^m e^{z_t} - e^{z_i} \cdot e^{z_j} }{(\sum_{t = 1}^m e^{z_t})^2} \\ &= - \frac{e^{z_i}}{\sum_{t = 1}^m e^{z_t}} \cdot \frac{e^{z_j}}{\sum_{t = 1}^m e^{z_t}} \\ &= -y_iy_j \end{split} \tag{4} \]

对 cross-entropy 求导

\(\bm {\hat y} = [\hat{y}_1, \hat{y}_2, \hat{y}_3]^{\top}\) 为输入 \(\bm x\) 真实类别的 one-hot encoding。

cross entropy 的定义如下:
\[ H(\bm {\hat y}, \bm y) = - \bm {\hat y}^{\top} \log \bm y = - \sum_{t = 1}^m \hat{y}_t\log y_t \tag{5} \]

对 cross entropy 求偏导:(\(\log\) 底数为 \(e\)
\[ \frac{\partial H(\bm {\hat y}, \bm y) }{\partial y_i} = \frac{\partial [- \sum_{t = 1}^m \hat{y}_t\log y_t ]}{\partial y_i} = - \frac{\hat{y}_i}{y_i} \tag{6} \]

\(\bm {\hat y}\) 是确定的值,可以理解为样本的真实 one-hot 标签,不受模型预测标签 \(\bm y\) 的影响。

对 softmax 和 cross-entropy 一起求导

\[ \begin{split} \frac{\partial H(\bm {\hat y}, \bm y) }{\partial z_j} &= \sum_{i = 1}^{m} \frac{\partial H(\bm {\hat y}, \bm y) }{\partial y_i} \frac{\partial y_i }{\partial z_j} \\ &= \sum_{i = 1}^{m} -\frac{\hat{y}_i}{y_i} \cdot \frac{\partial y_i }{\partial z_j} \\ &= \left(-\frac{\hat{y}_i}{y_i} \cdot \frac{\partial y_i }{\partial z_j}\right )_{i = j} + \sum_{i = 1 , i \not = j}^{m} -\frac{\hat{y}_i}{y_i} \cdot \frac{\partial y_i }{\partial z_j} \\ &= -\frac{\hat{y}_j}{y_i} \cdot y_i(1-y_j) + \sum_{i = 1 , i \not = j}^{m} -\frac{\hat{y}_i}{y_i} \cdot -y_iy_j \\ &= - \hat{y}_j + \hat{y}_jy_j + \sum_{i = 1 , i \not = j}^{m} \hat{y}_iy_j \\ & = - \hat{y}_j + y_j\sum_{i = 1}^{m} \hat{y}_i \\ &= y_j - \hat{y}_j \end{split} \tag{7} \]

交叉熵 loss function 对 softmax function 输入 \(z_j\) 的求导结果相当简单,在 tensorflow 中,softmax 和 cross entropy 也合并成了一个函数,tf.nn.softmax_cross_entropy_with_logits,从导数求解方面看,也是有道理的。

在实际使用时,推荐使用 tensorflow 中实现的 API 去实现 softmax 和 cross entropy,而不是自己写,原因如下:

  • 都已经有 API 了,干嘛还得自己写,懒就是最好的理由;
  • softmax 因为计算了 exp(x),很容易就溢出了,比如 np.exp(800) = inf,需要做一些缩放,而 tensorflow 会帮我们处理这种数值不稳定的问题。

References

TensorFlow MNIST Dataset and Softmax Regression - Data Flair
链式法则 - 维基百科
Softmax函数与交叉熵 - 知乎

转载于:https://www.cnblogs.com/wuliytTaotao/p/10787510.html

<think>嗯,用户现在问的是`softmax_cross_entropy_with_logits``softmax`的区别。首先,我需要确认这两个概念在TensorFlow或者机器学习中的具体含义。根据之前的知识,`softmax`是一个激活函数,用于将logits转换为概率分布,而`softmax_cross_entropy_with_logits`可能是一个计算交叉熵损失函数的操作,结合了softmax交叉熵的计算。 用户可能在使用TensorFlow构建分类模型时遇到了这两个函数,不清楚它们各自的用途以及何时使用哪个。需要详细解释两者的区别,以及为什么有时候会一起使用,或者为什么存在一个合并的函数。 首先,我应该回顾这两个函数的具体定义用途。`softmax`函数的作用是将输入的值(logits)转化为概率分布,每个类别的概率在0到1之间,且所有类别的概率为1。而交叉熵损失函数通常用于衡量模型输出的概率分布与真实标签之间的差异。在分类任务中,通常会先用`softmax`处理logits得到概率,然后计算交叉熵损失。 不过,TensorFlow提供了`softmax_cross_entropy_with_logits`这个函数,它可能将这两个步骤合并,直接接收logits并计算交叉熵损失,而不需要显式地调用`softmax`。这样做可能有数值稳定性的好处,因为分开计算softmax再计算交叉熵可能会导致数值问题,尤其是在logits很大或很小的时候。合并后的函数可能在内部优化了计算过程,减少数值误差。 接下来需要解释两者的区别,包括功能上的不同、使用场景以及数值稳定性方面的考虑。同时,用户可能想知道在实际编程中应该如何选择,比如什么时候使用单独的softmax,什么时候使用合并的函数。 可能还需要给出代码示例,说明两者的使用方式,比如在使用`softmax`时,需要先应用softmax,然后手动计算交叉熵,而使用`softmax_cross_entropy_with_logits`则可以直接传入logits标签,得到损失值。此外,需要提醒用户注意标签的格式,比如是否是one-hot编码或者稀疏标签,以及函数的不同版本(如sparse_softmax_cross_entropy_with_logits)的区别。 另外,用户可能对为什么存在合并的函数有疑问,这时候需要解释数值计算上的优化稳定性问题,以及简化代码的好处。同时,可能还需要提到在TensorFlow 2.x中,这些函数是否有变化,比如是否推荐使用Keras中的损失函数而不是底层的函数。 最后,总结两者的主要区别,强调在训练分类模型时,推荐使用合并的函数以提升数值稳定性效率,而在需要显式获取概率分布时才单独使用softmax。</think>在TensorFlow中,`softmax``softmax_cross_entropy_with_logits`是深度学习中分类任务的核心组件,它们的关系与区别如下: --- ### **1. 功能定位** | | `softmax` | `softmax_cross_entropy_with_logits` | |--------------------|------------------------------------|---------------------------------------------| | **本质** | 激活函数 | 损失函数计算操作 | | **输入** | 原始logits(未归一化的预测值) | 原始logits + 真实标签(one-hot或类别索引) | | **输出** | 概率分布(为1) | 交叉熵损失值(标量) | | **数学表达式** | $\sigma(z_i) = \frac{e^{z_i}}{\sum_j e^{z_j}}$ | $-\sum y_i \log(\sigma(z_i))$ | --- ### **2. 使用场景对比** #### **(1) 单独使用`softmax`的情况** ```python import tensorflow as tf logits = tf.constant([[2.0, 1.0, 0.1], [0.5, 3.0, -1.0]]) probabilities = tf.nn.softmax(logits, axis=1) # 输出概率分布 # 结果示例: # [[0.6590, 0.2424, 0.0986], # [0.0553, 0.8225, 0.1222]] ``` **适用场景**: - 需要显式获取预测概率(如模型推理阶段输出概率) - 与其他自定义损失函数配合使用 #### **(2) 使用`softmax_cross_entropy_with_logits`的情况** ```python labels = tf.constant([[1, 0, 0], [0, 1, 0]]) # one-hot格式 loss = tf.nn.softmax_cross_entropy_with_logits(labels=labels, logits=logits) # 等价于先计算softmax,再计算交叉熵: # tf.reduce_sum(-labels * tf.math.log(tf.nn.softmax(logits)), axis=1) ``` **适用场景**: - 直接计算分类任务的交叉熵损失(训练阶段) - 需要数值稳定性的场景 --- ### **3. 关键区别** | **维度** | `softmax` | `softmax_cross_entropy_with_logits` | |------------------|------------------------------------|-------------------------------------------| | **数值稳定性** | 直接计算可能溢出(需手动处理) | 内部优化算法(避免指数爆炸/下溢) | | **计算效率** | 单独计算两步骤 | 合并计算(更高效) | | **梯度计算** | 需要手动反向传播 | 自动微分支持更好 | | **API演进** | 保留核心操作 | TF2.x中推荐改用`tf.keras.losses.CategoricalCrossentropy(from_logits=True)` | --- ### **4. 数值稳定性对比** 假设极端输入: ```python logits = tf.constant([[1000.0, 0.0]]) # 极大值 ``` - **单独使用`softmax`**: ```python tf.exp(1000) # 会导致数值溢出(inf) ``` - **使用`softmax_cross_entropy_with_logits`**: ```python # 内部使用log-sum-exp技巧: # log(exp(z1) + exp(z2)) = max(z) + log(exp(z1-max(z)) + exp(z2-max(z))) # 避免直接计算大指数值 ``` --- ### **5. 实际应用建议** 1. **训练分类模型时**: ```python # 推荐方式(TF2.x): model.compile(loss=tf.keras.losses.CategoricalCrossentropy(from_logits=True)) # 模型最后一层不需要激活函数,直接输出logits ``` 2. **需要输出概率时**: ```python logits = model(inputs) probabilities = tf.nn.softmax(logits) # 显式转换 ``` 3. **处理稀疏标签**: ```python # 使用稀疏交叉熵版本(避免one-hot转换) tf.nn.sparse_softmax_cross_entropy_with_logits(labels=class_indices, logits=logits) ``` --- ### **总结图示** ``` 原始logits → [softmax] → 概率分布 → [交叉熵计算] → 损失值 ⇅ ⇅ [softmax_cross_entropy_with_logits](合并优化) ``` 选择依据:是否需要显式获取概率分布 vs 直接高效计算损失。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值