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

无法手动验证tf.keras.losses.BinaryCrossentropy计算结果

计算错误的核心原因

手动计算时存在两个关键偏差:

  • 忽略了from_logits=True参数的作用:你使用的公式仅适用于输入y_pred是经过sigmoid激活、取值在[0,1]区间的概率值的场景。当from_logits=True时,传入的y_pred是未经过激活的原始logit值,取值范围为全体实数,框架会先对其做sigmoid映射转换为概率,再计算交叉熵损失,且整个计算流程做了数值稳定性优化。
  • 公式遗漏了前置负号:标准二分类交叉熵的公式是loss = -[y_true * log(p) + (1 - y_true) * log(1 - p)],没有负号的话计算出的损失值为负数,不符合损失函数的定义。
官方示例手动复现步骤

首先明确两个基础计算逻辑:

  • sigmoid激活公式:sigmoid(x) = 1 / (1 + exp(-x)),作用是将任意实数映射到[0,1]的概率区间
  • 当from_logits=True时,TensorFlow默认对所有样本的逐样本损失取均值作为最终输出(reduction参数默认值为sum_over_batch_size)

官方示例输入如下:

y_true = [0, 1, 0, 0]
y_pred = [-18.6, 0.51, 2.94, -12.8]

第一步:对每个logit值计算sigmoid概率

  • sigmoid(-18.6) ≈ 8.4e-9,无限趋近于0
  • sigmoid(0.51) ≈ 0.625
  • sigmoid(2.94) ≈ 0.95
  • sigmoid(-12.8) ≈ 2.7e-6,无限趋近于0

第二步:逐样本计算BCE损失

  • 样本1(y=0, p≈8.4e-9):- [0*log(p) + 1*log(1-p)] ≈ 8.4e-9,几乎为0
  • 样本2(y=1, p≈0.625):- [1*log(0.625) + 0] ≈ 0.47
  • 样本3(y=0, p≈0.95):- [0 + 1*log(1-0.95)] ≈ 2.996
  • 样本4(y=0, p≈2.7e-6):- [0 + 1*log(1-p)] ≈ 2.7e-6,几乎为0

第三步:对所有样本损失取均值
(0 + 0.47 + 2.996 + 0) / 4 ≈ 0.866,和官方给出的0.865结果一致,微小误差来自手动计算时的数值近似。

补充说明

框架专门提供from_logits=True的入参模式主要有两个优势:

  • 数值稳定性更强:如果手动先计算sigmoid再算交叉熵,当logit绝对值很大时(比如示例中的-18.6、-12.8),sigmoid结果会无限趋近于0或1,受浮点数精度限制容易出现下溢、上溢问题,导致log计算出现nan或inf。框架内部会将sigmoid和交叉熵计算合并,用等价数学式直接从logit推导损失,规避精度问题。
  • 简化代码逻辑:模型输出层不需要额外添加sigmoid激活,直接输出原始logit即可计算损失,仅在推理阶段将logit通过sigmoid转换为概率输出即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 19:36:25