Using VGG16 and ResNet50 as Base Models
keras.applications.VGG16(weights='imagenet', include_top=False), adding custom head.
Using VGG16 and ResNet50 as Base Models is a free Learn AI with Python lesson on CoddyKit — lesson 2 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Learn AI with Python learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Keras Applications Module
tf.keras.applications ships dozens of pretrained architectures you can download with one line. Two classics are VGG16 (simple, deep stack of 3x3 convolutions) and ResNet50 (residual connections, deeper and more accurate).
Loading VGG16 as a Base
Load VGG16 with ImageNet weights but without its classifier head so you can attach your own.
from tensorflow.keras.applications import VGG16
base = VGG16(
weights="imagenet", # download pretrained weights
include_top=False, # drop the 1000-class classifier
input_shape=(224, 224, 3) # standard ImageNet input size
)Understanding the Arguments
weights="imagenet": load pretrained weights instead of random.include_top=False: remove the original dense classifier so you can add yours.input_shape=(224,224,3): height, width, and 3 RGB channels.
Setting include_top=False is what makes the model reusable for a new task.
Freezing the Base
Set base.trainable = False so the pretrained convolutional weights stay fixed during the first training phase. Only your new head will learn.
base.trainable = False
print(len(base.trainable_weights)) # -> 0 when frozenGlobalAveragePooling2D
The base outputs a 3D feature map like (7, 7, 512). GlobalAveragePooling2D averages each channel over its spatial grid, collapsing it to a single vector per channel, here length 512.
It replaces a giant Flatten + Dense, drastically cutting parameters and reducing overfitting.
from tensorflow.keras.layers import GlobalAveragePooling2D
# (batch, 7, 7, 512) -> (batch, 512)
pooled = GlobalAveragePooling2D()(base.output)Adding the Dense Output Head
Attach a Dense layer sized to your number of classes. Use softmax for multi-class or sigmoid for binary.
from tensorflow.keras import layers, Model
x = base.output
x = layers.GlobalAveragePooling2D()(x)
x = layers.Dropout(0.3)(x)
outputs = layers.Dense(10, activation="softmax")(x)
model = Model(inputs=base.input, outputs=outputs)Switching to ResNet50
ResNet50 uses the same API. Its residual (skip) connections let it train much deeper without vanishing gradients, usually giving higher ImageNet accuracy than VGG16 at a similar speed.
from tensorflow.keras.applications import ResNet50
base = ResNet50(
weights="imagenet",
include_top=False,
input_shape=(224, 224, 3)
)
base.trainable = FalseVGG16 vs ResNet50
- VGG16: ~138M params, simple uniform 3x3 stack, heavy memory, easy to understand.
- ResNet50: ~25M params, residual blocks, deeper, usually higher accuracy and lighter.
For most modern transfer-learning tasks ResNet50 is the stronger default.
Matching Preprocessing
Each family has its own preprocess_input. VGG16 subtracts mean RGB values, while ResNet50 uses a similar caffe-style scaling. Always import the one matching your base.
from tensorflow.keras.applications.resnet50 import preprocess_input
x = preprocess_input(image_batch) # required for correct resultsCompiling the Model
With the base frozen, compile and train the head with a normal optimizer.
model.compile(
optimizer="adam",
loss="categorical_crossentropy",
metrics=["accuracy"]
)
model.fit(train_ds, validation_data=val_ds, epochs=10)Inspecting the Architecture
Call model.summary() to confirm the base is frozen (Non-trainable params is large) and only the head is trainable. This sanity check catches setup mistakes early.
model.summary()
# Look at "Trainable params" vs "Non-trainable params"Quick Check
Check your grasp of building a transfer-learning model in Keras.
Recap
You loaded VGG16 and ResNet50 with weights="imagenet", include_top=False, and input_shape=(224,224,3), froze the base with base.trainable=False, pooled features with GlobalAveragePooling2D, and added a Dense output head.
ResNet50 is the stronger default. Next: unfreezing layers to fine-tune.
Frequently asked questions
Is the “Using VGG16 and ResNet50 as Base Models” lesson free?
Yes — the full text of “Using VGG16 and ResNet50 as Base Models” is free to read here on the web, and the Learn AI with Python course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Learn AI with Python course, upgrade to CoddyKit PRO.
What will I learn in “Using VGG16 and ResNet50 as Base Models”?
keras.applications.VGG16(weights='imagenet', include_top=False), adding custom head. You practise Learn AI with Python with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Learn AI with Python?
No prior experience is required. Learn AI with Python on CoddyKit is structured for beginners through advanced learners; this is — lesson 2 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Using VGG16 and ResNet50 as Base Models” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Learn AI with Python lesson?
Yes. Every Learn AI with Python lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Transfer Learning Concepts and Strategies
- Using VGG16 and ResNet50 as Base Models
- Fine-tuning: Unfreezing and Retraining
- MobileNet and EfficientNet for Edge Deployment