Thuta Learning
BasicAIintermediate

Image Transformations and Augmentation Basics

What you'll walk away with

  • Explain the core ideas behind Image Transformations and Augmentation Basics
  • Run the sample code and verify its output
  • Apply the technique correctly to the Tutorial Platform and production scenarios

Build the mental model

A transform in torchvision is simply a function (or a small callable object) that takes an image tensor and returns a modified one, and the transforms.v2 API is the current, actively maintained way to write them — it works uniformly whether you're transforming a plain image tensor, a batch, or, when needed, paired data like bounding boxes and segmentation masks. Some transforms are shape-preserving: RandomHorizontalFlip reorders pixels left-to-right but the tensor still comes out (C, H, W) with the same H and W it went in with; Normalize and color-jitter operations rescale pixel values without touching spatial dimensions at all. Other transforms are shape-changing: Resize explicitly produces a different H and W, and RandomCrop/CenterCrop cut the tensor down to a smaller region. Compose chains several transforms into one callable, applying them in order — exactly the pipeline a DataLoader runs on every sample it yields, so understanding which stage changes shape and which doesn't matters for debugging batch-shape mismatches later.

The reason augmentation transforms like flips, crops, and color jitter exist at all is that they synthetically expand a training set's diversity without collecting a single new photo: randomly flipping a training image left-to-right doesn't change what object is in it, so training on both versions teaches the network that orientation shouldn't matter for the label — a form of invariance you're deliberately injecting rather than hoping the network discovers on its own from a fixed dataset. Crucially, these random transforms are applied stochastically and only during training; at evaluation or inference time you want a deterministic, repeatable transform (fixed resize, no random flip) so that the same input always produces the same prediction and your reported metrics don't jitter run to run just because of random augmentation.

Connect it to a real scenario

The Tutorial Platform generates three thumbnail sizes — a grid-card thumbnail, a hero banner, and a mobile-view crop — from a single instructor-uploaded course image by running it through a Resize-based pipeline at page-render time, and separately maintains an internal 'course-image quality' classifier trained with RandomHorizontalFlip and small random crops added to its training set, so the model doesn't accidentally learn that only left-facing or perfectly centered banners count as good thumbnails.

Try the working example

python
import torch
from torchvision.transforms import v2

torch.manual_seed(0)

# Synthetic batch: a single fake RGB image, 3 channels, 64x64.
image = torch.rand(3, 64, 64)

flip = v2.RandomHorizontalFlip(p=1.0)  # p=1.0 makes this deterministic for the demo
flipped = flip(image)
print("original shape:", image.shape)
print("flipped shape:", flipped.shape)
print("flip changed pixel order:", not torch.equal(image, flipped))

resize = v2.Resize((32, 32))
resized = resize(image)
print("resized shape:", resized.shape)

# Compose chains several transforms into one callable pipeline --
# this is exactly the kind of pipeline a DataLoader applies per sample.
pipeline = v2.Compose([
    v2.Resize((32, 32)),
    v2.RandomHorizontalFlip(p=0.5),
])
augmented = pipeline(image)
print("pipeline output shape:", augmented.shape)
You should see
Prints original shape: torch.Size([3, 64, 64]), flipped shape: torch.Size([3, 64, 64]) (unchanged — flip only reorders pixels), flip changed pixel order: True (guaranteed since p=1.0 forces the flip and a random continuous image is essentially never left-right symmetric), resized shape: torch.Size([3, 32, 32]), and pipeline output shape: torch.Size([3, 32, 32]) (the resize inside the pipeline always applies, so the output shape is the same regardless of whether the 50%-probability flip happened to trigger).

5-minute try-it

Add v2.RandomCrop((24, 24)) into the pipeline, run the pipeline three times in a loop printing augmented.shape and whether torch.equal(augmented, image) each time (accounting for the resize), and note which parts of the output are identical across runs (shape) versus which vary (exact pixel content due to the random flip).

One important caution

Applying RandomHorizontalFlip or other random augmentations during evaluation/inference instead of only during training — this makes the same input produce different predictions across runs and makes reported eval metrics noisy and irreproducible.

Assuming every transform in a Compose chain preserves shape — a Resize or CenterCrop anywhere in the chain changes H/W, so hardcoding an expected tensor shape downstream (e.g. for a fixed-size buffer) will break the moment someone adds a shape-changing transform earlier in the pipeline.

PyTorch Vision Docs — Transforming images, videos, boxes and moreComputer Vision

Easy traps

  • Applying RandomHorizontalFlip or other random augmentations during evaluation/inference instead of only during training — this makes the same input produce different predictions across runs and makes reported eval metrics noisy and irreproducible.
  • Assuming every transform in a Compose chain preserves shape — a Resize or CenterCrop anywhere in the chain changes H/W, so hardcoding an expected tensor shape downstream (e.g. for a fixed-size buffer) will break the moment someone adds a shape-changing transform earlier in the pipeline.
  • Validate sample code in a local or test environment before applying it to a production system.

Exercise

Add v2.RandomCrop((24, 24)) into the pipeline, run the pipeline three times in a loop printing augmented.shape and whether torch.equal(augmented, image) each time (accounting for the resize), and note which parts of the output are identical across runs (shape) versus which vary (exact pixel content due to the random flip).

You'll know it worked when: Prints original shape: torch.Size([3, 64, 64]), flipped shape: torch.Size([3, 64, 64]) (unchanged — flip only reorders pixels), flip changed pixel order: True (guaranteed since p=1.0 forces the flip and a random continuous image is essentially never left-right symmetric), resized shape: torch.Size([3, 32, 32]), and pipeline output shape: torch.Size([3, 32, 32]) (the resize inside the pipeline always applies, so the output shape is the same regardless of whether the 50%-probability flip happened to trigger).

Image Transformations and Augmentation Basics | Thuta Learning