P e x c e r a

Feature Extraction vs. Fine-tuning Guidelines

Choosing between feature extraction and fine-tuning depends on the size of the target dataset and its similarity to the source domain.


Decision Matrix and Domain Similarity

The optimal transfer strategy is determined by dataset size and similarity between source and target visual spaces.

Target Dataset Size

The size of the target dataset is the primary constraint. If the target dataset is extremely small (e.g., fewer than 1000 images), fine-tuning deep layers will lead to severe overfitting. In this scenario, feature extraction is the only viable option.

If the target dataset is large (e.g., over 100,000 images), the model can support fine-tuning of all layers without risk of overfitting. The abundance of data allows the pre-trained weights to be adjusted to the target domain safely, improving final classification accuracy.

Similarity to Source Domain

The similarity between the pre-trained dataset (e.g., ImageNet) and the target dataset (e.g., satellite imagery) determines the relevance of the features.

If the domains are highly similar (e.g., classifying dog breeds), the pre-trained filters are highly relevant, and feature extraction is sufficient. If the domains differ significantly (e.g., classifying medical ultrasound scans), the low-level edge features are still useful, but the high-level semantic shapes differ completely, requiring deep fine-tuning.

Practical Guidelines and Trade-offs

Understanding scenario-based guidelines enables developers to select training options that balance computation and accuracy.

The Four Scenarios

The decision matrix can be divided into four scenarios. Scenario 1: Small dataset, similar domain. Use feature extraction; train only the classifier head to avoid overfitting. Scenario 2: Large dataset, similar domain. Use fine-tuning with a low learning rate; since data is abundant, this will improve performance. Scenario 3: Small dataset, different domain. This is the hardest case. Freezing the feature extractor is sub-optimal because the features are not relevant, but fine-tuning leads to overfitting. A common compromise is to freeze early layers and fine-tune only the final few blocks. Scenario 4: Large dataset, different domain. Fine-tune the entire network from pre-trained weights; the pre-trained initialization speeds up convergence compared to random weights.

Using this structured approach ensures that resources are allocated efficiently, matching target data traits.

Training Speed and Compute Trade-offs

Feature extraction is computationally cheaper because gradients are only computed for the classification head, reducing memory usage and training time.

Fine-tuning requires computing gradients for all parameters and updating optimizer states, which increases memory consumption and slows down execution. In cloud deployments, choosing feature extraction reduces training costs significantly.

Pre-trained Diagnostics

We can verify parameter freeze states programmatically to ensure our training setup aligns with transfer guidelines.

Diagnostic Step for Transfer Learning

The code below shows how to log the trainable parameter status of a model, helping verify that the chosen transfer learning strategy is implemented correctly.

<pre><code class="language-python">import torch import torch.nn as nn from torchvision import models def print_model_status(model): trainable_count = sum(p.numel() for p in model.parameters() if p.requires_grad) total_count = sum(p.numel() for p in model.parameters()) print(f"Trainable: {trainable_count:,} / {total_count:,} ({trainable_count/total_count:.2%})") model = models.resnet18(pretrained=True) # Freeze feature extractor for param in model.parameters(): param.requires_grad = False model.fc = nn.Linear(model.fc.in_features, 10) print_model_status(model) # Trainable count is only 5,130 weights out of 11M total</pre>

In this diagnostics run, only the weights in the replaced linear classifier head require gradients, demonstrating a feature extraction setup where 99.95% of weights are locked.

Optimization Settings

Below is the setup showing how to filter out frozen parameters when passing them to the optimizer.

<pre><code class="language-python">import torch.optim as optim # Create optimizer passing only trainable parameters optimizer = optim.SGD( filter(lambda p: p.requires_grad, model.parameters()), lr=0.01, momentum=0.9 )</pre>

Filtering parameters prevents the optimizer from creating momentum buffers for frozen weights, saving memory during backpropagation.