Built-in datasets and the modern transforms pipeline
torchvision ships ready-to-use datasets (MNIST, CIFAR-10/100, ImageNet, COCO) and a transforms pipeline. The current API is torchvision.transforms.v2 — it replaced the older torchvision.transforms as the recommended path. Use v2 for new code.
Why v2 matters
Native support for tv_tensors (Image, BoundingBoxes, Mask, Video) — important for detection and segmentation.
Transforms apply correctly across multiple inputs simultaneously: rotate an image AND its bounding boxes AND its mask, in one pass.
Much faster on the most common ops thanks to a rewritten implementation.
Cleaner separation between PIL-image transforms and tensor transforms.
The standard preprocessing chain
For ImageNet-pretrained models you'll see this exact recipe constantly:
ToImage() — wrap as a tv_tensor.Image (the v2-native type).
ToDtype(torch.float32, scale=True) — convert to float32 in [0, 1].
import torch
import torchvision.transforms.v2 as T
# This is the chain that matches every torchvision pretrained model
preprocess = T.Compose([
T.ToImage(),
T.ToDtype(torch.float32, scale=True),
T.Resize(256),
T.CenterCrop(224),
T.Normalize(mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225]),
])
# But the modern recommended way is to ASK the model for its transforms:
from torchvision.models import resnet50, ResNet50_Weights
weights = ResNet50_Weights.IMAGENET1K_V2
preprocess = weights.transforms()
# weights.transforms() returns the EXACT preprocessing the model was trained with
import torch
import torchvision.transforms.v2 as T
from torchvision import tv_tensors
# A scene with image + bounding boxes + segmentation mask
img = torch.randint(0, 255, (3, 224, 224), dtype=torch.uint8)
boxes = tv_tensors.BoundingBoxes(
[[10, 20, 100, 150]], format='XYXY', canvas_size=(224, 224)
)
mask = tv_tensors.Mask(torch.zeros(224, 224, dtype=torch.uint8))
transform = T.Compose([
T.RandomHorizontalFlip(p=1.0),
T.RandomRotation(15),
])
# Apply to all three at once — boxes and mask transform consistently with image
img_t, boxes_t, mask_t = transform(img, boxes, mask)
print(img_t.shape, boxes_t, mask_t.shape)
# This was nearly impossible with the old transforms API.
Load CIFAR-10 with the v2 transforms pipeline. Print the dtype, shape, mean, and std of one transformed image. Then load it WITHOUT Normalize and check the value range — should be [0, 1]. Add Normalize and verify the mean shifts toward 0 and std toward 1.
Progress
Progress is local-only — sign in to sync across devices.