Losses
A loss function turns predictions and labels into a single number that gradient descent minimizes. Pick the wrong one and the model can’t learn the task you think you’re training. TensorFlow ships dozens of standard losses plus a clean API for custom ones.
Built-in losses + masks + custom
EXAMPLE
import tensorflow as tf
import tensorflow.keras as keras
# 1) Regression losses
mse = keras.losses.MeanSquaredError()
mae = keras.losses.MeanAbsoluteError()
huber = keras.losses.Huber(delta=1.0) # robust to outliers
msle = keras.losses.MeanSquaredLogarithmicError()
y_true = tf.constant([1.0, 2.0, 3.0])
y_pred = tf.constant([1.1, 1.9, 2.8])
print(mse(y_true, y_pred).numpy()) # 0.01
# 2) Binary classification
bce = keras.losses.BinaryCrossentropy(from_logits=True)
bce_focal = keras.losses.BinaryFocalCrossentropy(gamma=2.0, from_logits=True)
# from_logits=True means the model outputs raw logits (no sigmoid)
# Numerically more stable than sigmoid + BCE separately.
logits = tf.constant([[2.0], [-1.0], [0.5]])
labels = tf.constant([[1.0], [0.0], [1.0]])
print(bce(labels, logits).numpy())
# 3) Multi-class
cce = keras.losses.CategoricalCrossentropy(from_logits=True) # one-hot labels
scce = keras.losses.SparseCategoricalCrossentropy(from_logits=True) # integer labels
# Most common: int labels + logits
logits = tf.constant([[2.0, 1.0, 0.1], [0.1, 2.0, 0.5]])
labels = tf.constant([0, 1])
print(scce(labels, logits).numpy())
# 4) Class imbalance — weighted loss
class_weights = {0: 1.0, 1: 5.0, 2: 2.0}
model.fit(X, y, class_weight=class_weights)
# Or sample weights per example
sample_w = tf.where(labels == 1, 5.0, 1.0)
model.fit(X, y, sample_weight=sample_w)
# 5) Sequence losses — mask the padding!
loss_fn = keras.losses.SparseCategoricalCrossentropy(
from_logits=True, reduction='none', # don't reduce yet
)
def masked_loss(y_true, y_pred):
mask = tf.cast(y_true != 0, tf.float32) # 0 = PAD token
loss = loss_fn(y_true, y_pred) * mask
return tf.reduce_sum(loss) / tf.reduce_sum(mask)
# 6) Custom loss — function form
def quantile_loss(q):
def loss(y_true, y_pred):
e = y_true - y_pred
return tf.reduce_mean(tf.maximum(q * e, (q - 1) * e))
return loss
model.compile(optimizer='adam', loss=quantile_loss(0.9))
# 7) Custom loss — class form (recommended; serializable)
@keras.utils.register_keras_serializable()
class DiceLoss(keras.losses.Loss):
def __init__(self, smooth=1.0, name='dice_loss'):
super().__init__(name=name)
self.smooth = smooth
def call(self, y_true, y_pred):
y_true = tf.cast(y_true, tf.float32)
y_pred = tf.sigmoid(y_pred)
inter = tf.reduce_sum(y_true * y_pred, axis=[1, 2, 3])
union = tf.reduce_sum(y_true + y_pred, axis=[1, 2, 3])
dice = (2 * inter + self.smooth) / (union + self.smooth)
return 1 - tf.reduce_mean(dice)
def get_config(self):
return {'smooth': self.smooth, 'name': self.name}
# 8) Combine losses (multi-task or hybrid)
bce = keras.losses.BinaryCrossentropy(from_logits=True)
def bce_dice(y_true, y_pred):
return bce(y_true, y_pred) + DiceLoss()(y_true, y_pred)
model.compile(optimizer='adam', loss=bce_dice)
# 9) Multiple outputs, multiple losses
model.compile(
optimizer='adam',
loss={'class': 'sparse_categorical_crossentropy', 'bbox': 'mse'},
loss_weights={'class': 1.0, 'bbox': 0.5},
)
# 10) Common bugs
# • from_logits=False with raw logits → wrong loss, model trains but slowly
# • from_logits=True after a softmax layer → double softmax, gradients vanish
# • CategoricalCrossentropy with int labels → shape error or NaN
# • Forgetting to mask PAD tokens → loss dominated by padding
# • MSE on classification → won't converge well
# • Cross-entropy on imbalanced data without weights → predicts majority class
Why it matters
Almost every loss has a from_logits flag — set it correctly or training will silently underperform. Pair it with the right final-layer choice: from_logits=True means no sigmoid/softmax in your model output, False means there is one.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
from tensorflow.keras import losses losses.SparseCategoricalCrossentropy() losses.BinaryCrossentropy() losses.MeanSquaredError()Try it Yourself »
Discussion
Loading…