keras
binary classification
from_logits
loss function
machine learning

How to properly use from_logits in keras loss function for binary classification?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In binary classification, from_logits tells Keras whether your model outputs raw scores or already-transformed probabilities. Getting that flag wrong means the loss interprets predictions incorrectly, which can slow training, distort gradients, and make evaluation look worse than it should.

What a Logit Actually Is

A logit is the raw output of the final linear layer before a sigmoid is applied. It can be any real number, positive or negative. A probability is the sigmoid-transformed version of that score and always falls between 0 and 1.

For binary classification, these two model designs are both valid:

  • Final layer has no activation and returns logits.
  • Final layer uses sigmoid and returns probabilities.

The loss configuration must match that design.

Case 1: Model Outputs Logits

If your final layer has no activation, use BinaryCrossentropy(from_logits=True). Keras then applies the numerically stable sigmoid-plus-cross-entropy calculation internally.

python
1import numpy as np
2import tensorflow as tf
3
4x = np.array([[0.0], [1.0], [2.0], [3.0]], dtype="float32")
5y = np.array([0, 0, 1, 1], dtype="float32")
6
7model = tf.keras.Sequential([
8    tf.keras.layers.Dense(1, input_shape=(1,))
9])
10
11model.compile(
12    optimizer="adam",
13    loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
14    metrics=[tf.keras.metrics.BinaryAccuracy(threshold=0.0)]
15)
16
17model.fit(x, y, epochs=5, verbose=0)
18logits = model.predict(x, verbose=0)
19print(logits[:3])

Notice the metric threshold. With logits, 0.0 is the decision boundary because sigmoid(0) equals 0.5.

Case 2: Model Outputs Probabilities

If your final layer already has a sigmoid activation, use from_logits=False, which is also the default.

python
1import numpy as np
2import tensorflow as tf
3
4x = np.array([[0.0], [1.0], [2.0], [3.0]], dtype="float32")
5y = np.array([0, 0, 1, 1], dtype="float32")
6
7model = tf.keras.Sequential([
8    tf.keras.layers.Dense(1, activation="sigmoid", input_shape=(1,))
9])
10
11model.compile(
12    optimizer="adam",
13    loss=tf.keras.losses.BinaryCrossentropy(from_logits=False),
14    metrics=["accuracy"]
15)
16
17model.fit(x, y, epochs=5, verbose=0)
18probs = model.predict(x, verbose=0)
19print(probs[:3])

Here the predictions are probabilities already, so the loss should not apply another sigmoid internally.

Why the Correct Pairing Matters

Using a sigmoid output with from_logits=True effectively applies sigmoid twice. That compresses values too aggressively and changes the gradient behavior.

Using raw logits with from_logits=False is also wrong because the loss expects numbers in the probability range. The computed loss can still produce values, but they no longer correspond to the intended objective.

The most stable setup for many modern models is a linear output layer plus from_logits=True. It avoids redundant activation work and uses a numerically stable implementation inside the loss.

Prediction Time Versus Training Time

When you train with logits, you often still want probabilities when serving the model or inspecting examples. Apply sigmoid at prediction time if needed.

python
logits = model.predict(x, verbose=0)
probabilities = tf.sigmoid(logits)
print(probabilities.numpy()[:3])

That separation is normal. The training graph can use logits for stability, while downstream code converts them to probabilities only when needed.

Choosing Metrics Carefully

Metrics must match the prediction format too. Standard accuracy assumes probabilities when used with a sigmoid output. With logits, use a threshold of 0.0 or convert predictions before metric evaluation.

That is why BinaryAccuracy(threshold=0.0) appears in the logits example. It treats positive logits as class 1 and negative logits as class 0.

Common Pitfalls

The most common mistake is forgetting that the final layer and the loss are a pair. Changing the layer activation without updating from_logits leaves the model in an inconsistent state.

Another issue is mixing training and inference conventions. A model trained with logits can be correct even if direct predictions are outside the 0 to 1 range. That is expected, not a sign of failure.

A final mistake is using metrics that assume probabilities while feeding them logits. If the metric threshold is wrong, model quality can appear worse than it really is.

Summary

  • Use from_logits=True when the final layer returns raw scores with no sigmoid activation.
  • Use from_logits=False when the final layer already outputs probabilities through sigmoid.
  • Do not apply sigmoid twice.
  • Logits are often preferable during training for numerical stability.
  • Make sure metrics and inference code match the output format.

Course illustration
Course illustration

All Rights Reserved.