Data Preprocessing
Data preprocessing turns raw tables, text, and images into the clean, scaled, fixed-format input a model expects. Common steps, leakage rules, and code.
Data preprocessing is the set of transformations that turn raw data into the clean, consistently formatted numerical input a machine learning (ML) model expects, applied the same way during training and at inference. For tabular data it means handling missing values, encoding categories as numbers, and scaling features. For images it means decoding files, resizing them to the network's input size, ordering the color channels, and scaling pixel values. The preprocessing is effectively part of the model: a network trained on RGB images scaled to 0–1 produces unreliable predictions when it receives BGR images with values from 0 to 255, even though its weights have not changed.
Common Preprocessing Steps#
- Data cleaning: Removing duplicates, corrupt files, and impossible values, and fixing inconsistent labels or units.
- Imputation: Filling missing values with a statistic such as the column median, a model-based estimate, or a separate "missing" category, or dropping rows with too many gaps.
- Encoding: Converting categories to numbers, with one-hot encoding for unordered categories such as color, ordinal codes for ordered ones such as size, and integer indices for class names.
- Scaling and normalization: Min-max scaling maps a feature to the range 0–1, and standardization subtracts the mean and divides by the standard deviation, so a feature measured in millimeters does not swamp one measured in meters in distance-based models, and gradient descent converges faster. Many ImageNet-pretrained models in torchvision expect each RGB channel standardized with the means 0.485, 0.456, and 0.406 and the standard deviations 0.229, 0.224, and 0.225.
- Resizing: Bringing every image to the network's input size, by stretching, by center cropping, or by letterboxing, which scales the image to fit and pads the remainder so objects keep their proportions.
- Tokenization: Splitting text into tokens and mapping each to an integer ID from a fixed vocabulary.
Domain-specific steps come on top. CT scans are windowed, mapping a range of Hounsfield units, such as the range that shows lung tissue, to the display intensities a model sees, and audio is resampled to a fixed rate and often converted to a spectrogram.
Fit on Training Data, Apply Everywhere#
Statistics used in preprocessing, such as feature means and standard deviations, imputation values, and category vocabularies, are computed on the training split only, saved, and then applied unchanged to validation, test, and production data. Computing them over the whole dataset before splitting lets information from the test set shape the training inputs, a form of data leakage that inflates evaluation scores. A scikit-learn Pipeline enforces the rule by fitting its preprocessing steps only inside the data passed to fit. Applying different preprocessing at serving time, such as another resize method or a different image decoder, causes training-serving skew, where a model scores well offline and worse in production.
Image Preprocessing for Vision Models#
Image models need a fixed tensor layout. OpenCV decodes images as height × width × channel arrays of 8-bit integers in BGR order, while PyTorch networks expect batches of float tensors in channel-first RGB order. YOLO26 prediction in Ultralytics runs these steps automatically: it resizes each image so its longer side matches imgsz, 640 pixels by default, without distorting it, pads it with gray pixels of value 114 to a 640 × 640 square for fixed-shape exported models or only to the next multiple of the 32-pixel stride for PyTorch models, flips BGR to RGB, reorders the array to channel-first, and divides by 255. The OpenCV and NumPy script below performs the square letterbox by hand:
import urllib.request
import cv2
import numpy as np
# Download a sample photo and read it as a BGR uint8 array of shape (height, width, 3)
urllib.request.urlretrieve("https://ultralytics.com/images/bus.jpg", "bus.jpg")
image = cv2.imread("bus.jpg")
# Resize so the longer side is 640 pixels, keeping the aspect ratio
scale = 640 / max(image.shape[:2])
resized = cv2.resize(image, None, fx=scale, fy=scale, interpolation=cv2.INTER_LINEAR)
# Letterbox: center the resized image on a 640x640 canvas of gray (114) padding
canvas = np.full((640, 640, 3), 114, dtype=np.uint8)
top, left = (640 - resized.shape[0]) // 2, (640 - resized.shape[1]) // 2
canvas[top : top + resized.shape[0], left : left + resized.shape[1]] = resized
# Reorder BGR to RGB and HWC to CHW, scale pixels to 0-1, and add a batch dimension
tensor = canvas[:, :, ::-1].transpose(2, 0, 1).astype(np.float32) / 255.0
batch = tensor[None]
print(f"{image.shape} uint8 -> {batch.shape} float32 in [{batch.min():.1f}, {batch.max():.1f}]")The script prints (1080, 810, 3) uint8 -> (1, 3, 640, 640) float32 in [0.0, 1.0]: the 1080 × 810 photo becomes a single-image batch in the layout and value range a PyTorch detector expects, with gray bars filling the 80 pixels on each side.
Data Preprocessing vs. Related Terms#
- Data labeling: Creating the ground-truth targets, such as classes and boxes, that preprocessing then converts into the numeric format training reads.
- Feature engineering: Creating new input variables from domain knowledge, such as body mass index from height and weight columns.
- Batch normalization: A layer inside the network that standardizes intermediate activations during training and inference. Input normalization in preprocessing happens once, before the data reaches the network.
- Data augmentation: Random transformations such as flips, color shifts, and mosaics, applied only during training to create varied copies of each example. Preprocessing is deterministic and identical at training and inference.










