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

在Keras中基于logits计算二元交叉熵时模型效果变差的原因

问题描述

在Keras框架下搭建的两类模型仅损失计算方式不同,但效果出现显著差异:

  • 第一种实现:最后一层不设置激活函数,使用带from_logits=True参数的BinaryCrossentropy损失
model = keras.Sequential([
    keras.Input((input.shape[-1],)),
    keras.layers.BatchNormalization(),
    keras.layers.Dense(50, activation="relu"),
    keras.layers.BatchNormalization(),
    keras.layers.Dense(1),
])
model.compile(optimizer=keras.optimizers.Adam(), loss=keras.losses.BinaryCrossentropy(from_logits=True), metrics=["auc"])
  • 第二种实现:最后一层设置sigmoid激活函数,使用普通的BinaryCrossentropy损失
model = keras.Sequential([
    keras.Input((input.shape[-1],)),
    keras.layers.BatchNormalization(),
    keras.layers.Dense(50, activation="relu"),
    keras.layers.BatchNormalization(),
    keras.layers.Dense(1, activation="sigmoid"),
])
model.compile(optimizer=keras.optimizers.Adam(), loss=keras.losses.BinaryCrossentropy(), metrics=["auc"])

两类实现仅存在上述差异,但前者模型的AUC约为73.5,后者约为76.5,前者效果明显更差。按理论,基于logits计算损失精度应相当或更高,特此请教该现象的原因。

可能的原因分析

虽然理论上from_logits=True能避免sigmoid带来的梯度消失问题,但实际效果差异可能由以下几点导致:

  1. 初始化与训练动态差异
    当使用logits输出时,最后一层Dense的输出范围无约束(可正可负且数值可能极大),初始阶段损失值会远大于带sigmoid的模型。Adam优化器的学习率基于损失梯度缩放,过大的初始损失可能导致优化器更新步长异常,干扰早期收敛方向。而带sigmoid的模型输出被限制在(0,1)区间,初始损失更稳定,优化器能更快找到合理的更新路径。

  2. Batch Normalization的间接影响
    模型在最后一层Dense前加入了BatchNormalization。logits模式下,BatchNormalization的缩放和偏移会让输出分布更难稳定;而sigmoid的压缩作用会抵消部分分布波动,让训练过程更平滑,模型更容易收敛到泛化性更好的状态。

  3. AUC计算的特性差异
    AUC衡量的是样本排序能力,而非绝对概率准确性。带sigmoid的输出是符合直观预期的概率值,分布更均衡;而logits的数值范围无限制,训练中可能出现极端大的正值或负值,模型过度拟合这类极端样本后,会忽略多数样本的区分度,最终导致排序能力(AUC)下降。

  4. 梯度稳定性的实际表现
    虽然from_logits=True解决了sigmoid饱和区的梯度消失,但如果数据集存在样本不平衡或噪声较多的情况,logits模式下的梯度更容易出现爆炸。大梯度会导致参数更新幅度过大,训练震荡加剧,最终影响收敛后的泛化能力。而sigmoid的梯度压缩作用反而能在这种场景下让训练更稳定。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 05:25:26