Python
TensorFlow
Error Handling
Machine Learning
Debugging

ValueError Shapes None, 1 and None, 3 are incompatible

Master System Design with Codemia

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

Introduction

The error ValueError: Shapes (None, 1) and (None, 3) are incompatible usually means your model output shape does not match the shape expected by the labels or the loss function. In Keras and TensorFlow, this almost always comes down to one of three mismatches: wrong output layer size, wrong label encoding, or wrong loss for the chosen encoding.

Read the Shapes Literally

A shape of (None, 1) means “one value per example,” with None representing the batch dimension. A shape of (None, 3) means “three values per example.”

So if your model predicts one value per example but the labels have three values per example, or the reverse, TensorFlow cannot align them for the loss computation.

That is why this error often appears at training time rather than model construction time.

A Common Cause: Wrong Output Layer for the Problem

Suppose you have a three-class classification problem. The final layer should usually output three logits or probabilities, not one.

Wrong for three classes:

python
1model = tf.keras.Sequential([
2    tf.keras.layers.Dense(32, activation="relu"),
3    tf.keras.layers.Dense(1, activation="sigmoid"),
4])

Better for three classes:

python
1model = tf.keras.Sequential([
2    tf.keras.layers.Dense(32, activation="relu"),
3    tf.keras.layers.Dense(3, activation="softmax"),
4])

If the labels are one-hot encoded with shape (batch, 3), the model output must also have three values per example.

Another Common Cause: Wrong Label Encoding

For multi-class classification, there are two common label styles:

  • integer class ids such as 0, 1, 2
  • one-hot vectors such as [1, 0, 0]

Those two styles require different loss functions.

One-hot labels with categorical crossentropy:

python
1import tensorflow as tf
2import numpy as np
3
4x = np.random.rand(8, 4).astype("float32")
5y = tf.keras.utils.to_categorical([0, 1, 2, 1, 0, 2, 1, 0], num_classes=3)
6
7model = tf.keras.Sequential([
8    tf.keras.layers.Input(shape=(4,)),
9    tf.keras.layers.Dense(16, activation="relu"),
10    tf.keras.layers.Dense(3, activation="softmax"),
11])
12
13model.compile(
14    optimizer="adam",
15    loss="categorical_crossentropy",
16)

Integer labels with sparse categorical crossentropy:

python
1y = np.array([0, 1, 2, 1, 0, 2, 1, 0], dtype="int32")
2
3model.compile(
4    optimizer="adam",
5    loss="sparse_categorical_crossentropy",
6)

If you mix these pairings incorrectly, shape mismatches are likely.

Binary Classification Is Different

For binary classification, the output is often shape (None, 1) with a sigmoid activation, and the labels are usually shape (None,) or (None, 1).

python
1model = tf.keras.Sequential([
2    tf.keras.layers.Input(shape=(4,)),
3    tf.keras.layers.Dense(16, activation="relu"),
4    tf.keras.layers.Dense(1, activation="sigmoid"),
5])
6
7model.compile(
8    optimizer="adam",
9    loss="binary_crossentropy",
10)

This is appropriate for yes and no problems, not for three-class classification.

Debug by Printing Shapes Early

A fast debugging step is to inspect the shape of the model output and the labels before calling fit.

python
print(model.output_shape)
print(x.shape)
print(y.shape)

If the output says (None, 1) and the labels say (batch, 3), the mismatch is already visible before the training loop starts.

Match the Whole Stack

A reliable classification setup needs these pieces to agree:

  • number of output units
  • activation choice
  • label encoding
  • loss function

For example:

  • binary classification: Dense(1, sigmoid) plus binary labels plus binary_crossentropy
  • multi-class with one-hot labels: Dense(num_classes, softmax) plus one-hot labels plus categorical_crossentropy
  • multi-class with integer labels: Dense(num_classes, softmax) plus integer labels plus sparse_categorical_crossentropy

Most shape errors are just one broken link in that chain.

Common Pitfalls

  • Using a one-unit sigmoid output for a multi-class classification problem.
  • Feeding one-hot labels into sparse_categorical_crossentropy.
  • Feeding integer class ids into categorical_crossentropy without one-hot encoding.
  • Looking only at the error message and not printing model and label shapes directly.
  • Fixing the output layer but forgetting to update the corresponding loss function.

Summary

  • This shape error usually means the model output, label encoding, and loss function do not agree.
  • '(None, 1) is often a binary output, while (None, 3) usually means three classes.'
  • For multi-class problems, use an output width equal to the number of classes.
  • Match one-hot labels with categorical_crossentropy and integer labels with sparse_categorical_crossentropy.
  • Print shapes early to find the mismatch before guessing.

Course illustration
Course illustration

All Rights Reserved.