Halloween DealsAmazon USHalloween week deals: useful picks before month-endAmazon US: current deals, useful picks and tech finds.Check DealsPC HealthRecommendedCrashes, freezes, slowdowns? Check your PC nowSpot repairable issues before they interrupt work.Check PCHalloween DealsAmazon USOctober picks are moving - compare before checkoutAmazon US: current deals, useful picks and tech finds.See Picks×
FREEDOM251

Freedom251 › Blog

How to Load Large Datasets From Directories for Deep Learning in Keras

By Freedom251 Team · · 18 min read

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Large datasets rarely fit comfortably in memory, especially when training deep learning models on high-resolution images, long text files, or millions of samples. Keras supports directory-based loading and streaming input pipelines so data can be read in batches from disk, transformed as needed, and fed to a model without loading everything at once.

A well-designed loading workflow starts with a predictable directory structure, consistent labels, and file formats that can be decoded efficiently. From there, Keras utilities such as image dataset loaders and TensorFlow tf.data pipelines make it possible to batch, shuffle, preprocess, augment, cache, and prefetch data for scalable training.

As an Amazon Associate I earn from qualifying purchases.

Using these tools correctly helps avoid common bottlenecks such as slow disk reads, memory spikes, label mismatches, repeated preprocessing work, and validation leakage. The goal is to keep the GPU or accelerator busy while maintaining a clean, reproducible data pipeline that works from experimentation through production-scale training.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Organizing Large Datasets in Directory Structures

A scalable Keras input pipeline starts with a predictable directory layout. For supervised image classification, the most common structure is one subdirectory per class, with files stored inside the matching class folder. Utilities such as keras.utils.image_dataset_from_directory and the older ImageDataGenerator.flow_from_directory infer labels directly from these folder names, so the directory tree becomes part of the training configuration.

A typical image dataset might use separate top-level folders for training, validation, and testing:

  • data/train/cats/ and data/train/dogs/ for training images
  • data/validation/cats/ and data/validation/dogs/ for validation images
  • data/test/cats/ and data/test/dogs/ for final evaluation images

This layout is simple, portable, and easy to inspect. It also avoids loading filenames, images, and labels into memory all at once. Keras scans the directory, builds a file index, and loads only the files needed for each batch during training. For large datasets, keep the directory hierarchy shallow and consistent. Millions of tiny nested folders can slow down file discovery, especially on network storage or cloud-mounted drives.

For text datasets, the same principle applies, but the unit of data may be one file per document, one subdirectory per category, or a manifest file that maps paths to labels. A sentiment dataset, for example, can be organized as text/train/positive/ and text/train/negative/. If each sample is stored as a separate .txt file, Keras and tf.data can stream file contents lazily. For very large corpora, it is often better to keep raw files in directories and maintain a separate CSV, JSONL, or Parquet index containing paths, labels, language, source, split, and other metadata.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use stable and machine-readable names for folders and files. Avoid changing class folder names between runs because class indices are assigned from directory names, often in sorted order unless explicitly provided. If cats is index 0 today and dogs is index 1, a renamed or newly inserted folder can alter that mapping and make old checkpoints, metrics, or saved predictions harder to interpret. When reproducibility matters, store the class-name list alongside the model artifacts.

Large datasets also benefit from a clear split strategy. Prefer creating fixed train, validation, and test directories before training, especially when mulle experiments must use the same split. Keras can create a validation split from one directory, but a persistent split on disk reduces accidental leakage and makes experiments easier to reproduce. For user-generated, medical, time-series, or document datasets, split by entity rather than by file when related samples could otherwise appear in both training and validation sets.

Before loading at scale, clean the directory tree. Remove corrupt images, unsupported formats, empty files, duplicate samples, hidden system files, and mislabeled examples where possible. Keep file extensions consistent, such as .jpg, .png, or .txt, and watch for case sensitivity differences between operating systems. A well-organized dataset reduces input pipeline errors, improves training reproducibility, and lets Keras stream batches efficiently without exhausting RAM.

