Step 1: freeze the base, train only the new head
Feature extraction is the safest, fastest form of transfer learning. You set base_model.trainable = False so every pretrained weight is locked, then bolt a tiny trainable head on top. Only the head learns — which means most of the network never computes gradients, training is cheap, and there is no way to damage the pretrained features. This is always your first move; fine-tuning (next lesson) only earns its complexity if this baseline plateaus.
Two details that trip people up
The head is deliberately small: a GlobalAveragePooling2D collapses the backbone's feature map into one vector per image, a Dropout guards against overfitting on your small dataset, and a single Dense sized to your classes does the prediction. Two non-obvious things in the Code section earn their keep:
training=Falsewhen you call the base model — this keeps BatchNorm layers in inference mode so their running statistics aren't disturbed by your data while the weights are frozen.- Using the functional
keras.Inputform rather than wrapping inSequential— it makes the frozen-base / trainable-head boundary explicit and is what the fine-tuning lesson builds on.