mrkeyoor.com_
Wed 05 Aug 19:54 UTC
PyPIAI / MLupdated 05 Aug 2026

torchvision

torchvision is PyTorch's official computer vision library: pretrained model architectures (ResNet, ViT, Faster R-CNN and friends), common datasets (CIFAR, ImageNet wrappers, COCO), and image transforms that run on both PIL images and tensors. It is versioned in lockstep with torch itself, so torchvision 0.28 requires exactly torch 2.13, and it is the default starting point for training or fine-tuning vision models in PyTorch.

Verdict

If you train vision models with PyTorch you will almost certainly have torchvision installed, and its weights-plus-transforms bundling is genuinely good engineering. Treat it as the reliable baseline and reach for timm or albumentations when you outgrow its model zoo or its augmentation speed.

API stability3/5Still 0.x after a decade, and the project does deprecate: pretrained=True gave way to weights enums, transforms v1 to v2, read_image to decode_image. Migrations are documented and gradual, but old tutorials break
Docs4/5The pytorch.org docs have solid API references and an example gallery, and every weights enum documents its accuracy and preprocessing; the split between v1 and v2 transforms docs still confuses newcomers
Maintenance5/5Pushed the day of this review, maintained by the PyTorch team with releases in lockstep with every torch release, about 1182 open issues and PRs on a very high-traffic repo
Ecosystem5/5It sits inside the PyTorch ecosystem, the dominant research ML stack; nearly every vision tutorial, course, and paper repo assumes torchvision datasets and transforms are available

Use it if

  • You are training or fine-tuning a vision model in PyTorch and want pretrained weights with the exact preprocessing pipeline bundled next to them (weights.transforms())
  • You need standard datasets like CIFAR-10 or COCO wired into a DataLoader without writing download and parsing code yourself
  • You want detection, segmentation, or keypoint models (Faster R-CNN, Mask R-CNN, DeepLab) that plug straight into torch training loops
  • You use transforms v2 to augment images together with their bounding boxes and masks, which plain image libraries cannot do
Skip it if

Setup reality

pip install torchvision pulls in the exact matching torch wheel, which is hundreds of MB, and CUDA builds come from a separate index URL you must pass explicitly (the PyPI default wheel is CUDA for Linux, CPU for Mac), so follow the pytorch.org selector rather than guessing. The version lockstep table in the README is not optional reading: torch and torchvision upgrade together or not at all. Datasets download at import-and-run time, sometimes gigabytes, and the project explicitly does not vouch for dataset licenses; some pretrained weights (SWAG) are CC-BY-NC and unusable commercially.

Patterns

Classify an image with a pretrained modelpretrained-classification

import torch
from torchvision.models import resnet50, ResNet50_Weights

weights = ResNet50_Weights.DEFAULT
model = resnet50(weights=weights).eval()
preprocess = weights.transforms()

batch = preprocess(img).unsqueeze(0)
with torch.no_grad():
    probs = model(batch).softmax(dim=1)
idx = probs.argmax().item()
print(weights.meta["categories"][idx])

The old models.resnet50(pretrained=True) style is gone; weights enums replaced it. Always use weights.transforms() for preprocessing, because wrong resize or normalization silently tanks accuracy instead of erroring.

Modern transforms v2 preprocessingtransforms-v2-pipeline

import torch
from torchvision.transforms import v2

transform = v2.Compose([
    v2.ToImage(),
    v2.RandomResizedCrop(224, antialias=True),
    v2.RandomHorizontalFlip(),
    v2.ToDtype(torch.float32, scale=True),
    v2.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])

v2.ToImage plus v2.ToDtype(scale=True) replaces the old ToTensor. Import from torchvision.transforms.v2, not torchvision.transforms, or you get the legacy versions with the same class names.

Train on a folder of images per classimagefolder-dataloader

from torch.utils.data import DataLoader
from torchvision import datasets

ds = datasets.ImageFolder("data/train", transform=transform)
loader = DataLoader(ds, batch_size=32, shuffle=True, num_workers=4)
print(ds.classes)  # folder names become class labels

Class indices come from alphabetical folder order, not creation order. If train and val folders differ in which classes exist, the index mapping silently diverges between them.

Fine-tune only the head of a pretrained modelfine-tune-classifier

