TensorFlow
NumPy
Python Programming
Data reshaping
Machine Learning Errors

expected ndim3, found ndim2

Master System Design with Codemia

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

Introduction

The error expected ndim=3, found ndim=2 means a layer was built to consume three-dimensional input, but the data you passed has only two axes. In Keras and TensorFlow this usually appears with sequence layers such as LSTM or Conv1D, where the model expects data shaped like batch, timesteps, features.

Why the model expects three dimensions

Different layer types expect different input ranks:

  • dense layers usually accept batch, features
  • recurrent layers usually accept batch, timesteps, features
  • 'Conv1D also expects three axes'

So if you define:

python
1from tensorflow import keras
2
3model = keras.Sequential([
4    keras.layers.LSTM(32, input_shape=(10, 4)),
5    keras.layers.Dense(1),
6])

the layer expects one batch of samples where each sample contains 10 time steps and 4 features per step. A single sample therefore needs shape 10, 4, and a training batch needs shape batch_size, 10, 4.

If you pass a plain 2D matrix like 100, 4, Keras cannot guess whether 100 means rows, timesteps, or samples. That ambiguity is why it raises the rank error.

Fix the input shape, not just the error message

The correct fix depends on what the data represents.

If the data is sequence data and you accidentally flattened it, reshape it back into three dimensions:

python
1import numpy as np
2
3x = np.random.rand(32, 10, 4).astype("float32")
4y = np.random.rand(32, 1).astype("float32")
5
6model.fit(x, y, epochs=1)

If you currently have shape 32, 40 because each sample was flattened from 10 x 4, you can restore the intended structure:

python
x = x.reshape(32, 10, 4)

But only do that if the original semantics really are 10 time steps with 4 features. Reshaping arbitrary data just to satisfy a layer is a common mistake.

Single-feature sequences still need three axes

Many people hit this error with a single feature per time step. They expect a 2D array to be enough because there is only one feature column. It is not.

For example, an LSTM over one sensor value per time step still expects:

  • 'batch'
  • 'timesteps'
  • 'features'

So 100 samples of 20 time steps with one feature should be shaped like:

python
x = np.random.rand(100, 20, 1).astype("float32")

not:

python
x = np.random.rand(100, 20).astype("float32")

That extra trailing dimension matters even when its size is 1.

Build a minimal correct example

Here is a complete working example:

python
1import numpy as np
2from tensorflow import keras
3
4x = np.random.rand(64, 15, 3).astype("float32")
5y = np.random.rand(64, 1).astype("float32")
6
7model = keras.Sequential([
8    keras.layers.Input(shape=(15, 3)),
9    keras.layers.LSTM(16),
10    keras.layers.Dense(1),
11])
12
13model.compile(optimizer="adam", loss="mse")
14model.fit(x, y, epochs=1, batch_size=8)

If you replace x with a 2D array such as 64, 45, you will see the rank mismatch immediately.

Check the data pipeline early

Before calling fit, print the array shape:

python
print(x.shape)

That one line often saves time because the problem is usually visible right away. In tf.data pipelines, inspect the element spec too:

python
print(dataset.element_spec)

If the dataset produces 2D tensors while the model expects 3D tensors, the mismatch is in preprocessing, batching, or sequence construction.

Common Pitfalls

The biggest mistake is reshaping data blindly until the error disappears. A tensor with the right rank but the wrong semantic layout will train badly even if the model compiles.

Another common mistake is forgetting the feature dimension when there is only one feature per time step. A single feature still requires a third axis of size 1.

Developers also confuse the batch dimension with the sequence dimension. The batch axis is added by training; it is not the same thing as the number of time steps.

Finally, if your data is truly tabular rather than sequential, the right fix may be to use a dense model instead of forcing the data into a sequence layer.

Summary

  • 'expected ndim=3, found ndim=2 means the model expects three axes and your input only has two.'
  • Sequence layers usually want batch, timesteps, features.
  • Add the missing feature or timestep axis only if it matches the real data meaning.
  • Print shapes before training so the mismatch is obvious early.
  • If the data is not sequential, reconsider the model architecture rather than just reshaping.

Course illustration
Course illustration

All Rights Reserved.