Keras
ValueError
TimeseriesGenerator
validation_split
error-handling

ValueError validation_split is only supported for Tensors or NumPy arrays, found keras.preprocessing.sequence.TimeseriesGenerator object

Master System Design with Codemia

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

Introduction

This Keras error appears when validation_split is used together with a generator such as TimeseriesGenerator. The split option only works when Keras can slice in-memory arrays itself; a generator yields batches dynamically, so Keras has no reliable way to carve out a validation subset from it.

Why validation_split Fails Here

With NumPy arrays or tensors, Keras can hold the full input in memory and split it by index. A generator is different. It is an iterator-like object that produces batches on demand, so there is no built-in "take the last 20 percent" operation.

That is why this fails:

python
model.fit(train_gen, epochs=10, validation_split=0.2)

train_gen is already a batch producer, not a raw array that Keras can slice internally.

The Correct Fix: Split the Raw Series First

For time-series work, split the original arrays yourself, then create separate generators for training and validation.

python
1import numpy as np
2from tensorflow.keras.preprocessing.sequence import TimeseriesGenerator
3
4series = np.arange(1000, dtype=np.float32)
5targets = series.copy()
6
7split = int(len(series) * 0.8)
8
9train_x, val_x = series[:split], series[split:]
10train_y, val_y = targets[:split], targets[split:]
11
12length = 20
13batch_size = 32
14
15train_gen = TimeseriesGenerator(train_x, train_y, length=length, batch_size=batch_size)
16val_gen = TimeseriesGenerator(val_x, val_y, length=length, batch_size=batch_size)
17
18model.fit(train_gen, validation_data=val_gen, epochs=5)

This is the standard solution. You do the split explicitly and pass validation data explicitly.

Preserve Time Order

For time-series forecasting, the split should usually be chronological. Randomly mixing past and future points between training and validation introduces leakage and makes the model look better than it really is.

A good default sequence is:

  1. Choose a time boundary.
  2. Train on the earlier segment.
  3. Validate on the later segment.
  4. Keep the same window length in both generators.

That keeps evaluation closer to the way the model will be used in production.

Check Generator Lengths

If the validation segment is too short relative to the sequence length, the validation generator may produce zero batches. Always inspect the generator sizes.

python
print("train steps:", len(train_gen))
print("validation steps:", len(val_gen))

If len(val_gen) is 0, your validation slice is not long enough to produce at least one full window.

A tf.data Alternative

If your project is already using tf.data, you can build explicit training and validation datasets there as well.

python
1import tensorflow as tf
2
3window = 20
4series = tf.range(0, 1000, dtype=tf.float32)
5
6def make_ds(values):
7    ds = tf.data.Dataset.from_tensor_slices(values)
8    ds = ds.window(window + 1, shift=1, drop_remainder=True)
9    ds = ds.flat_map(lambda w: w.batch(window + 1))
10    ds = ds.map(lambda w: (w[:-1], w[-1]))
11    return ds.batch(32).prefetch(tf.data.AUTOTUNE)
12
13split = 800
14train_ds = make_ds(series[:split])
15val_ds = make_ds(series[split:])
16
17model.fit(train_ds, validation_data=val_ds, epochs=5)

This avoids TimeseriesGenerator entirely and gives you more control over the input pipeline.

Why Explicit Validation Is Better Anyway

Even if validation_split did work on generators, explicit validation data is usually clearer. It makes the train-validation boundary visible in code and easier to audit.

That matters in time-series projects because:

  • chronology matters
  • leakage is easy to introduce
  • evaluation windows often need special handling

An explicit split also makes it easier to reuse the same validation set across experiments.

Common Pitfalls

The most common mistake is assuming validation_split works for every Keras input type. It does not; it is meant for arrays and tensors, not batch generators.

Another issue is creating the generator first and then trying to split conceptually afterward. The split should happen before generator construction.

Developers also randomize time-series splits out of habit from tabular ML workflows. That often leaks future information into training.

Finally, do not forget to check the length of the validation generator. A too-short validation segment can silently undermine your training setup.

Summary

  • 'validation_split works with tensors and NumPy arrays, not with TimeseriesGenerator.'
  • Split the raw time series first, then build separate training and validation generators.
  • Keep the split chronological to avoid leakage in forecasting tasks.
  • Verify that the validation generator produces enough batches to be meaningful.
  • Consider tf.data when you want more explicit and scalable sequence pipelines.

Course illustration
Course illustration

All Rights Reserved.