Data Pipelines
Loading, transforming, and feeding data for training — RecordReader, DataSetIterator, normalization, and mini-batching
Getting data into a neural network is often the most involved part of a project. DL4J deliberately separates data loading from training, which makes it possible to swap data sources, normalize differently, or experiment with mini-batch sizes without touching the model definition. This page walks through each layer of that pipeline.
1. The Data Pipeline
Data moves from disk (or memory) to model weights through a fixed sequence of components:
Raw Data → InputSplit → RecordReader → RecordReaderDataSetIterator → DataSet/DataSetIterator → Model.fit()InputSplit — tells the reader where to find the raw files
RecordReader — reads each file/row and converts it into a
List<Writable>recordRecordReaderDataSetIterator — converts records into
DataSetobjects and groups them into mini-batchesDataSet / DataSetIterator — the in-memory representation that
MultiLayerNetworkandComputationGraphconsume viafit()
The following sections cover each component in detail.
2. InputSplit
An InputSplit defines which files or URIs a RecordReader should consume. The three most common variants are:
import org.datavec.api.split.FileSplit;
import org.datavec.api.split.NumberedFileInputSplit;
import org.datavec.api.split.CollectionInputSplit;
// Point at a directory and filter by extension
FileSplit fileSplit = new FileSplit(new File("/path/to/data"), new String[]{"csv"});
// Point at a numbered sequence of files (e.g., train_0.csv … train_99.csv)
NumberedFileInputSplit numberedSplit = new NumberedFileInputSplit("/path/train_%d.csv", 0, 99);
// Point at an explicit list of URIs
CollectionInputSplit collSplit = new CollectionInputSplit(uriList);FileSplit can also recurse into subdirectories, which is useful for image datasets where each class lives in its own folder. Pass true as the third argument to enable recursive traversal.
3. RecordReader
A RecordReader reads raw bytes from an InputSplit and converts each example into a List<Writable>. A Writable is a lightweight, type-safe wrapper around primitive values (integers, floats, text, and so on).
CSV Data
Each row becomes one record. Numeric columns become DoubleWritable or IntWritable; text columns become Text.
Image Data
ParentPathLabelGenerator assigns labels by directory name, which is the standard layout for classification datasets (one subdirectory per class).
Sequence (Time Series) Data
Each file represents a complete time series. Rows within the file are individual time steps.
Other RecordReader Implementations
JacksonRecordReader
JSON or YAML files
LineRecordReader
Raw text, one example per line
RegexLineRecordReader
Text files with regex-based field extraction
LibSvmRecordReader
Sparse feature vectors in LibSVM format
4. DataSet and MultiDataSet
DataSet is the central data container in DL4J. It holds:
features — an
INDArrayof input valueslabels — an
INDArrayof target valuesfeature mask (optional) — used for variable-length sequences
label mask (optional) — used for variable-length sequences
Array Shapes by Network Type
Feed-forward (dense)
[batchSize, numFeatures]
[batchSize, numClasses]
Convolutional (CNN)
[batchSize, channels, height, width]
[batchSize, numClasses]
Recurrent (RNN)
[batchSize, features, timeSteps]
[batchSize, numClasses, timeSteps]
Labels for classification are stored as one-hot vectors — a [batchSize, numClasses] array where each row has a 1.0 at the index of the true class and 0.0 everywhere else. RecordReaderDataSetIterator handles this conversion automatically.
MultiDataSet
MultiDataSet extends this concept to networks with multiple input arrays and/or multiple output arrays. It is used exclusively with ComputationGraph and RecordReaderMultiDataSetIterator. For a MultiLayerNetwork with a single input and output, DataSet is sufficient.
5. RecordReaderDataSetIterator
RecordReaderDataSetIterator is the bridge between DataVec (data loading) and DL4J (training). It reads records from a RecordReader, converts them to INDArray features and labels, and groups them into mini-batches of the requested size.
Classification
Regression
Image Classification
Sequence Data
For time series, use SequenceRecordReaderDataSetIterator instead:
Multiple Inputs and Outputs
For ComputationGraph models that consume more than one input array or produce more than one output, use RecordReaderMultiDataSetIterator:
6. Mini-Batching
Neural networks learn by computing gradients over small random samples of the training data, called mini-batches, and updating the weights after each one. This is the core of stochastic gradient descent.
The batchSize parameter on the iterator controls how many examples are returned per call to next().
Choosing a Batch Size
1 (online learning)
Very noisy gradient updates; slow convergence but good regularization
32–256 (typical)
Good balance of gradient quality and memory use
Full dataset (batch GD)
Low noise, but high memory cost and fewer weight updates per epoch
For most tasks, start with 32 or 64 and increase if GPU utilization is low. Values that are powers of 2 allow the hardware to use memory alignment optimizations more effectively.
When training for multiple epochs with model.fit(iterator, numEpochs), DL4J calls iterator.reset() automatically between epochs. If you manage the training loop manually, call iter.reset() yourself at the start of each epoch.
7. Built-in Dataset Iterators
DL4J ships with ready-to-use iterators for several standard benchmark datasets. These download and cache the data automatically on first use.
These iterators are useful for quickly verifying that a model architecture works before moving to a production dataset.
8. Normalization
Neural networks are sensitive to the scale of their inputs. Weights are typically initialized to small values near zero, and the optimizer step size (learning rate) is calibrated for inputs that are also near zero. Raw features — pixel values in the range 0–255, sensor readings spanning thousands of units, or mixed-scale tabular data — will cause very slow or unstable training unless normalized first.
DL4J provides normalizers that attach directly to iterators via setPreProcessor().
NormalizerStandardize (zero mean, unit variance)
This is the default choice for tabular data. It subtracts the mean and divides by the standard deviation so that each feature ends up with mean 0 and standard deviation 1.
NormalizerMinMaxScaler (range scaling)
Scales each feature to a target range — typically [0, 1] or [-1, 1].
ImagePreProcessingScaler
Divides pixel values (0–255) by a configurable factor to produce values in [0, 1].
VGG16ImagePreProcessor
For fine-tuning pretrained ImageNet models, this preprocessor subtracts the per-channel ImageNet mean (the same preprocessing VGGNet was trained with).
Critical Rule: Fit on Training Data Only
Always call normalizer.fit() on the training iterator and then apply the resulting normalizer to both training and test/validation iterators. Fitting on the full dataset (including test data) leaks information from the test set into training and inflates reported accuracy.
When you save a model for inference, save the normalizer alongside it so that the same transformation is applied to new inputs at prediction time:
9. Async Data Loading
On GPU-accelerated systems, data loading on the CPU can become the bottleneck: the GPU sits idle waiting for the next batch. Wrapping an iterator in AsyncDataSetIterator causes a background thread to prefetch batches while the GPU is processing the current one.
Note that MultiLayerNetwork.fit(DataSetIterator) and ComputationGraph.fit(DataSetIterator) automatically wrap compatible iterators in AsyncDataSetIterator internally, so you normally do not need to add this wrapper yourself. It is useful when you are calling iterator.next() in a manual training loop.
For multi-input networks, the equivalent wrapper is AsyncMultiDataSetIterator.
Putting It Together: A Complete CSV Example
This pattern — separate readers for train and test, normalization fit on training data only, iterator reset handled by fit() — is the foundation for virtually every DL4J training workflow.
Last updated
Was this helpful?