Training a big network from scratch can take millions of examples and weeks of computing. Transfer learning lets you skip most of that by starting from a model that has already learned from a huge dataset, and adapting it to your own problem. It's how most real-world deep learning projects are built today.
- Level: Intermediate
- Time: about 40 minutes
- Needs: Modules 1 to 10
By the end of this module you will be able to
- Explain what transfer learning is and why it works
- Explain the difference between feature extraction and fine-tuning
- Choose a strategy based on how much data you have and how similar it is
- Find pretrained models for images and text
- Build an image classifier on top of a pretrained model in Keras
- Recognise when transfer learning won't help
11.1What is transfer learning?
Transfer learning means taking a model trained on one task and reusing what it learned for a different, related task.
You already do this
If you can drive a car, learning to drive a van takes hours, not months. You don't relearn steering, braking or road signs; you just adjust to the bigger size. Your "driving knowledge" transfers. In the same way, a network that has learned to recognise a thousand kinds of objects already knows about edges, textures, shapes and parts. It just needs a little extra training to recognise your objects.
This works because of what you learned in Module 8: the early layers of a CNN learn general features (edges, colours, textures) that are useful for almost any image task. Only the last layers are specific to the original task.
| Training from scratch | Transfer learning | |
|---|---|---|
| Data needed | Often tens of thousands of labelled examples or more | Often just hundreds, sometimes fewer |
| Training time | Hours to weeks, often on expensive GPUs | Minutes to hours |
| Typical accuracy with little data | Poor: overfits easily | Usually much better |
11.2Feature extraction and fine-tuning
There are two main ways to reuse a pretrained model. Both start the same way: remove the model's original output layer (its "head") and add a new one for your classes.
trainable = False in Keras.| Strategy | What you do | When to use it |
|---|---|---|
| Feature extraction | Freeze the whole pretrained model and train only the new head. The pretrained model acts as a fixed "feature finder" | Small datasets; fast and hard to overfit |
| Fine-tuning | After training the head, unfreeze some of the top pretrained layers and train them with a very small learning rate | More data, or your images differ a bit from the original ones |
Two golden rules of fine-tuning
1. Train the new head first. A new head starts with random weights, so its first big, messy gradients could wreck the carefully learned pretrained weights. 2. Use a tiny learning rate (for example 0.00001) when fine-tuning, so the pretrained knowledge is adjusted gently, not overwritten.
11.3Choosing a strategy
The right approach depends on two questions: how much labelled data do you have? And how similar is it to what the model was originally trained on?
Try it: transfer learning advisor
11.4Where to find pretrained models
| Source | What you'll find |
|---|---|
| Keras Applications | Popular image models, pretrained on ImageNet, in one line: MobileNetV2, EfficientNet, ResNet50, VGG16 and more |
| Hugging Face | Hundreds of thousands of pretrained models for text, images and audio, including BERT-style and GPT-style Transformers (Module 10) |
| TensorFlow Hub / Kaggle Models | Ready-to-use models for many tasks |
| PyTorch Hub, torchvision | Pretrained models for PyTorch users |
| Model | Size | Good for |
|---|---|---|
| MobileNetV2 | Small (about 3.5 million weights) | Fast; phones and laptops; a great first choice |
| EfficientNet | Small to large family | Strong accuracy for its size |
| ResNet50 | About 25 million weights | A reliable, well-understood workhorse |
Transfer learning isn't just for images. In language, almost every project today starts from a pretrained Transformer and fine-tunes it, for example to sort support emails or analyse reviews. That's how LLMs like ChatGPT and Claude are built too: a huge pretrained model, then further training for specific behaviour.
11.5Transfer learning in Keras
Here's a complete, real-world template: an image classifier built on MobileNetV2. Put your images in one folder per class (for example photos/cracked and photos/ok), and it trains in two stages: first the new head, then fine-tuning.
# Run this in Google Colab or on your own computer (it downloads the pretrained weights)
import keras
from keras import layers
# 1. Load MobileNetV2, pretrained on over a million ImageNet photos, minus its top layer
base = keras.applications.MobileNetV2(
input_shape=(160, 160, 3), include_top=False, weights="imagenet")
base.trainable = False # freeze its 2.2 million weights
# 2. Load YOUR images: one folder per class, e.g. photos/cracked, photos/ok
train_ds = keras.utils.image_dataset_from_directory(
"photos", validation_split=0.2, subset="training", seed=1,
image_size=(160, 160), batch_size=32)
val_ds = keras.utils.image_dataset_from_directory(
"photos", validation_split=0.2, subset="validation", seed=1,
image_size=(160, 160), batch_size=32)
# 3. Add a small new head for your classes
inputs = keras.Input(shape=(160, 160, 3))
x = keras.applications.mobilenet_v2.preprocess_input(inputs) # same scaling as ImageNet
x = base(x, training=False)
x = layers.GlobalAveragePooling2D()(x)
x = layers.Dropout(0.2)(x)
outputs = layers.Dense(len(train_ds.class_names), activation="softmax")(x)
model = keras.Model(inputs, outputs)
# 4. Stage 1: train only the new head
model.compile(optimizer="adam", loss="sparse_categorical_crossentropy", metrics=["accuracy"])
model.fit(train_ds, validation_data=val_ds, epochs=10)
# 5. Stage 2: fine-tune the top layers of the base with a tiny learning rate
base.trainable = True
for layer in base.layers[:-30]: # keep the early layers frozen
layer.trainable = False
model.compile(optimizer=keras.optimizers.Adam(1e-5),
loss="sparse_categorical_crossentropy", metrics=["accuracy"])
model.fit(train_ds, validation_data=val_ds, epochs=10)
Run this in Google Colab
This code downloads the pretrained weights and needs your own folder of images, so we haven't shown output here. In Colab, upload a zip of your folders, unzip it, and run the code. A GPU (Runtime → Change runtime type) makes it much faster. With a few hundred images per class of everyday objects, this approach often reaches high accuracy within a few epochs.
Reading the code
include_top=Falseremoves MobileNetV2's original 1,000-class output layer.base.trainable = Falsefreezes it for stage 1 (feature extraction).preprocess_inputscales your images exactly the way the original training images were scaled. Forgetting this is a very common mistake.- Stage 2 unfreezes only the top 30 layers, and uses a learning rate of 0.00001.
11.6When transfer learning doesn't help
Transfer learning works best when the pretrained model learned from a large, varied dataset. It helps much less if the original training data was small or narrow. Here's a real experiment: we trained a small CNN on handwritten digits 0 to 4, then reused it to learn digits 5 to 9 from just 25 images.
import os
os.environ["TF_CPP_MIN_LOG_LEVEL"] = "3"
import numpy as np
from sklearn.datasets import load_digits
import keras
from keras import layers
X, y = load_digits(return_X_y=True)
X = (X / 16.0).reshape(-1, 8, 8, 1)
# The "big" task: digits 0-4, with plenty of data (about 900 images)
big = y < 5
X_big, y_big = X[big], y[big]
# The NEW task: digits 5-9, with only 5 labelled images of each
rng = np.random.default_rng(0)
new_idx = np.where(y >= 5)[0]
train_idx = np.concatenate([rng.choice(new_idx[y[new_idx] == d], 5, replace=False)
for d in range(5, 10)])
test_idx = np.setdiff1d(new_idx, train_idx)
X_small, y_small = X[train_idx], y[train_idx] - 5
X_test, y_test = X[test_idx], y[test_idx] - 5
def feature_extractor():
return keras.Sequential([
keras.Input(shape=(8, 8, 1)),
layers.Conv2D(32, 3, padding="same", activation="relu"),
layers.MaxPooling2D(2),
layers.Conv2D(64, 3, padding="same", activation="relu"),
layers.Flatten(),
], name="features")
def with_new_head(base):
model = keras.Sequential([base, layers.Dense(5, activation="softmax")])
model.compile(optimizer=keras.optimizers.Adam(1e-3),
loss="sparse_categorical_crossentropy", metrics=["accuracy"])
return model
# 1. Pretrain on the big task
keras.utils.set_random_seed(0)
base = feature_extractor()
pre = keras.Sequential([base, layers.Dense(5, activation="softmax")])
pre.compile(optimizer="adam", loss="sparse_categorical_crossentropy", metrics=["accuracy"])
pre.fit(X_big, y_big, epochs=30, verbose=0)
pretrained_weights = base.get_weights()
# 2. Three ways to learn the new task from just 25 images
results = {}
keras.utils.set_random_seed(1)
scratch = with_new_head(feature_extractor()) # a) start from nothing
scratch.fit(X_small, y_small, epochs=100, verbose=0)
results["From scratch"] = scratch.evaluate(X_test, y_test, verbose=0)[1]
keras.utils.set_random_seed(1)
frozen_base = feature_extractor(); frozen_base.set_weights(pretrained_weights)
frozen_base.trainable = False # b) freeze the base
frozen = with_new_head(frozen_base)
frozen.fit(X_small, y_small, epochs=100, verbose=0)
results["Feature extraction (frozen)"] = frozen.evaluate(X_test, y_test, verbose=0)[1]
frozen_base.trainable = True # c) then fine-tune it all
fine = keras.Sequential([frozen_base, frozen.layers[-1]])
fine.compile(optimizer=keras.optimizers.Adam(1e-4), # much smaller learning rate
loss="sparse_categorical_crossentropy", metrics=["accuracy"])
fine.fit(X_small, y_small, epochs=30, verbose=0)
results["Fine-tuned"] = fine.evaluate(X_test, y_test, verbose=0)[1]
print(f"Training images for the new task: {len(X_small)} | Test images: {len(X_test)}")
for name, acc in results.items():
print(f"{name:28} test accuracy = {acc:.3f}")
Training images for the new task: 25 | Test images: 871 From scratch test accuracy = 0.931 Feature extraction (frozen) test accuracy = 0.892 Fine-tuned test accuracy = 0.894
What the output tells us
- Training from scratch won (93.1%), and both transfer approaches did a little worse (89%).
- Why? The "pretrained" model only ever saw about 900 tiny 8 × 8 images of five digits. Its features were too narrow to beat learning afresh, and digits are simple enough to learn from 25 examples anyway.
- Compare that with MobileNetV2, which learned from over a million varied photos. Its features are general enough to help with almost any photo task.
| Transfer learning helps most when… | It may not help when… |
|---|---|
| The pretrained model learned from a huge, varied dataset | The source dataset was small or narrow |
| Your data is similar in kind (e.g. photos to photos) | Your data is completely different (e.g. photos to audio) |
| You have little labelled data | You already have huge amounts of labelled data |
The lesson: always compare against a baseline, just as you did in the Machine Learning track. Don't assume a technique helps; test it.
SummaryKey takeaways
- Transfer learning reuses a model trained on a big dataset for a new, related task.
- It works because early layers learn general features (edges, textures, shapes).
- Feature extraction: freeze the pretrained model, train a new head. Best for small datasets.
- Fine-tuning: then unfreeze top layers and train them with a tiny learning rate. Train the head first.
- Choose based on how much data you have and how similar it is to the original data.
- Find models in Keras Applications and Hugging Face. Use the model's own
preprocess_input. - Transfer helps most when the source is large and varied; always compare with a baseline.
Check your understanding
Your neural networks roadmap
- 01Introduction to Neural NetworksWhat neural networks are and how they work
- 02The Perceptron and the Artificial NeuronBuild a single neuron from scratch
- 03Activation FunctionsSigmoid, tanh, ReLU and softmax
- 04Loss Functions and Gradient DescentHow networks measure and reduce error
- 05BackpropagationHow every weight learns its share of the blame
- 06Building Networks with KerasYour first deep learning library
- 07Training Better NetworksOverfitting, dropout, batch normalisation, early stopping
- 08Convolutional Neural NetworksTeaching computers to see
- 09Recurrent Neural Networks and LSTMsWorking with sequences
- 10Transformers and AttentionThe architecture behind ChatGPT and Claude
- 11Transfer Learning and Pretrained ModelsYou are here
- 12Capstone ProjectBuild and present a deep learning project
Next module
Capstone Project