import torch.nn as nn
from torchvision.models import resnet50, ResNet50_Weights

model = resnet50(weights=ResNet50_Weights.DEFAULT)
for p in model.parameters():
    p.requires_grad = False
model.fc = nn.Linear(model.fc.in_features, num_classes)  # new head, grads on

Replacing model.fc after freezing works because the new Linear defaults to requires_grad=True. For other architectures the head attribute differs (classifier, heads), so print the model first.

Read an image file straight to a tensordecode-image

from torchvision.io import decode_image

img = decode_image("cat.jpg")  # uint8 tensor, shape [C, H, W]
print(img.shape, img.dtype)

decode_image is the current API; read_image is the deprecated older name. Output is uint8 in [0, 255], so pass it through v2.ToDtype(torch.float32, scale=True) before feeding a model.

Download and use a built-in datasetbuiltin-dataset

from torchvision import datasets

train = datasets.CIFAR10(root="data", train=True, download=True,
                         transform=transform)
img, label = train[0]

download=True fetches to root on first run and is a no-op afterwards. The project does not host these datasets and explicitly leaves license compliance to you, which matters for commercial use.

Run a pretrained detector on one imageobject-detection-inference

from torchvision.models.detection import (
    fasterrcnn_resnet50_fpn, FasterRCNN_ResNet50_FPN_Weights)

weights = FasterRCNN_ResNet50_FPN_Weights.DEFAULT
model = fasterrcnn_resnet50_fpn(weights=weights).eval()
pred = model([weights.transforms()(img)])[0]
keep = pred["scores"] > 0.8
print(pred["boxes"][keep], pred["labels"][keep])

Detection models take a list of image tensors, not a batched 4D tensor, and return one dict per image. Filter by score yourself; the model happily returns near-zero-confidence boxes.

Visualize detection resultsdraw-bounding-boxes

from torchvision.utils import draw_bounding_boxes
from torchvision.transforms.v2.functional import to_pil_image

annotated = draw_bounding_boxes(img, boxes=pred["boxes"][keep],
                                labels=names, width=3)
to_pil_image(annotated).show()

draw_bounding_boxes wants the uint8 image, not the normalized float tensor you fed the model. Keep a copy of the original around for visualization.

Augment image and bounding boxes togetherjoint-transform-boxes

from torchvision import tv_tensors
from torchvision.transforms import v2

boxes = tv_tensors.BoundingBoxes(raw_boxes, format="XYXY",
                                 canvas_size=img.shape[-2:])
transform = v2.Compose([v2.RandomHorizontalFlip(p=1.0)])
out_img, out_boxes = transform(img, boxes)

This is the headline feature of transforms v2: wrapping boxes in tv_tensors.BoundingBoxes makes flips and crops update coordinates too. Plain tensors passed alongside are treated as images and transformed independently.

Semantic segmentation with DeepLabV3segmentation-inference

from torchvision.models.segmentation import (
    deeplabv3_resnet50, DeepLabV3_ResNet50_Weights)

weights = DeepLabV3_ResNet50_Weights.DEFAULT
model = deeplabv3_resnet50(weights=weights).eval()
out = model(weights.transforms()(img).unsqueeze(0))["out"]
mask = out.argmax(1)[0]  # [H, W] class index per pixel

The model returns a dict; the logits live under the out key (plus aux when training). The 21 classes are the PASCAL VOC set, so anything else gets folded into background.

Install a compatible torch and torchvision pairmatch-torch-version

# torchvision 0.28.x requires torch 2.13.x, exactly
pip install torch==2.13.0 torchvision==0.28.0
# CUDA builds come from the pytorch index, e.g.:
pip install torch torchvision --index-url https://download.pytorch.org/whl/cu126

Mismatched pairs fail at import or with cryptic undefined-operator errors at runtime, not at install. The compatibility table in the README is the source of truth when pinning.

Alternatives

PackageRegistryPick it when
timmPyPIYou mainly want a large, current zoo of pretrained image classifiers and backbones
albumentationsPyPIAugmentation speed and variety matter more than staying inside the torch API
korniaPyPIYou need differentiable, GPU-batched image operations inside the training graph
opencv-pythonPyPIClassic image processing or video handling without any deep learning stack