Freeze pretrained backbone, only train new classifier:
Copy
import torchimport torch.nn as nnimport torchvision.models as models# Load pretrained modelbackbone = models.resnet50(weights=models.ResNet50_Weights.IMAGENET1K_V2)# Freeze all parametersfor param in backbone.parameters(): param.requires_grad = False# Replace classifiernum_features = backbone.fc.in_featuresbackbone.fc = nn.Sequential( nn.Dropout(0.2), nn.Linear(num_features, 256), nn.ReLU(), nn.Dropout(0.2), nn.Linear(256, num_classes))# Only new layers are trainabletrainable_params = sum(p.numel() for p in backbone.parameters() if p.requires_grad)print(f"Trainable parameters: {trainable_params:,}")
def unfreeze_layers(model, num_layers): """Unfreeze last N layers of ResNet.""" layers = list(model.children()) # Freeze all for param in model.parameters(): param.requires_grad = False # Unfreeze last N layers for layer in layers[-num_layers:]: for param in layer.parameters(): param.requires_grad = True# Stage 1: Train classifier onlyunfreeze_layers(model, 1)train(model, epochs=5, lr=1e-3)# Stage 2: Unfreeze last blockunfreeze_layers(model, 2)train(model, epochs=5, lr=1e-4)# Stage 3: Fine-tune more layersunfreeze_layers(model, 4)train(model, epochs=10, lr=1e-5)
import timm# Load pretrained ViTmodel = timm.create_model('vit_base_patch16_224', pretrained=True, num_classes=10)# Freeze patch embedding and first N blocksfor param in model.patch_embed.parameters(): param.requires_grad = Falsefor i, block in enumerate(model.blocks): if i < 8: # Freeze first 8 of 12 blocks for param in block.parameters(): param.requires_grad = False# Fine-tune with smaller LR for unfrozen pretrained layersoptimizer = torch.optim.AdamW([ {'params': model.blocks[8:].parameters(), 'lr': 1e-5}, {'params': model.head.parameters(), 'lr': 1e-4},])