Python
Google Colab
Machine Learning
ValueError
Class Weight

on colab - class_weight is causing a ValueError The truth value of an array with more than one element is ambiguous. Use a.any or a.all

Master System Design with Codemia

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

Introduction

When training a Keras model with imbalanced classes on Google Colab, passing class_weight to model.fit() can trigger ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all(). This error occurs when class_weight is passed as a NumPy array or an incorrectly formatted structure instead of a plain Python dictionary. Keras internally checks the truth value of the class weight object, and NumPy arrays do not support boolean evaluation of multi-element arrays. The fix is to ensure class_weight is a dict mapping class indices to weight values.

The Error Explained

python
1import numpy as np
2
3# This is what happens internally when Keras checks class_weight
4weights = np.array([1.0, 2.5])
5
6# NumPy arrays cannot be evaluated as a single boolean
7if weights:  # ValueError!
8    pass
9# ValueError: The truth value of an array with more than one element is ambiguous
10
11# Python dicts work fine with truth checks
12weights_dict = {0: 1.0, 1: 2.5}
13if weights_dict:  # True — no error
14    pass

Python can evaluate a dictionary as True (non-empty) or False (empty), but a NumPy array with multiple elements cannot be reduced to a single boolean. Keras performs this kind of check internally when processing the class_weight parameter.

The Wrong Way (Causes the Error)

python
1import numpy as np
2from tensorflow import keras
3
4model = keras.Sequential([
5    keras.layers.Dense(64, activation='relu', input_shape=(10,)),
6    keras.layers.Dense(3, activation='softmax')
7])
8model.compile(optimizer='adam', loss='categorical_crossentropy')
9
10# WRONG: passing a numpy array
11class_weights = np.array([1.0, 2.5, 1.5])
12model.fit(X_train, y_train, class_weight=class_weights, epochs=10)
13# ValueError: The truth value of an array with more than one element is ambiguous
14
15# WRONG: passing a list
16class_weights = [1.0, 2.5, 1.5]
17model.fit(X_train, y_train, class_weight=class_weights, epochs=10)
18# Same error in some Keras versions

The Correct Way (Dictionary Format)

python
1from tensorflow import keras
2
3model = keras.Sequential([
4    keras.layers.Dense(64, activation='relu', input_shape=(10,)),
5    keras.layers.Dense(3, activation='softmax')
6])
7model.compile(optimizer='adam', loss='categorical_crossentropy')
8
9# CORRECT: use a dictionary mapping class index to weight
10class_weights = {0: 1.0, 1: 2.5, 2: 1.5}
11model.fit(X_train, y_train, class_weight=class_weights, epochs=10)

The class_weight parameter must be a Python dict where keys are integer class indices (0, 1, 2, ...) and values are the corresponding float weights.

Computing Class Weights Automatically

python
1import numpy as np
2from sklearn.utils.class_weight import compute_class_weight
3
4# For integer labels
5y_train_labels = np.array([0, 0, 0, 1, 1, 2])  # imbalanced
6
7weights = compute_class_weight('balanced', classes=np.unique(y_train_labels), y=y_train_labels)
8class_weight_dict = dict(zip(np.unique(y_train_labels), weights))
9print(class_weight_dict)
10# {0: 0.667, 1: 1.0, 2: 2.0}
11
12model.fit(X_train, y_train, class_weight=class_weight_dict, epochs=10)

sklearn.utils.class_weight.compute_class_weight('balanced') computes weights inversely proportional to class frequencies. The result is a NumPy array — you must convert it to a dict before passing to Keras.

Handling One-Hot Encoded Labels

python
1import numpy as np
2from sklearn.utils.class_weight import compute_class_weight
3
4# If y_train is one-hot encoded: [[1,0,0], [0,1,0], [0,0,1], ...]
5y_train_onehot = np.array([[1,0,0], [1,0,0], [0,1,0], [0,0,1]])
6
7# Convert to integer labels first
8y_labels = np.argmax(y_train_onehot, axis=1)
9# [0, 0, 1, 2]
10
11weights = compute_class_weight('balanced', classes=np.unique(y_labels), y=y_labels)
12class_weight_dict = dict(zip(np.unique(y_labels), weights))
13print(class_weight_dict)
14
15# Now pass the dict to model.fit
16model.fit(X_train, y_train_onehot, class_weight=class_weight_dict, epochs=10)

Using sample_weight as an Alternative

python
1import numpy as np
2
3# sample_weight assigns a weight to each individual sample
4# This is more flexible than class_weight for complex weighting schemes
5
6y_labels = np.array([0, 0, 0, 1, 1, 2])
7weight_map = {0: 1.0, 1: 2.5, 2: 3.0}
8
9# Create per-sample weights from class weights
10sample_weights = np.array([weight_map[label] for label in y_labels])
11print(sample_weights)  # [1.0, 1.0, 1.0, 2.5, 2.5, 3.0]
12
13# Pass as sample_weight instead of class_weight
14model.fit(X_train, y_train, sample_weight=sample_weights, epochs=10)

sample_weight is a NumPy array (not a dict) with one weight per training sample. It provides finer control than class_weight and avoids the dict format requirement.

Colab-Specific Version Issues

python
1# Check your TensorFlow/Keras version on Colab
2import tensorflow as tf
3print(tf.__version__)
4
5# Colab may have different default TF versions across sessions
6# Pin a specific version if needed:
7# !pip install tensorflow==2.15.0
8
9# Some older Keras versions (<2.4) accepted lists for class_weight
10# Newer versions strictly require a dict
11# Always use a dict for compatibility across versions

Common Pitfalls

  • Passing a NumPy array or list as class_weight: Keras requires a plain Python dict for class_weight. compute_class_weight() returns a NumPy array, which must be converted to a dict with dict(zip(classes, weights)) before passing to model.fit().
  • Forgetting to convert one-hot labels to integers: compute_class_weight expects integer labels, not one-hot encoded arrays. Use np.argmax(y_onehot, axis=1) to convert one-hot labels to integer class indices before computing weights.
  • Using string class names as dict keys: class_weight keys must be integers matching the class indices, not string labels. If your labels are strings, map them to integers first (e.g., using LabelEncoder).
  • Confusing class_weight with sample_weight: class_weight is a dict applied to all samples of a class. sample_weight is a per-sample array. They cannot be used interchangeably — class_weight expects a dict while sample_weight expects an array.
  • Colab runtime restarts changing TF version: Colab may update TensorFlow versions between sessions, changing how class_weight is validated. Pin your TensorFlow version with !pip install tensorflow==X.Y.Z at the start of your notebook to ensure consistent behavior.

Summary

  • class_weight must be a Python dict mapping integer class indices to float weights
  • Passing a NumPy array or list causes the "truth value of an array" ValueError
  • Use compute_class_weight('balanced', ...) from sklearn, then convert to a dict
  • Convert one-hot labels to integers with np.argmax() before computing weights
  • Use sample_weight (a per-sample array) as an alternative for more flexible weighting
  • Pin your TensorFlow version on Colab to avoid version-related behavior changes

Course illustration
Course illustration

All Rights Reserved.