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

TensorFlow文本分类示例中为何需设置from_logits=True?

问题:BinaryCrossentropy设置from_logits=True的原因及训练准确率无变化的问题

我在运行TensorFlow基础文本分类示例时产生疑问:为什么使用BinaryCrossentropy损失函数时需要设置from_logits=True?当我移除该参数,同时给最后一层Dense添加activation="sigmoid"后,训练过程中的binary_accuracy完全没有变化。

修改后的代码

model = tf.keras.Sequential([
  layers.Embedding(max_features + 1, embedding_dim),
  layers.Dropout(0.2),
  layers.GlobalAveragePooling1D(),
  layers.Dropout(0.2),
  layers.Dense(1, activation="sigmoid")]) # <-- 此处添加sigmoid激活

model.compile(loss=losses.BinaryCrossentropy(), # <-- 此处移除from_logits=True
              optimizer='adam',
              metrics=tf.metrics.BinaryAccuracy(threshold=0.0))

epochs = 10
history = model.fit(
    train_ds,
    validation_data=val_ds,
    epochs=epochs)

训练输出

Epoch 1/10
625/625 [==============================] - 4s 4ms/step - loss: 0.6635 - binary_accuracy: 0.4981 - val_loss: 0.6149 - val_binary_accuracy: 0.5076
Epoch 2/10
625/625 [==============================] - 2s 4ms/step - loss: 0.5492 - binary_accuracy: 0.4981 - val_loss: 0.4990 - val_binary_accuracy: 0.5076
Epoch 3/10
625/625 [==============================] - 2s 4ms/step - loss: 0.4453 - binary_accuracy: 0.4981 - val_loss: 0.4208 - val_binary_accuracy: 0.5076
Epoch 4/10
625/625 [==============================] - 2s 4ms/step - loss: 0.3792 - binary_accuracy: 0.4981 - val_loss: 0.3741 - val_binary_accuracy: 0.5076
Epoch 5/10
625/625 [==============================] - 3s 4ms/step - loss: 0.3360 - binary_accuracy: 0.4981 - val_loss: 0.3454 - val_binary_accuracy: 0.5076
Epoch 6/10
625/625 [==============================] - 3s 4ms/step - loss: 0.3054 - binary_accuracy: 0.4981 - val_loss: 0.3262 - val_binary_accuracy: 0.5076
Epoch 7/10
625/625 [==============================] - 3s 4ms/step - loss: 0.2813 - binary_accuracy: 0.4981 - val_loss: 0.3126 - val_binary_accuracy: 0.5076
Epoch 8/10
625/625 [==============================] - 3s 4ms/step - loss: 0.2616 - binary_accuracy: 0.4981 - val_loss: 0.3033 - val_binary_accuracy: 0.5076
Epoch 9/10
625/625 [==============================] - 3s 4ms/step - loss: 0.2456 - binary_accuracy: 0.4981 - val_loss: 0.2967 - val_binary_accuracy: 0.5076
Epoch 10/10
625/625 [==============================] - 2s 4ms/step - loss: 0.2306 - binary_accuracy: 0.4981 - val_loss: 0.2920 - val_binary_accuracy: 0.5076

解答

1. from_logits=True的作用

核心是为了数值稳定性:

  • 当模型最后一层没有激活函数时,输出的是原始logits(无范围限制的实数),设置from_logits=True会让损失函数内部自动完成sigmoid转换,同时避免直接计算sigmoid可能引发的梯度消失问题——当logits绝对值很大时,sigmoid的梯度会趋近于0,导致模型训练停滞。
  • 如果最后一层加了sigmoid激活,输出已经是0-1之间的概率值,此时from_logits应该设为False(默认值),损失函数会直接用概率值计算交叉熵。

2. 准确率无变化的原因

问题出在BinaryAccuracy(threshold=0.0)上:

  • 加了sigmoid后,模型输出是0-1的概率值,而threshold=0.0会把所有大于0的输出都判定为类别1。你的数据集正负样本比例接近1:1(初始准确率约0.5),模型输出几乎全大于0,相当于把所有样本归为一类,准确率自然固定在样本占比高的那一类数值上,不会随训练更新。

解决方法

把BinaryAccuracy的阈值改成默认的0.5即可,这样输出大于0.5判定为类别1,小于等于0.5判定为类别0,准确率会随训练正常变化:

model.compile(loss=losses.BinaryCrossentropy(),
              optimizer='adam',
              metrics=tf.metrics.BinaryAccuracy()) # 去掉threshold=0.0,使用默认0.5

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 11:03:14