How can I use tf.data Datasets in eager execution mode?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
In TensorFlow 2.x, eager execution is enabled by default, which means operations run immediately and are easier to debug. The tf.data API still matters in eager mode because it gives you a high performance input pipeline for training and inference. You can iterate through datasets naturally in Python while keeping options like parallel mapping, caching, prefetching, and batching. The key idea is that tf.data controls how data moves and transforms, while eager execution controls when ops are evaluated. This article shows practical dataset patterns that work well in eager mode and explains how to avoid the most common pipeline mistakes.
Core Sections
Build datasets directly from tensors and files
Start with simple constructors and keep transformations incremental. For in-memory arrays, use from_tensor_slices.
This loop runs eagerly, so printing and debugging are straightforward.
For file based data, use TextLineDataset, TFRecordDataset, or list_files with interleave when you need parallel reads.
Use map for preprocessing and keep it pure
A good map function should take tensors and return tensors without side effects. Keep random augmentation explicit and use TensorFlow ops when possible.
Even in eager mode, this pipeline can be compiled and optimized internally.
Integrate with Keras training
model.fit accepts datasets directly. Make sure your dataset yields (features, labels) tuples with shapes the model expects.
If your dataset is infinite due to repeat(), pass steps_per_epoch so training knows when each epoch ends.
Debug and inspect in eager mode
Because execution is immediate, you can inspect samples at any point:
Use .take(n) generously while building pipelines. It is faster than running full epochs to discover input shape issues.
Common Pitfalls
- Applying
repeat()beforeshuffle()with a tiny buffer, which can reduce data randomness across epochs. - Returning Python objects from
mapinstead of tensors, causing shape/type errors later in training. - Forgetting to batch the dataset before
model.fit, which can make training very slow and memory inefficient. - Using blocking Python logic inside
map, preventing parallelism and reducing pipeline throughput. - Omitting
prefetch, which leaves GPU or TPU resources waiting for input data.
Production Readiness Check
Before closing the task, run a short validation loop on representative inputs and one intentional failure case. Confirm that your code path behaves correctly for normal data, empty data, and malformed data. Capture at least one measurable signal such as runtime, memory use, or error rate, then compare it to your baseline so regressions are visible. Keep this check lightweight so it can run in local development and CI without slowing feedback too much. A simple checklist plus one executable smoke test prevents most regressions after refactors and library upgrades.
Summary
tf.data works very well with eager execution and should be your default input pipeline layer in TensorFlow 2.x. Build datasets from tensors or files, keep preprocessing functions tensor-native, and compose shuffle, batch, cache, and prefetch in a clear order. Eager mode makes debugging easier, while tf.data preserves performance at scale. If you validate shapes early and monitor throughput, you can get both developer productivity and strong training performance from the same pipeline.