Loading Images with Keras Directory-Based Utilities

Keras provides directory-aware loaders that let you train on large image collections without reading every file into memory at once. The most common modern option is tf.keras.utils.image_dataset_from_directory, which scans a folder tree, builds labels from subdirectory names, and returns a tf.data.Dataset that yields batches on demand. This is usually the best starting point for large image datasets because it integrates cleanly with TensorFlow input pipelines, preprocessing layers, distribution strategies, and model.fit().

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

For a typical classification dataset, the directory should contain one subfolder per class, such as train/cats, train/dogs, and train/birds. The loader assigns labels according to the sorted class folder names unless you provide class_names explicitly. A minimal call usually specifies the root directory, target image size, batch size, label mode, and shuffle behavior. For example, you might load RGB images resized to 224x224 in batches of 32 with integer labels for sparse categorical cross-entropy.

Rank #2
Sale
Hands-On Machine Learning with Scikit-Learn, Keras, and TensorFlow: Concepts, Tools, and Techniques to Build Intelligent Systems
  • Use scikit-learn to track an example ML project end to end
  • Explore several models, including support vector machines, decision trees, random forests, and ensemble methods
  • Exploit unsupervised learning techniques such as dimensionality reduction, clustering, and anomaly detection
  • Dive into neural net architectures, including convolutional nets, recurrent nets, generative adversarial networks, autoencoders, diffusion models, and transformers
  • Use TensorFlow and Keras to build and train neural nets for computer vision, natural language processing, generative models, and deep reinforcement learning

train_ds = tf.keras.utils.image_dataset_from_directory(
"data/train",
image_size=(224, 224),
batch_size=32,
label_mode="int",
shuffle=True,
seed=123
)

The returned dataset yields tensors shaped like (batch, height, width, channels) and labels shaped according to label_mode. Use "int" for sparse labels, "categorical" for one-hot labels, "binary" for two-class problems, and None when loading unlabeled images for inference, autoencoders, or custom labeling workflows. You can inspect the detected classes through train_ds.class_names before adding transformations to the dataset.

Choosing the right loader settings

  • image_size: resizes images during loading, which keeps batch tensor shapes consistent for the model.
  • batch_size: controls memory pressure; reduce it if the GPU or host RAM runs out of memory.
  • color_mode: use "rgb", "rgba", or "grayscale" depending on the model input.
  • label_mode: match this to the loss function used during training.
  • shuffle and seed: shuffle training data reproducibly while keeping validation or test loading deterministic.

Older Keras projects may use ImageDataGenerator.flow_from_directory. It still works and can be useful in legacy code, especially for simple rescaling and augmentation, but it produces a Python iterator rather than a fully optimized tf.data pipeline. For new TensorFlow/Keras projects, image_dataset_from_directory is generally easier to optimize with cache(), prefetch(), parallel mapping, and preprocessing layers.

Utility Best use Output
image_dataset_from_directory Modern Keras training at scale tf.data.Dataset
ImageDataGenerator.flow_from_directory Legacy pipelines and simple generator-based workflows Directory iterator

Directory-based utilities are convenient, but they do not remove the need to validate the dataset. Corrupt images, mixed file extensions, unexpected grayscale files, hidden system files, and mismatched class folders can interrupt training or silently skew labels. Before a long run, load a few batches, print class names, check tensor shapes, and visualize sample images with their labels. This small verification step catches most directory and labeling problems before they become expensive training failures.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Building Efficient tf.data Pipelines from Files

For very large datasets, a tf.data pipeline gives you more control than high-level directory loaders while still avoiding the need to load everything into RAM. Instead of materializing images, text, or labels as large NumPy arrays, the pipeline keeps file paths in a dataset, reads each file only when needed, decodes it, preprocesses it, batches it, and streams batches to the model. This approach is especially useful when you need custom parsing, mixed file formats, multi-label targets, paired inputs, or metadata stored outside the directory tree.

