Images as Tensors
An image file is encoded bytes; a model receives a numeric tensor. The conversion contract must name the axis order, dtype, value range, color space, and normalization. This path uses (N, C, H, W): batch, channel, height, width.
Prerequisites
Complete Tensors, Gradients, and Autodiff. You should recognize shapes, dtypes, and broadcasting.
Learning goals
- distinguish file layout
(H, W, C)from PyTorch's common(C, H, W)layout. - scale
uint8values in[0, 255]to floating-point values in[0, 1]deliberately. - apply per-channel normalization without mixing batch or spatial axes.
Worked example
This generated 2-by-3 RGB image has a visible, auditable value in every channel. permute changes axis order; it does not change the pixels. The leading dimension is then added for a one-image batch.
import torch
image_hwc = torch.tensor(
[
[[255, 0, 0], [0, 255, 0], [0, 0, 255]],
[[255, 255, 255], [0, 0, 0], [128, 64, 32]],
],
dtype=torch.uint8,
)
image_chw = image_hwc.permute(2, 0, 1).to(torch.float32) / 255.0
batch = image_chw.unsqueeze(0)
mean = torch.tensor([0.5, 0.5, 0.5])[:, None, None]
normalized = (image_chw - mean) / mean
print(f"file_like={tuple(image_hwc.shape)} dtype={image_hwc.dtype} range=({image_hwc.min()}, {image_hwc.max()})")
print(f"model_batch={tuple(batch.shape)} dtype={batch.dtype} range=({batch.min():.1f}, {batch.max():.1f})")
print(f"normalized_pixel={[round(v, 1) for v in normalized[:, 0, 0].tolist()]}")
Output:
file_like=(2, 3, 3) dtype=torch.uint8 range=(0, 255)
model_batch=(1, 3, 2, 3) dtype=torch.float32 range=(0.0, 1.0)
normalized_pixel=[1.0, -1.0, -1.0]
Real decoders must also define color conversion: grayscale, RGB, RGBA, and CMYK are not interchangeable. When resizing, specify the output (height, width), interpolation, and antialiasing. Bilinear interpolation is sensible for continuous-color images; nearest-neighbor interpolation is normally required for integer class masks so interpolation does not invent label IDs.
Common mistakes
- Treating
(H, W, C)as(C, H, W)because both contain three dimensions. - Dividing values already in
[0, 1]by 255 again, or feedinguint8to a floating-point model. - Copying normalization constants from pretrained weights without using the matching color order and preprocessing recipe.
- Computing dataset mean and standard deviation before the split, which leaks validation and test pixels.
- Resizing an image without documenting aspect-ratio distortion or interpolation.
Practice
Change the pixel at row 1, column 2 to [255, 128, 0]. Predict its three normalized values before running. Then explain which axes a batch of four 64-by-96 RGB images would have.
Next steps
Continue with Convolution and Pooling to exploit spatial locality while preserving the tensor contract.
Primary sources
Checked 2026-10-16: TorchVision tensor image conventions, TorchVision ToDtype, TorchVision Normalize, and TorchVision Resize.