TensorFlow
image processing
machine learning
dataset
data loading

Loading Images in a Directory As Tensorflow Data set

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

Introduction

Loading images from a directory into a TensorFlow dataset is a common first step in computer vision training pipelines. The modern, reliable approach is tf.keras.utils.image_dataset_from_directory, which handles label extraction, batching, and basic splitting. Performance and correctness still depend on resizing, normalization, class balance, and pipeline tuning.

This article shows a practical end-to-end setup with tf.data best practices for training-ready image datasets.

Core Sections

1. Directory structure and label inference

Typical layout:

text
1data/
2  train/
3    cats/
4    dogs/

Class names are inferred from subdirectory names.

2. Load datasets with utility API

python
1import tensorflow as tf
2
3train_ds = tf.keras.utils.image_dataset_from_directory(
4    "data/train",
5    image_size=(224, 224),
6    batch_size=32,
7    validation_split=0.2,
8    subset="training",
9    seed=42,
10)
11
12val_ds = tf.keras.utils.image_dataset_from_directory(
13    "data/train",
14    image_size=(224, 224),
15    batch_size=32,
16    validation_split=0.2,
17    subset="validation",
18    seed=42,
19)

Deterministic seed ensures stable split reproducibility.

3. Normalize and prefetch

python
1normalization = tf.keras.layers.Rescaling(1./255)
2train_ds = train_ds.map(lambda x, y: (normalization(x), y), num_parallel_calls=tf.data.AUTOTUNE)
3val_ds = val_ds.map(lambda x, y: (normalization(x), y), num_parallel_calls=tf.data.AUTOTUNE)
4
5train_ds = train_ds.prefetch(tf.data.AUTOTUNE)
6val_ds = val_ds.prefetch(tf.data.AUTOTUNE)

Prefetching overlaps input pipeline with model execution.

4. Optional augmentation pipeline

python
1data_aug = tf.keras.Sequential([
2    tf.keras.layers.RandomFlip("horizontal"),
3    tf.keras.layers.RandomRotation(0.1),
4])

Apply augmentation in training path only.

5. Handle class imbalance and inspection

python
class_names = train_ds.class_names
print(class_names)

For imbalance, consider class weights or resampling strategy.

6. Large dataset scaling

For very large datasets, consider TFRecord conversion and distributed input pipelines to reduce decode overhead and improve throughput.

text
directory loader is excellent for prototyping; TFRecord often scales better

Common Pitfalls

  • Relying on implicit class ordering without checking class_names.
  • Forgetting to normalize pixel values before training.
  • Applying augmentation to validation/test data.
  • Skipping prefetch and underutilizing GPU/CPU.
  • Assuming directory loader is optimal for very large-scale production training.

Summary

TensorFlow makes directory-based image loading easy with image_dataset_from_directory, but robust pipelines still require explicit normalization, reproducible splitting, and input-performance tuning. Start with the built-in utility for fast iteration, then evolve toward TFRecord and advanced data strategies when scale demands it.

For long-term maintainability, treat loading images in a directory as tensorflow data set as a contract problem as much as a code problem. Write down the assumptions that are currently implicit in helper methods, controller glue, and data adapters. Typical assumptions include input normalization rules, default values, acceptable error states, ordering guarantees, and version compatibility boundaries. Once these are explicit, convert them into fast executable checks. Keep one focused smoke test for the core path and one for each high-impact edge case observed in production logs. This style of regression coverage is usually more valuable than large numbers of shallow unit tests because it reflects real failure modes and protects the exact integration seams where breakages usually occur after upgrades.

Operationally, instrument the decision points, not just the final failures. Emit structured diagnostic fields for environment, dependency version, and branch outcome while redacting sensitive values. During incident review, add one permanent guard per root cause: either a targeted test, a validation rule at the boundary, or an alert on unexpected state transitions. Avoid scattering near-identical logic in multiple modules; centralize shared behavior and expose it through a small, documented API so call sites stay consistent. Before rolling out dependency updates, run a compatibility checklist that includes this topic’s smoke tests against representative fixtures. Teams that combine explicit contracts, narrow regression tests, and lightweight telemetry usually see lower incident recurrence and faster mean time to diagnosis.

Documenting one canonical example command or snippet in team docs alongside expected output also reduces future ambiguity, especially when debugging under time pressure. Adding a quick dataset-integrity job that verifies image decode success, class counts, and shape consistency before training can prevent expensive failures deep into long training runs.


Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

All Rights Reserved.