A typical file-based pipeline starts by listing paths with tf.data.Dataset.list_files() or by creating a dataset from an explicit Python list of paths using tf.data.Dataset.from_tensor_slices(). For classification datasets, labels can come from parent directory names, a CSV manifest, or a lookup table. The mapping step then reads the file with TensorFlow operations such as tf.io.read_file(), decodes the content, and returns a pair like (features, label). Keeping this work inside TensorFlow operations allows the input pipeline to run efficiently and be optimized by the runtime.

Common image pipeline pattern

For image training, the mapping function usually reads the file, decodes JPEG or PNG bytes, converts the image to a consistent dtype, resizes it, and attaches the label. A practical pipeline also sets a fixed number of channels, such as RGB, so that batches have predictable shapes. If images vary widely in dimensions, resizing during the pipeline prevents shape errors at batching time and keeps the model input consistent.

  • List files: collect matching paths such as train/*/*.jpg or use a manifest when labels are not encoded in folders.
  • Parse labels: derive class IDs from directory names or map string labels from a table to integers.
  • Read and decode: use TensorFlow file and image decoding ops rather than Python image libraries inside the hot path.
  • Normalize shapes: resize, crop, pad, or standardize sequence length before batching.
  • Return tensors: output tensors in the exact structure expected by model.fit().

Text datasets can follow the same pattern. Each path can point to a document, review, article, or transcript. The pipeline reads the file as a string tensor, pairs it with a label, and then applies a text preprocessing layer such as TextVectorization. For large corpora, it is often better to adapt the vectorizer on a representative training dataset, save the vocabulary, and reuse it for training and evaluation so that token indexes remain stable.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Using parallelism without losing control

The map() step is where many pipelines become slow if files are decoded one at a time. Passing num_parallel_calls=tf.data.AUTOTUNE lets TensorFlow process mulle files concurrently and tune the level of parallelism for the machine. This is valuable when training on a GPU or TPU, where the accelerator can sit idle if CPU decoding and disk reads are too slow. Pairing parallel mapping with batching and prefetching creates a producer-consumer flow: the input pipeline prepares future batches while the model trains on the current one.

For datasets that do not fit comfortably in memory, avoid caching the entire decoded dataset unless you have enough RAM or use a disk cache intentionally. Caching file paths is cheap; caching decoded and resized images can be expensive. Also be careful with Python functions inside map(), because they may prevent graph optimizations and make distributed training harder. Prefer TensorFlow-native operations for reading, parsing, decoding, resizing, tokenizing, and label conversion whenever possible.

A well-built tf.data pipeline separates concerns cleanly: file discovery, label construction, parsing, preprocessing, batching, and performance tuning. This makes it easier to inspect individual stages, reproduce label mappings, handle corrupted or unusual files, and scale from a small development subset to millions of files without changing the model training loop.

Batching, Shuffling, Caching, and Prefetching

Once files are being streamed from disk, the next step is to make the input pipeline deliver batches quickly and consistently enough to keep the GPU or accelerator busy. In Keras, datasets returned by utilities such as image_dataset_from_directory() are already batched when you pass batch_size, while custom tf.data.Dataset pipelines usually need an explicit .batch(batch_size). For large datasets, batching is essential because it amortizes file I/O, decoding, preprocessing, and device transfer over many samples instead of handling one item at a time.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Batch size should be chosen based on model size, image or sequence dimensions, available memory, and training stability. A larger batch can improve throughput, but it may exceed GPU memory or reduce the beneficial noise in gradient updates. A smaller batch uses less memory and can work better for variable-length text or high-resolution images, but it may leave hardware underutilized. If the final partial batch causes shape issues, especially with distributed training or models expecting fixed batch shapes, use drop_remainder=True when batching a custom dataset.

Shuffling large datasets effectively

Shuffling prevents the model from seeing samples in a predictable directory or filename order, which is especially relevant when files are grouped by class, date, source, or subject. With Keras directory loaders, set shuffle=True for training data. With tf.data, apply .shuffle(buffer_size) before batching in most training pipelines. The buffer_size controls how many examples are held in memory for randomization: a larger buffer gives better mixing but uses more RAM. For millions of files, shuffling the entire dataset in memory is usually unnecessary; a buffer of a few thousand to tens of thousands examples is often a practical compromise.

  • Training: shuffle file paths or decoded examples, repeat as needed, then batch.
  • Validation and test: avoid shuffling if you need reproducible evaluation, stable predictions, or filename-to-output mapping.
  • Class-balanced data: directory order alone is not enough; consider stratified splits or sampling if classes are highly imbalanced.

Caching decoded and preprocessed data

Caching can reduce repeated disk reads and decoding work across epochs, but it must be used carefully with large datasets. Calling .cache() without a filename stores elements in memory, which is only safe when the decoded and preprocessed dataset fits comfortably in RAM. For datasets that are too large, use .cache("/path/to/cache") to cache to local SSD storage, or skip caching and rely on parallel reads and prefetching. Avoid caching after random augmentation if you expect new augmented variants each epoch; cache before augmentation so deterministic steps such as loading, decoding, resizing, and normalization are reused while random transformations remain fresh.

A common efficient order for image training is: list files, shuffle file paths, decode and resize in parallel, cache if appropriate, apply random augmentation, batch, then prefetch. For text, tokenize or vectorize as part of the pipeline when possible, cache only if the tokenized representation is not too large, and use padded batching for variable-length sequences. If preprocessing uses a Keras layer such as TextVectorization or image normalization, place it consistently either inside the model or in the dataset pipeline so training and inference do not silently diverge.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Prefetching and parallelism

Prefetching overlaps input preparation on the CPU with model execution on the GPU. In most cases, add .prefetch(tf.data.AUTOTUNE) as the final step in the pipeline. AUTOTUNE lets TensorFlow adjust the prefetch buffer and parallelism dynamically. For custom loaders, also use parallel mapping with .map(parse_fn, num_parallel_calls=tf.data.AUTOTUNE) so mulle files can be read, decoded, and transformed at the same time. When reading from slow network storage, local SSD staging, larger read buffers, or converting many small files into larger container formats may provide a major speedup.

The most common performance pitfalls are batching too late, shuffling with an enormous buffer that consumes memory, caching a dataset that does not fit in RAM, and placing expensive Python code inside the input path. Prefer TensorFlow operations inside .map(), monitor GPU utilization during training, and adjust batch size, shuffle buffer, cache location, and prefetch settings based on measured throughput rather than assumptions.

Applying Preprocessing and Data Augmentation During Loading

Preprocessing should happen as close to the input pipeline as possible so large datasets are decoded, resized, normalized, and batched without first being loaded fully into memory. For image directories loaded with tf.keras.utils.image_dataset_from_directory, common options such as image_size, color_mode, batch_size, label_mode, and crop_to_aspect_ratio handle much of the basic preparation during dataset construction. This keeps the model interface consistent: every batch has the same height, width, channel count, label format, and tensor dtype.

Pixel scaling can be applied either inside the model or in the tf.data pipeline. A model-side approach using layers such as Rescaling, Normalization, and augmentation layers is often convenient because preprocessing becomes part of the saved model. A pipeline-side approach using Dataset.map() is useful when preprocessing is dataset-specific, when inputs come from custom file readers, or when the same model should receive already-standardized tensors from mulle sources. For example, image tensors can be converted from integer values in the 0-255 range to floating-point values in the 0-1 range before training.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Image preprocessing and augmentation

For images, preprocessing usually includes resizing, channel handling, value scaling, and sometimes normalization with dataset-specific mean and variance. Data augmentation adds randomized transformations that improve generalization, especially when classes are visually diverse or the dataset is not large enough to cover all expected variations. Keras preprocessing layers are designed to work with batches and can be placed at the start of a model or called inside a mapped dataset transformation.

  • Resizing: standardize all images to the input size expected by the model, such as 224×224 or 256×256.
  • Rescaling: convert pixel values from [0, 255] to [0, 1] or to the range expected by a pretrained backbone.
  • Normalization: adapt a Normalization layer on the training data only, then reuse it for validation and testing.
  • Augmentation: use random flips, rotations, zooms, translations, contrast changes, and cropping where those transformations preserve the label.

Augmentation should normally be applied only to the training dataset. Validation and test datasets should receive deterministic preprocessing so evaluation metrics reflect model performance on stable inputs. For instance, random horizontal flips may be appropriate for animal or product images, but they can be harmful for text screenshots, medical scans, traffic signs, or any task where orientation and asymmetry carry meaning. Random brightness and contrast changes can help with natural photos, but may distort images where intensity is part of the label signal.

Text preprocessing from directories

For text datasets organized by class directories, tf.keras.utils.text_dataset_from_directory can stream files into batches of strings and labels. The typical next step is a TextVectorization layer, which handles lowercasing, tokenization, vocabulary lookup, sequence truncation, and padding. The layer should be adapted on the training text only, then reused unchanged for validation and test splits. This avoids leaking validation vocabulary statistics into training and keeps evaluation realistic.

As with image preprocessing, text vectorization can live inside the model or in the pipeline. Keeping it inside the model is useful when exporting a model that accepts raw strings. Mapping vectorization in the dataset can improve visibility into tensor shapes and may be preferred when training mulle models from the same prepared input. For very large corpora, use a bounded vocabulary size and fixed output sequence length to control memory use and keep batch shapes efficient.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Task Recommended placement Common pitfall
Image rescaling Model layer or map() Applying different scaling to training and validation data
Image augmentation Training pipeline or model layers active during training Augmenting validation and test batches
Text vectorization TextVectorization layer Adapting vocabulary on all splits instead of training only
Pretrained model preparation Backbone-specific preprocessing function or layer Using generic 0-1 scaling when the backbone expects another format

When using Dataset.map(), set num_parallel_calls=tf.data.AUTOTUNE for CPU-bound decoding and preprocessing, then place prefetch(tf.data.AUTOTUNE) after mapping so the input pipeline prepares the next batch while the model trains on the current one. Avoid expensive Python-side operations inside mapped functions, since they can serialize execution and reduce throughput. Prefer TensorFlow operations and Keras layers, which integrate better with graph execution, distribution strategies, and accelerator-backed training.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Handling Validation Splits, Class Labels, and Edge Cases

Validation handling should be decided before training starts, because changing the split after model selection can make reported metrics unreliable. With image datasets arranged as one subdirectory per class, keras.utils.image_dataset_from_directory can create training and validation datasets using validation_split, subset, and a fixed seed. The same seed and split value must be used for both subsets so that Keras partitions the file list consistently. For very large datasets, many teams prefer explicit train/, val/, and test/ folders because the split is visible, reproducible across machines, and less likely to change when new files are added.

Class labels deserve the same care as the files themselves. Keras infers class names from subdirectory names in alphanumeric order unless class_names is supplied. That means folders such as cat, dog, and zebra will map to integer labels in that sorted order. Save this mapping with the trained model artifacts, especially when exporting to a serving system or comparing experiments. If labels come from a CSV file rather than directory names, build a lookup table once, keep it stable, and avoid generating label IDs independently in training and evaluation scripts.

Common edge cases in directory-based loading

  • Hidden and temporary files: files such as .DS_Store, thumbnails, partially copied images, and editor backups can break decoding or silently alter file counts. Clean directories before indexing them.
  • Class imbalance: large datasets often contain dominant classes. Use class weights, balanced sampling, oversampling, or stratified splits instead of relying on a random split that may underrepresent rare classes.
  • Corrupt or unsupported files: validate files before long training runs, or add defensive decoding in a custom tf.data pipeline so a single bad image does not stop an overnight job.
  • Duplicate samples: near-duplicate images or repeated text files can leak between training and validation sets. Split by source entity, user, patient, document group, or capture session when samples are related.
  • Uneven image sizes and channels: enforce a target size and color mode during loading. Mixing grayscale, RGB, and RGBA files without normalization can produce shape mismatches.

Text datasets have similar concerns, but the directory layout is often combined with file parsing. A sentiment dataset might use train/positive/ and train/negative/, while a document classification corpus may store one text file per example with the label encoded in the path. When using tf.data.Dataset.list_files, keep shuffling deterministic for validation data and avoid applying random augmentations or random cropping-style transformations to evaluation inputs. Tokenization and vocabulary adaptation should be fit only on the training split, then reused unchanged for validation and test data.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

For production-scale training, treat the validation set as a fixed contract. Do not cache a validation dataset after applying random transformations, do not use repeat() on validation without setting explicit evaluation steps, and do not let newly added classes appear only in validation. If the dataset is updated regularly, version the file manifest or store a snapshot of paths used for each experiment. This makes metrics comparable, prevents accidental label drift, and keeps large Keras input pipelines predictable even as the underlying directory tree grows.

Frequently Asked Questions

Should I use image_dataset_from_directory or ImageDataGenerator for large image datasets?

For most new Keras projects, use tf.keras.utils.image_dataset_from_directory because it returns a tf.data.Dataset that works well with caching, prefetching, distribution strategies, and modern preprocessing layers. ImageDataGenerator is still found in older tutorials, but it is less flexible for high-performance pipelines. If your dataset is very large, keep images on disk, load them in batches, and add prefetch(tf.data.AUTOTUNE).

How should my folders be organized so Keras can infer class labels correctly?

For classification, place one subdirectory per class under a root folder, such as train/cat, train/dog, val/cat, and val/dog. Keras assigns labels based on subdirectory names, usually in alphanumeric order unless you pass an explicit class_names list. Keep class names stable between training and validation folders to avoid mismatched labels.

Can I train on millions of files without loading the full dataset into RAM?

Yes. Directory-based Keras loaders and tf.data pipelines read files lazily and only materialize a batch at a time. Avoid converting the full dataset to NumPy arrays, and be careful with cache() because caching in memory can exhaust RAM on large datasets. If caching is useful, cache to a local SSD path or cache only after resizing and decoding when the cached data size is manageable.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Where should resizing, normalization, and data augmentation happen?

Resize images during loading by passing image_size to image_dataset_from_directory, then apply normalization and augmentation as Keras preprocessing layers in the model or in the input pipeline. Putting augmentation in the model is convenient because it runs only during training and is saved with the model. For maximum throughput, benchmark both approaches and combine them with batching and prefetching.

How do I create a reliable validation split from a directory dataset?

You can use validation_split and subset with a fixed seed when calling image_dataset_from_directory. For large production datasets, separate physical folders such as train, val, and test are often safer and easier to audit. Make sure duplicate or near-duplicate samples do not appear in both training and validation sets, especially when files come from the same user, video, document, or capture session.

Bottom Line

Loading large datasets from directories in Keras is most reliable when you keep data on disk, organize it consistently, and stream it in batches with tools like image_dataset_from_directory, text_dataset_from_directory, or custom tf.data pipelines. Add preprocessing, shuffling, caching, prefetching, and augmentation carefully so your model stays fed without overwhelming RAM.

Before scaling up training, validate your folder structure, labels, batch shapes, and train/validation split on a small subset. Once the pipeline is correct and performant, you can increase dataset size, tune throughput, and train with confidence on real-world data volumes.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Recommended PC Tool
Recommended PC Tool
Crashes, No Sound, or Screen Glitches?Free driver scan
Windows Errors? Fix Them Before They SpreadFree repair scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.