Skip to main content

Logistic Regression with TensorFlow

A single Keras Dense(1) layer without an activation produces logits. Pair it with BinaryCrossentropy(from_logits=True) so the loss and output representation agree and the numerically stable combined operation is used.

import numpy as np
import tensorflow as tf
from sklearn.datasets import make_classification
from sklearn.metrics import accuracy_score, roc_auc_score
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

tf.keras.utils.set_random_seed(42)
tf.config.threading.set_inter_op_parallelism_threads(1)
tf.config.threading.set_intra_op_parallelism_threads(1)

X, y = make_classification(
n_samples=320,
n_features=6,
n_informative=4,
n_redundant=0,
class_sep=1.4,
random_state=42,
)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.25, stratify=y, random_state=42
)
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train).astype("float32")
X_test = scaler.transform(X_test).astype("float32")

model = tf.keras.Sequential([
tf.keras.Input(shape=(X_train.shape[1],)),
tf.keras.layers.Dense(1),
])
model.compile(
optimizer=tf.keras.optimizers.Adam(learning_rate=0.05),
loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
)
model.fit(X_train, y_train, epochs=80, batch_size=32, verbose=0, shuffle=False)
logits = model.predict(X_test, verbose=0).squeeze(1)
probabilities = tf.math.sigmoid(logits).numpy()
predictions = (probabilities >= 0.5).astype(int)

assert np.isfinite(probabilities).all()
print(f"Accuracy: {accuracy_score(y_test, predictions):.3f}")
print(f"ROC AUC: {roc_auc_score(y_test, probabilities):.3f}")

If the layer instead uses activation="sigmoid", configure the loss with from_logits=False; mixing those conventions gives the wrong objective. Select operational thresholds on validation data and examine calibration when predicted probabilities matter. Preserve the training-fitted scaler for every future prediction.

Keras is appropriate when the linear classifier is part of a larger differentiable model. scikit-learn is usually the clearer choice for ordinary tabular logistic regression, regularization search, and cross-validation.