You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TensorFlow内置tf.nn.softmax为何比手写实现表现更优?

为什么自己实现的Softmax比TensorFlow原生的效果差?

嘿,这问题我之前调模型的时候也踩过坑!自己手写Softmax和用tf.nn.softmax在收敛速度、最终准确率上差这么多,核心原因基本都是数值稳定性和实现细节的问题,咱们来掰扯清楚:

1. 原生tf.nn.softmax做了数值稳定优化

Softmax的公式是:
$$\text{softmax}(x_i) = \frac{e{x_i}}{\sum_{j}e{x_j}}$$
如果你的logits里有比较大的数值(比如100),直接计算$e^{100}$会溢出变成inf,后续除以inf就会得到nan,这会让训练梯度直接失效,模型根本学不动。

而TensorFlow的原生tf.nn.softmax内部自动做了数值稳定处理:先把每个logits减去该行的最大值,再计算exp和归一化:
$$\text{softmax}(x_i) = \frac{e^{x_i - \max(x)}}{\sum_{j}e^{x_j - \max(x)}}$$
这样处理后,exp的输入最大是0,$e^0=1$,完全不会出现溢出的情况,数值计算更稳定。

如果你的自定义Softmax没加这一步,那训练中很容易出现数值异常,自然收敛慢、准确率低。

2. 结合损失函数的联合优化(关键!)

如果你的逻辑回归用的是交叉熵损失,那更要注意:原生的tf.nn.softmax_cross_entropy_with_logits(新版是tf.nn.softmax_cross_entropy_with_logits_v2)是把Softmax计算和交叉熵损失合并在一起优化的,用了更稳定的推导公式:

直接分开算的话,$\text{cross_entropy} = -\sum y_i \log(\text{softmax}(x_i))$,当$\text{softmax}(x_i)$接近0时,$\log(0)$会变成-inf,导致梯度爆炸或者消失。

而原生组合函数会用等价的稳定形式计算:
$$\text{cross_entropy} = \max(x) + \log(\sum e^{x_j - \max(x)}) - \sum y_i x_i$$
完全避免了计算$\log(\text{softmax})$的步骤,数值稳定性拉满,梯度计算也更高效。

给你补个稳定的自定义Softmax实现

如果一定要自己写Softmax,记得加上数值稳定步骤,比如:

def stable_softmax(logits):
    # 减去每行的最大值,防止exp溢出
    logits = logits - tf.reduce_max(logits, axis=1, keepdims=True)
    exp_logits = tf.exp(logits)
    softmax_output = exp_logits / tf.reduce_sum(exp_logits, axis=1, keepdims=True)
    return softmax_output

另外,训练时尽量用原生的交叉熵组合函数,别分开算Softmax再算损失,这会让数值稳定性大打折扣。

内容的提问来源于stack exchange,提问作者menphix

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:00:37