Modele wstępnie wytrenowane w torchvision: ResNet, EfficientNet i ViT
Uczą się Państwo wczytywać ResNet-50 wstępnie wytrenowany na ImageNet, analizować jego architekturę oraz wykonywać inferencję dla nowego obrazu, aby zweryfikować wcześniej nauczone reprezentacje.
Modele wstępnie wytrenowane w torchvision: ResNet, EfficientNet i ViT to bezpłatna lekcja Machine Learning Academy na CoddyKit. To lekcja 1 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Machine Learning Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Machine Learning Academy zawiera 4 lekcji w sumie.
Części tej lekcji nie zostały jeszcze przetłumaczone i są wyświetlane po angielsku.
Why Use Pre-trained Models?
Training a deep neural network on ImageNet from scratch requires millions of labelled images and weeks of GPU compute. Pre-trained models have already learned general visual features — edges, textures, shapes, and high-level object parts — from this enormous dataset.
By reusing these weights, you benefit from the learning done on 1.2 million images without paying the training cost. This is the core idea of transfer learning: features learned on one large task transfer well to related smaller tasks. torchvision.models provides dozens of pre-trained architectures ready to download and use.
import torchvision.models as models
# List some available pre-trained models
print(dir(models)) # Shows resnet50, efficientnet_b0, vit_b_16, etc.
# Loading weights pre-trained on ImageNet-1k
resnet = models.resnet50(weights=models.ResNet50_Weights.IMAGENET1K_V1)
print('ResNet-50 loaded, parameters:', sum(p.numel() for p in resnet.parameters()))ResNet-50: Architecture Overview
ResNet-50 (Residual Network with 50 layers) introduced skip connections that add the input of a block directly to its output: output = F(x) + x. This allows gradients to flow directly through the addition, enabling training of very deep networks without vanishing gradients.
ResNet-50 has approximately 25 million parameters and consists of: one initial 7×7 convolutional layer, max pooling, four residual blocks (layer1–layer4), and a global average pooling layer followed by a 1000-class fully connected head for ImageNet classification. The final fc layer is what we replace for custom tasks.
import torchvision.models as models
import torch
resnet = models.resnet50(weights=models.ResNet50_Weights.IMAGENET1K_V1)
print(resnet) # Prints the full architecture
# Key layers
print('Final FC layer:', resnet.fc) # Linear(2048, 1000)
print('Layer4 output channels:', 2048) # Feature dimension before FCRunning Inference with ResNet-50
Before running inference, inputs must match the preprocessing used during ImageNet training: resize to at least 224×224, normalise with ImageNet mean and standard deviation. The torchvision.transforms API handles this. Always call model.eval() before inference to disable dropout and batch normalisation training mode.
The model outputs 1000 logits, one per ImageNet class. We apply softmax to get probabilities and pick the top-k classes. torchvision.models now includes category names in the weights metadata, eliminating the need for a separate labels file.
import torch
from torchvision import transforms
from PIL import Image
import torchvision.models as models
weights = models.ResNet50_Weights.IMAGENET1K_V1
resnet = models.resnet50(weights=weights)
resnet.eval()
# Preprocessing transforms from the weights metadata
preprocess = weights.transforms()
# Load and preprocess an image
img = Image.open('cat.jpg')
tensor = preprocess(img).unsqueeze(0) # Add batch dimension
with torch.no_grad():
logits = resnet(tensor)
probs = torch.softmax(logits, dim=1)
top5 = torch.topk(probs, 5)
print('Top-5 probabilities:', top5.values)EfficientNet: Compound Scaling
EfficientNet (2019) introduced compound scaling: systematically scaling network width, depth, and input resolution together using a single compound coefficient. Instead of arbitrarily making networks wider or deeper, EfficientNet balances all three dimensions for optimal accuracy-efficiency trade-offs.
The EfficientNet family ranges from efficientnet_b0 (5M parameters) to efficientnet_b7 (66M parameters). EfficientNet-B0 achieves comparable accuracy to ResNet-50 while using 8× fewer parameters and 6× fewer FLOPs, making it ideal for mobile and edge deployment. PyTorch provides all eight variants.
import torchvision.models as models
import torch
# EfficientNet-B0: lightweight but accurate
eff_b0 = models.efficientnet_b0(weights=models.EfficientNet_B0_Weights.IMAGENET1K_V1)
print('EfficientNet-B0 params:', sum(p.numel() for p in eff_b0.parameters()))
print('EfficientNet-B0 classifier:', eff_b0.classifier)
# Compare with ResNet-50
resnet50 = models.resnet50(weights=None) # No weights to count params only
print('ResNet-50 params:', sum(p.numel() for p in resnet50.parameters()))Vision Transformer (ViT): Attention Without Convolutions
Vision Transformers (ViT) (2020) apply the transformer architecture directly to images, without any convolution. The image is split into a grid of fixed-size patches (e.g., 16×16 pixels), each flattened and projected to an embedding vector. These patch embeddings are treated like word tokens in NLP.
A CLS (classification) token is prepended to the patch sequence. After passing through multiple transformer encoder blocks with self-attention, the CLS token's output is used for classification. ViT requires large training datasets to outperform CNNs, but pre-trained ViT models from torchvision bring this power to your tasks immediately.
import torchvision.models as models
import torch
# ViT-B/16: Base model with 16x16 patches
vit = models.vit_b_16(weights=models.ViT_B_16_Weights.IMAGENET1K_V1)
print('ViT-B/16 params:', sum(p.numel() for p in vit.parameters()))
print('ViT patch size: 16x16 pixels')
print('ViT sequence length for 224x224 image:', (224 // 16) ** 2 + 1, '(196 patches + 1 CLS token)')
print('ViT head:', vit.heads) # Linear(768, 1000)Comparing ResNet, EfficientNet, and ViT
Choosing among these architectures depends on your constraints and task. ResNet-50 is the reliable default: well understood, strong baseline, many tutorials and implementations. EfficientNet-B0/B2 wins when inference speed and model size matter — mobile apps, real-time systems, or edge hardware.
ViT excels on large-scale tasks and benefits from self-supervised pre-training (DINO, CLIP). It requires more compute and memory than CNNs of similar accuracy. For most custom image classification tasks with moderate-sized datasets, start with EfficientNet-B2 or ResNet-50, then try ViT if you have the resources to fine-tune it.
# Rough comparison on ImageNet top-1 accuracy
comparison = {
'ResNet-50': {'params': '25M', 'top1': '76.1%', 'year': 2015},
'EfficientNet-B0': {'params': '5M', 'top1': '77.7%', 'year': 2019},
'EfficientNet-B4': {'params': '19M', 'top1': '83.4%', 'year': 2019},
'ViT-B/16': {'params': '86M', 'top1': '81.1%', 'year': 2020},
'ViT-L/16': {'params': '307M','top1': '85.1%', 'year': 2020},
}
for name, info in comparison.items():
print(f'{name}: {info["params"]} params, {info["top1"]} top-1')Inspecting Model Internals
Before modifying a pre-trained model for your task, inspect its architecture to understand which layers to replace. Use print(model) to see the layer tree, and named_modules() or named_children() to iterate programmatically.
The key insight: every torchvision model ends with a classification head sized for 1000 ImageNet classes. To adapt the model to your task with num_classes different from 1000, you replace this final layer. The feature extractor (everything before the head) retains ImageNet-learned features.
import torchvision.models as models
resnet = models.resnet50(weights=models.ResNet50_Weights.IMAGENET1K_V1)
# Find the names of top-level children
for name, module in resnet.named_children():
print(name, '->', type(module).__name__)
# Output:
# conv1 -> Conv2d
# bn1 -> BatchNorm2d
# relu -> ReLU
# maxpool -> MaxPool2d
# layer1 -> Sequential (Residual blocks)
# layer2 -> Sequential
# layer3 -> Sequential
# layer4 -> Sequential
# avgpool -> AdaptiveAvgPool2d
# fc -> Linear <-- This is what we replaceFeature Vector Size for Each Architecture
When you replace the classification head, you need to know the feature dimension output by the backbone (everything except the final layer). This dimension is the input size of your new classification head.
Common backbone output dimensions: ResNet-50 outputs 2048, EfficientNet-B0 outputs 1280, and ViT-B/16 outputs 768. These feature vectors are computed by global average pooling over the spatial feature maps, producing a single vector per image. Your replacement head takes this vector as input.
import torch
import torchvision.models as models
# Feature dimensions before the classification head
feature_dims = {
'resnet50': 2048,
'efficientnet_b0': 1280,
'efficientnet_b2': 1408,
'efficientnet_b4': 1792,
'vit_b_16': 768,
'vit_l_16': 1024,
}
# Verify for ResNet-50 by running a dummy forward pass without the head
resnet = models.resnet50(weights=None)
resnet.fc = torch.nn.Identity() # Remove FC layer
x = torch.randn(1, 3, 224, 224)
features = resnet(x)
print('ResNet-50 feature size:', features.shape) # (1, 2048)Checking Pre-trained Weight Quality
You can quickly verify that a pre-trained model's weights are correct by running it on a well-known test image and checking whether the top prediction matches the expected label. This sanity check ensures the weights loaded correctly and the preprocessing pipeline is correct.
Beyond this test, it is good practice to always check the expected input format from the weights metadata: input size (224×224 for most models), channel order (RGB, not BGR), and normalisation constants (ImageNet mean and std). Using wrong normalisation is a common bug that causes poor transfer learning results.
import torchvision.models as models
weights = models.ResNet50_Weights.IMAGENET1K_V1
print('Expected input size:', weights.meta['min_size']) # (1, 1)
print('Transforms:', weights.transforms())
# Includes Resize(232), CenterCrop(224), Normalize(mean, std)
# ImageNet normalisation constants
IMAGENET_MEAN = [0.485, 0.456, 0.406]
IMAGENET_STD = [0.229, 0.224, 0.225]
# Always use these EXACT values with ImageNet pre-trained modelsPreparing for Fine-Tuning Your Own Task
The typical workflow for using pre-trained models on custom tasks is: (1) load the pre-trained model with weights=...IMAGENET1K..., (2) replace the final classification head with a new nn.Linear sized for your number of classes, (3) optionally freeze the backbone weights initially, and (4) train using a lower learning rate than you would use from scratch.
The new classification head starts with random weights and needs to learn from your data. The backbone starts with excellent features and needs only minor adjustments. This is why differential learning rates — a very low rate for the backbone and a higher rate for the head — often improve convergence speed and final accuracy.
import torchvision.models as models
import torch.nn as nn
# Example: Adapt ResNet-50 for 5-class flower classification
model = models.resnet50(weights=models.ResNet50_Weights.IMAGENET1K_V1)
# Replace the final FC layer
num_classes = 5
model.fc = nn.Linear(model.fc.in_features, num_classes)
# Differential learning rates
optimizer = torch.optim.Adam([
{'params': model.fc.parameters(), 'lr': 1e-3}, # High LR for new head
{'params': [p for n, p in model.named_parameters() if 'fc' not in n], 'lr': 1e-5} # Low LR for backbone
])Quick Check
Test your understanding of pre-trained torchvision models from this lesson.
Lesson Recap
In this lesson you learned: ResNet-50 uses skip connections to train very deep networks and outputs 2048-dimensional features, EfficientNet achieves better accuracy-efficiency trade-offs through compound scaling of width, depth, and resolution, and ViT applies transformer self-attention to image patches without convolutions. Next up we learn feature extraction — freezing the pre-trained backbone and training only a new classification head on your custom dataset.
Często zadawane pytania
Czy lekcja „Modele wstępnie wytrenowane w torchvision: ResNet, EfficientNet i ViT” jest bezpłatna?
Tak — pełny tekst „Modele wstępnie wytrenowane w torchvision: ResNet, EfficientNet i ViT” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Machine Learning Academy, przejdź na CoddyKit PRO. Kurs Machine Learning Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Modele wstępnie wytrenowane w torchvision: ResNet, EfficientNet i ViT”?
Uczą się Państwo wczytywać ResNet-50 wstępnie wytrenowany na ImageNet, analizować jego architekturę oraz wykonywać inferencję dla nowego obrazu, aby zweryfikować wcześniej nauczone reprezentacje. Ćwiczysz Machine Learning Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Machine Learning Academy?
Nie wymagamy żadnego doświadczenia. Machine Learning Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 1 z 4.
Ile czasu zajmuje lekcja „Modele wstępnie wytrenowane w torchvision: ResNet, EfficientNet i ViT”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Machine Learning Academy?
Tak. Każda lekcja Machine Learning Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Modele wstępnie wytrenowane w torchvision: ResNet, EfficientNet i ViT
- Ekstrakcja cech: zamrażanie backbone'u
- Dostrajanie: odmrażanie warstw i niskie współczynniki uczenia
- Adaptacja domeny: obrazowanie medyczne z niewielką liczbą etykiet