How to handle class weight for multiple outputs in keras?
Quick answer
Keras does not accept class_weight for models with multiple outputs — it raises 'class_weight is only supported for Models with a single output'. The workaround is sample_weight: turn each output's class weights into a per-sample weight array, then pass them to model.fit as a dict keyed by output name, e.g. sample_weight={'out1': sw1, 'out2': sw2}. Alternatively, bake the class weighting into a separate custom loss per output using tf.gather.
Short answer: Keras rejects class_weight on a multi-output model — it raises "class_weight is only supported for Models with a single output." Convert each output's class weights into a per-sample weight array, then pass them to fit as a dict keyed by output name: sample_weight={"out1": sw1, "out2": sw2}. Or bake the weighting into a separate custom loss per output.
class_weight maps one {class: weight} dict to one set of labels. With several outputs, Keras can't tell which output the dict applies to, so it errors. The two reliable workarounds are below.
Option 1 — sample_weight as a per-output dict (recommended)
Turn each output's class weights into an array with one weight per training sample, then hand fit a dict keyed by the output layer names. This is the direct equivalent of class_weight, and it's the approach the Keras docs point you to.
import numpy as np
# class weights per output (from the class imbalance of each label set)
cw_out1 = {0: 1.0, 1: 5.0} # binary, positive class is rare
cw_out2 = {0: 1.0, 1: 2.0, 2: 3.0} # 3-class
# map each label to its weight -> one weight per sample, per output
sw_out1 = np.array([cw_out1[y] for y in y1_train])
sw_out2 = np.array([cw_out2[y] for y in y2_train])
model.compile(
optimizer="adam",
loss={"out1": "sparse_categorical_crossentropy",
"out2": "sparse_categorical_crossentropy"},
)
model.fit(
x_train,
{"out1": y1_train, "out2": y2_train},
sample_weight={"out1": sw_out1, "out2": sw_out2},
epochs=10,
batch_size=32,
)The keys ("out1", "out2") must match the name= of each output layer. Note the per-output weight arrays are built independently — the earlier mistake is weighting only one output and passing a single array.
Option 2 — a weighted loss per output
If you'd rather keep the weighting inside the loss, give each output its own loss. Keras calls a per-output loss with that output's y_true/y_pred (not a list of all of them), so tf.gather the right weight for each label:
import tensorflow as tf
def make_weighted_loss(class_weights):
cw = tf.constant(class_weights, dtype=tf.float32) # shape [num_classes]
def loss(y_true, y_pred):
per_example = tf.keras.losses.sparse_categorical_crossentropy(y_true, y_pred)
idx = tf.cast(tf.reshape(y_true, [-1]), tf.int32)
weights = tf.gather(cw, idx) # weight per sample
return tf.reduce_mean(per_example * weights)
return loss
model.compile(
optimizer="adam",
loss={"out1": make_weighted_loss([1.0, 5.0]),
"out2": make_weighted_loss([1.0, 2.0, 3.0])},
)
model.fit(x_train, {"out1": y1_train, "out2": y2_train}, epochs=10, batch_size=32)Which to use
sample_weightdict — simplest, no custom code, mirrorsclass_weightsemantics exactly. Prefer this.- Custom per-output loss — when you need more than class weighting (e.g. focal loss, or combining the weight with a per-sample importance).
Balance the outputs against each other with loss_weights={"out1": 1.0, "out2": 0.5} in compile — that's a separate knob from the class weighting above.
Related guides
Sources
Key takeaways
- •Keras rejects class_weight for multi-output models and raises an error.
- •The workaround is sample_weight: turn your class weights into a per-sample weight array for each output.
- •Pass the sample weights as a dict keyed by output name to model.fit(sample_weight=...).
- •Alternatively, bake the class weighting directly into a custom loss for each output.
Frequently asked questions
Why does class_weight fail with multiple outputs in Keras?
Keras only supports class_weight for single-output models; with multiple outputs it cannot map one class-weight dict to several label sets, so it errors.
How do I weight classes per output?
Convert each output's class weights into a per-sample weight array and pass them to model.fit as a sample_weight dict keyed by the output layer names.
Is a custom loss an option?
Yes. You can multiply each output's loss by its class weights inside a custom loss function, which gives full control over how each output is weighted.
Software Engineering Leader & Technical Author · Updated September 9, 2026