Keras
fit_generator
Python
AttributeError
deep learning

keras fit_generator 'zip' object has no attribute 'shape'

Master System Design with Codemia

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

Introduction

The error 'zip' object has no attribute 'shape' usually means Keras received a Python zip iterator where it expected an array-like batch or a generator that yields batch tuples. The real problem is not the missing shape attribute itself. It is that the data pipeline is handing Keras the wrong object type. Once you align the generator output with what Keras expects, the error disappears.

What Keras Expects

Legacy fit_generator and modern model.fit both expect batch-oriented data. That normally means one of these patterns:

  • NumPy arrays directly
  • a generator that yields (x_batch, y_batch)
  • a keras.utils.Sequence
  • a tf.data.Dataset

A raw zip(...) object is just a Python iterator that pairs elements together. It is not a batch tensor, and it does not expose array metadata such as .shape.

Why zip Causes the Error

This is the kind of misuse that triggers the problem.

python
1x = [[1, 2], [3, 4]]
2y = [0, 1]
3train_data = zip(x, y)
4
5# Wrong idea for Keras training
6# model.fit_generator(train_data, ...)

Each iteration from zip yields one pair, not a proper batch object that Keras can inspect and manage in the way it expects. Older code paths often end up calling logic that assumes array-like inputs and tries to read .shape.

Fix 1: Yield Proper Batches From a Generator

If you want generator-based training, write a generator that yields full batches of features and labels.

python
1import numpy as np
2
3
4def batch_generator(x, y, batch_size):
5    x = np.asarray(x)
6    y = np.asarray(y)
7
8    while True:
9        for start in range(0, len(x), batch_size):
10            end = start + batch_size
11            yield x[start:end], y[start:end]
12
13x = np.array([[1, 2], [3, 4], [5, 6], [7, 8]], dtype="float32")
14y = np.array([0, 1, 0, 1], dtype="float32")

That generator yields exactly the structure Keras expects.

Fix 2: Use model.fit Instead of fit_generator

In current Keras and TensorFlow usage, fit_generator is legacy API. The preferred entry point is simply model.fit, which already accepts generators and datasets.

python
1import tensorflow as tf
2import numpy as np
3
4model = tf.keras.Sequential([
5    tf.keras.layers.Input(shape=(2,)),
6    tf.keras.layers.Dense(4, activation="relu"),
7    tf.keras.layers.Dense(1, activation="sigmoid"),
8])
9model.compile(optimizer="adam", loss="binary_crossentropy")
10
11x = np.array([[1, 2], [3, 4], [5, 6], [7, 8]], dtype="float32")
12y = np.array([0, 1, 0, 1], dtype="float32")
13
14model.fit(batch_generator(x, y, batch_size=2), steps_per_epoch=2, epochs=3)

The important part is not the method name. It is that the generator yields valid batch tensors.

Fix 3: Use tf.data.Dataset When the Pipeline Grows

If the data pipeline is becoming more complex, tf.data.Dataset is often the cleaner answer.

python
1import tensorflow as tf
2import numpy as np
3
4x = np.array([[1, 2], [3, 4], [5, 6], [7, 8]], dtype="float32")
5y = np.array([0, 1, 0, 1], dtype="float32")
6
7ds = tf.data.Dataset.from_tensor_slices((x, y)).batch(2)
8model.fit(ds, epochs=3)

This avoids the accidental iterator-shape problems that arise when general Python iterators are pressed into service as training inputs.

If You Really Need to Combine Iterables

If you started with zip because you had separate feature and label iterables, convert them into arrays or into a proper batch-producing generator before handing them to Keras. The fix is not “make zip look like it has a shape.” The fix is “stop using zip as though it were a batch container.”

That distinction matters because patching around the error without fixing the data contract usually creates another error later in training.

Common Pitfalls

  • Passing a raw zip iterator to Keras instead of a generator that yields full batches.
  • Thinking the problem is only the missing .shape attribute rather than the overall input contract.
  • Continuing to use fit_generator style examples without recognizing that modern Keras code should generally use model.fit.
  • Yielding single examples instead of batched arrays from a generator when the training loop expects batches.
  • Using ad hoc Python iterators where tf.data.Dataset or keras.utils.Sequence would make the data interface clearer.

Summary

  • The error happens because Keras received a zip iterator instead of array-like batch data.
  • Keras training expects batches such as (x_batch, y_batch).
  • Write a proper generator, use model.fit, or switch to tf.data.Dataset.
  • Do not try to “fix” zip itself; fix the shape and batching contract of the input pipeline.
  • Modern Keras training code is usually simpler and safer when the data source is explicit about batch structure.

Course illustration
Course illustration

All Rights Reserved.