Transfer Learning
A model trained on other photographs may already measure useful visual patterns. We can test those features with a new prediction head before deciding whether the feature extractor also needs to change.
14 sections · 4 questions · 2 coding challenges
The arrow keys move between sections too.
Testing Which Learned Features Transfer
BOTIE
That work investigated transfer rather than inventing the general idea of reusing learned knowledge. For our purposes, it suggests a practical question: do the available features already separate our new classes, or does the representation itself need to change?
Do We Have to Learn Every Visual Pattern Again?
Botie wants to distinguish healthy leaves from damaged ones, but he has only a small labelled collection. A large image network contains far more adjustable settings than this small collection can reliably teach from scratch.
Suppose another network has already learned to measure edges, textures, and more complicated visual patterns. Could those measurements help with our leaves? We will first keep that measuring process fixed and learn a new rule from its outputs.
The feature vectors are supplied teaching values, not outputs from a pretrained image model.
Step 1 of 3
Separate two jobs
The feature extractor maps an image to measurements. The head maps those measurements to the answer required by our new task.
- Feature extractor
- image → feature vector
- New head
- feature vector → leaf class
Step 2 of 3
Hold one part fixed
For an initial experiment, the feature extractor stays unchanged while the new head learns from labelled leaves.
- Extractor parameters
- fixed
- Head parameters
- adjusted from new labels
Step 3 of 3
Inspect the boundary of what can be learned
If the extractor gives indistinguishable features to two differently labelled leaves, a head cannot recover the distinction from those features alone.
| Feature coordinate | Healthy leaf features | Damaged leaf features |
|---|---|---|
| Feature 1 | 0.4 | 0.4 |
| Feature 2 | 0.6 | 0.6 |
Feature 1
- Healthy leaf features
- 0.4
- Damaged leaf features
- 0.4
Feature 2
- Healthy leaf features
- 0.6
- Damaged leaf features
- 0.6
A learned representation can support another prediction task
The feature extractor's output is fixed. Only the head determines how those measurements become scores and class decisions.
What can a new head do with fixed leaf features?
The feature rows have already been computed. Change the head's coefficients and compare its class decisions without changing what the feature extractor supplied.
BOTIE
Class decisions from the new head
- 01
- 10
- 21
Follow the operations
1. Fixed leaf features
1 0 0 1 1 1 2. New head weights
- 02
- 1-1
3. Matrix times vector
- 02
- 1-1
- 21
4. New head bias
-0.5
5. Add
- 01.5
- 1-1.5
- 20.5
6. Set a constant
0
7. Threshold gate
- 01
- 10
- 21
8. Result
- 01
- 10
- 21
The feature vectors and head are invented. This construction demonstrates inference from a supplied head, not backbone training or a transfer-performance claim.
1. Name the Representation and the New Head
A feature extractor is the part of a model that turns an input into a vector or feature map. A prediction head is the part that turns that representation into the output we need. We usually replace the old head because its classes differ from ours.
In this lesson we supply tiny feature vectors directly. They are invented measurements that let us inspect the head's arithmetic, not outputs from a downloaded pretrained network.
Image → fixed feature extractor → feature vector h
Score = w · h + b
Probability of class 1 = sigmoid(score)The class meaning comes from the new labelled task. A pretrained network does not know our class definitions merely because it has useful features.
2. Freeze Parameters and Preserve the Input Contract
Let's first keep the feature extractor's parameters fixed and train only the new head. Disabling optimizer updates is one part of that job. Dropout and batch normalization also have training and evaluation behaviours, which are controlled separately from whether parameters receive updates.
The images must be prepared as the pretrained weights expect. Check their channel order and resizing policy, as well as normalization. If we cache features to reuse later, run the extractor in the intended deterministic evaluation mode so the saved values represent the same procedure.
The PyTorch reference shows these controls in a real model. Here we work directly with fixed feature rows so the boundary is explicit.
3. Fit a Small Head From the New Labels
For a binary task, a linear head supplies one weight per feature and a bias. The sigmoid turns its score into a probability. We can then use binary cross-entropy to fit the head.
Each training row contributes the difference between its predicted probability and observed label. Combining those differences with the feature columns gives the weight gradient. Averaging the differences gives the bias gradient.
scores = H @ w + b
p = sigmoid(scores)
weight_gradient = H.T @ (p - y) / number_of_rows
bias_gradient = mean(p - y)The gradient changes the head only. The supplied feature rows stay fixed.
Predict from a supplied head
These two invented features are already available. Inspect how the head combines them.
import numpy as np
H = np.array([[1.,0.], [0.,1.], [1.,1.]])
w = np.array([2.,-1.])
b = -0.5
scores = H @ w + b
print(scores.tolist())
print((scores >= 0).astype(int).tolist())[1.5, -1.5, 0.5]
[1, 0, 1]A zero score is the probability-one-half boundary for this sigmoid head. Our decision rule assigns equality to class one.
4. Fine-Tune Only When the Comparison Justifies It
If the frozen features are insufficient, we can unfreeze some or all of the extractor and continue training. This is fine-tuning. It adds flexibility but also more ways to overfit a small dataset or damage useful existing features.
A common experiment starts with the head, then tries limited fine-tuning with a smaller learning rate for the extractor. The appropriate settings depend on the source and target data. Keep a held-out comparison and inspect class-specific errors.
Pretraining on ordinary photographs may transfer poorly to a very different measurement process. Reuse is a hypothesis to evaluate, not a guarantee.
5. Keep the Evaluation About New Observations
Separate related photographs before fitting or augmenting. Compare the transferred model against a simple baseline using the same held-out groups. Fit any new preprocessing statistics on training data only.
Botie's workshop follows a frozen feature row through weights, bias, and a decision threshold. The programming challenges then make one head update so you can see exactly which numbers training changes.
This exercise covers the head and the transfer protocol. It does not measure the performance of an actual pretrained vision backbone.
6. A Frozen Extractor Still Has an Execution Mode
Preventing parameter updates and selecting evaluation behaviour are separate decisions. Dropout can still randomise features in training mode. Batch normalisation can update running statistics even when its trainable coefficients are frozen.
If we cache features, use a documented deterministic extractor configuration and preserve its preprocessing. Otherwise the head may be trained on representations that differ from those used at prediction time. Changing the extractor invalidates a cache made from its earlier state.
7. Let the New Labels Train the Head
For a binary head, subtract labels from sigmoid probabilities to obtain score derivatives under mean binary cross-entropy. Multiply those derivatives by the feature table to collect weight gradients. The bias receives their mean.
Repeat the update on the same supplied features to see the head learn. A real transfer experiment would replace these invented features with a pretrained extractor and evaluate on held-out leaves.
Train only the decision layer
One feature orders the examples from healthy to damaged; the feature values themselves never change.
import numpy as np
features = np.array([[-2.],[-1.],[1.],[2.]])
y = np.array([0.,0.,1.,1.])
w, b = np.zeros(1), 0.
for _ in range(200):
probability = 1/(1+np.exp(-(features@w+b)))
error = probability-y
w -= .1*(features.T@error)/len(y)
b -= .1*error.mean()
print(((features@w+b) >= 0).astype(int).tolist())
print(features[:,0].tolist())[0, 0, 1, 1]
[-2.0, -1.0, 1.0, 2.0]The head can separate this deliberately simple representation. Its training success is not evidence that an arbitrary source extractor will represent leaf damage well.
8. A Useful Source Model Can Still Be the Wrong Starting Point
If the source training discarded exactly the variation our target needs, a frozen head may have little information to use. Compare frozen features, limited fine-tuning and a suitable simpler baseline under the same split.
Inspect which classes improve and which regress. A smaller learning rate for the extractor is a reasonable experiment, not a guarantee against damaging useful features. Save the best validated state and its preprocessing together, rather than selecting the last training step automatically.
Check yourself
Questions on Parts 1 to 8
Question 1 of 4
Which values should the optimiser update in this experiment?
Use the information below.
The pretrained extractor produces H. A new binary head has weights w and bias b. The extractor is frozen.Try it with Botie
Build with Botie
Write and run Python