TensorFlow MobileNetV2 vs ResNet50: Image Classification with Pretrained Models
Introduction: TensorFlow Image Classification with MobileNetV2 and ResNet50 using mobilenetv2 tensorflow
This tutorial shows how to perform TensorFlow image classification using Keras pretrained models—specifically MobileNetV2 and ResNet50—without any additional training with mobilenetv2 tensorflow.
You’ll learn how to load a single image, preprocess it to the expected input shape, run inference against ImageNet weights, and translate the numeric outputs into human-readable labels using decode_predictions
.
We’ll begin by demonstrating the workflow with ResNet50 in principle (you’ll see the commented line in the code that toggles this), and then switch to MobileNetV2 to compare behavior, speed, and results using mobilenetv2 tensorflow.
By the end, you will have a clean, copy-paste-ready pipeline you can adapt to your own images, plus guidelines on when to pick MobileNetV2 vs ResNet50 for production or experimentation.
The link for the video : https://youtu.be/40_NC2Ahs_8&list=UULFTiWJJhaH6BviSWKLJUM9sg
Link for the full code : https://ko-fi.com/s/32570663e8
Link for my blog (more tutorials) : https://eranfeit.net/blog/
Choosing a Pretrained Model (ResNet50 vs MobileNetV2)
Introduction
Selecting the right pretrained model is a balance between inference speed, model size, and accuracy. ResNet50 is a classic high-capacity backbone with strong accuracy on ImageNet. MobileNetV2 is lightweight and optimized for speed and resource-constrained environments. The code below includes both options so you can toggle between them with a single uncomment.
Elaborated description
First, note the commented line #resnet = tf.keras.applications.resnet50.ResNet50()
. This indicates Phase 1: trying ResNet50. In this phase, you would instantiate the ResNet50 model and use tf.keras.applications.resnet50.preprocess_input
during preprocessing, followed by resnet.predict(...)
to generate logits.
In Phase 2, we switch to MobileNetV2 with tf.keras.applications.mobilenet_v2.MobileNetV2()
. This reduces parameters and speeds up inference significantly, which is especially useful on CPUs, laptops, or edge devices. The trade-off is that MobileNetV2’s top-1 accuracy is slightly below heavier backbones—but often “good enough” for many applications.
When you architect production pipelines, consider inference budget (latency), memory constraints, and expected traffic. If your service handles thousands of requests per minute or runs on devices with limited compute, MobileNetV2 often wins. If you need a bit more accuracy and can afford more compute, ResNet50 is a dependable baseline.
The key is that both integrate seamlessly via Keras Applications, so you can experiment and benchmark without rewriting your tooling. That’s what makes this tutorial portable and maintainable.
### Import TensorFlow for deep learning operations and pretrained models. import tensorflow as tf ### Import NumPy for numerical arrays and dimension manipulation. import numpy as np ### Import Matplotlib for optional visualization of the input image. import matplotlib.pyplot as plt ### Import OpenCV (optional) if you plan to do additional image I/O or transforms. import cv2 ### Import PIL helpers via Keras preprocessing utilities later for image loading. from PIL import Image ### Define the local path to the image you want to classify. filename = 'C:/GitHub/Object-Detection/TensorFlowKeras-PreTrainedModels/dog2.jpg' ### Phase 1 option: instantiate ResNet50 (commented by default to show phase switching). #resnet = tf.keras.applications.resnet50.ResNet50() ### Phase 2 option: instantiate MobileNetV2 (lightweight and fast). mobile = tf.keras.applications.mobilenet_v2.MobileNetV2()
Link for the full code : https://ko-fi.com/s/32570663e8
You now have both models available. Start with ResNet50 by uncommenting the ResNet line, or stick with MobileNetV2 to prioritize speed. The remainder of the pipeline is identical except for the preprocessing function and which model’s predict
you call.
Loading and Preprocessing the Image
Introduction
Pretrained ImageNet models expect images in a specific size and pixel distribution. For ResNet50 and MobileNetV2, the common input shape is (224, 224, 3). Keras provides convenient utilities to load, resize, and format images for model consumption.
Elaborated description
We use image.load_img(..., target_size=(224,224))
to ensure the image matches the model’s input resolution. Then image.img_to_array(img)
converts the PIL image to a NumPy array so TensorFlow can process it.
Neural networks operate on batches of images. Even if you classify a single image, we expand its dimensions from (224, 224, 3)
to (1, 224, 224, 3)
using np.expand_dims(..., axis=0)
.
Crucially, each model family expects a specific preprocessing routine. ResNet50 and MobileNetV2 use different normalization schemes. For ResNet50, use tf.keras.applications.resnet50.preprocess_input
. For MobileNetV2, use tf.keras.applications.mobilenet_v2.preprocess_input
. Mixing these up can degrade predictions.
By keeping both preprocessing lines in the code (with one commented), you can toggle models safely and reproducibly.
### Import Keras image utilities for loading and converting images. from tensorflow.keras.preprocessing import image ### Load the image from disk and resize to the expected 224x224 resolution. img = image.load_img(filename, target_size=(224, 224)) # the model works with 224x224 resolution ### Convert the PIL image to a NumPy array (H, W, C). resizedImage = image.img_to_array(img) ### Print the shape to verify the resize step worked as expected. print("Risized image shape") print(resizedImage.shape) ### Expand dimensions so the array represents a batch of size 1 (N, H, W, C). imageWithMoreDimantion = np.expand_dims(resizedImage, axis=0) ### Print the new shape to confirm batching. print("imageWithMoreDimantion image shape") print(imageWithMoreDimantion.shape) ### PREPROCESS for ResNet50 (use this if you enabled ResNet50 above). #finalImage = tf.keras.applications.resnet50.preprocess_input(imageWithMoreDimantion) ### PREPROCESS for MobileNetV2 (use this if you enabled MobileNetV2 above). finalImage = tf.keras.applications.mobilenet_v2.preprocess_input(imageWithMoreDimantion)
Link for the full code : https://ko-fi.com/s/32570663e8
Your single image is now a properly shaped, normalized batch ready for inference. Remember: match the preprocessing to the model family—that small detail preserves accuracy.
Running Inference and Decoding Predictions
Introduction
With the preprocessed tensor, inference is a single function call. The model outputs class probabilities over 1,000 ImageNet categories. We then use decode_predictions
to map the top scores into readable labels.
Elaborated description
For ResNet50, call resnet.predict(finalImage)
. For MobileNetV2, call mobile.predict(finalImage)
. Both return a (1, 1000)
array of scores.decode_predictions
converts those scores into (class_id, class_name, probability)
tuples, sorted by confidence. This helps you quickly interpret whether the model recognized your object (e.g., a dog breed) correctly.
If you want more granular control, you can inspect predictions[0]
, find np.argmax
, or adjust top-k results to show more candidates.
In production, you might log raw scores for auditing and track top-k accuracy across diverse inputs to monitor model drift.
### Run inference using the selected model. ### If you enabled ResNet50 above, use: #predictions = resnet.predict(finalImage) ### If you enabled MobileNetV2 above, use: predictions = mobile.predict(finalImage) ### Import ImageNet utilities for mapping numeric outputs to human-readable labels. from tensorflow.keras.applications import imagenet_utils ### Decode the predictions to get (class_id, class_name, probability) tuples. results = imagenet_utils.decode_predictions(predictions) ### Print the decoded results to the console. print('Results :') print(results)
Link for the full code : https://ko-fi.com/s/32570663e8
You now have interpretable predictions from a pretrained ImageNet model. The top entries should reflect the object category in your image. If confidence is low, try a clearer image or experiment with the other backbone.
Visualizing the Input (and Interpreting Results)
Introduction
Although the model doesn’t require visualization, plotting the input helps verify that you loaded and resized the correct image. It’s also useful when you iterate on multiple test images and want quick visual feedback.
Elaborated descriptionplt.imshow(img)
displays the resized image that was passed to the model. If colors appear off, verify your image loading and preprocessing.
For reporting, you can overlay the top prediction on the plot title (e.g., plt.title(results[0][0][1])
) to make screenshots self-contained.
If you plan further post-processing—like drawing bounding boxes or saliency maps—you’ll likely leverage OpenCV or Grad-CAM utilities, which plug neatly into this pipeline.
Finally, consider saving both the raw predictions and the plotted image for reproducibility and to build a lightweight evaluation set over time.
### Visualize the input image to confirm correct loading and resizing. plt.imshow(img) ### Render the plot window (or inline cell) so you can see the image. plt.show()
Link for the full code : https://ko-fi.com/s/32570663e8
A quick visualization step improves trust and debuggability. It ensures what you think you classified is exactly what the model saw.
Practical Comparison: When to Use ResNet50 vs MobileNetV2
Introduction
Both backbones are strong baselines for tensorflow image classification. Your choice depends on deployment constraints and accuracy requirements.
Elaborated description
- Speed & Size: MobileNetV2 is typically faster and smaller—ideal for laptops, CPUs, and edge devices.
- Accuracy: ResNet50 often edges out MobileNetV2 on top-1 accuracy—useful when you can afford extra compute.
- Preprocessing: Always use the matching preprocessing function to avoid silent performance drops.
- Production fit: Benchmark both on your target hardware and real images. Latency budgets, throughput targets, and energy constraints usually decide the winner.
Connect :
☕ Buy me a coffee — https://ko-fi.com/eranfeit
🖥️ Email : feitgemel@gmail.com
🤝 Fiverr : https://www.fiverr.com/s/mB3Pbb
Enjoy,
Eran