Introduction
MobileNet v3 is a lightweight neural network architecture optimized for mobile and edge devices. Combined with TensorFlow Lite, it enables real-time object detection on smartphones, IoT devices, and embedded systems with minimal latency and power consumption. MobileNet v3 comes in two variants — Large (higher accuracy) and Small (faster, lower memory) — both suitable for TFLite deployment.
Getting a MobileNet v3 TFLite Model
Option 1: TensorFlow Hub (Pre-trained)
1import tensorflow as tf
2import tensorflow_hub as hub
3
4# Load SSD MobileNet v3 from TF Hub
5model_url = "https://tfhub.dev/tensorflow/lite-model/ssd_mobilenet_v3_large_coco/1/default/1"
6
7# Download the .tflite model directly
8import urllib.request
9urllib.request.urlretrieve(
10 "https://storage.googleapis.com/tfhub-lite-models/tensorflow/lite-model/ssd_mobilenet_v3_large_coco/1/default/1?lite-format=tflite",
11 "ssd_mobilenet_v3.tflite"
12)
Option 2: TensorFlow Model Zoo
Download from the TensorFlow Model Garden:
# SSD MobileNet v3 Large
wget http://download.tensorflow.org/models/object_detection/tf2/ssd_mobilenet_v3_large_coco17_tpu-8.tar.gz
tar xzf ssd_mobilenet_v3_large_coco17_tpu-8.tar.gz
Option 3: Convert a SavedModel to TFLite
1import tensorflow as tf
2
3# Convert SavedModel to TFLite
4converter = tf.lite.TFLiteConverter.from_saved_model('saved_model_dir')
5converter.optimizations = [tf.lite.Optimize.DEFAULT]
6converter.target_spec.supported_types = [tf.float16] # Float16 quantization
7
8tflite_model = converter.convert()
9
10with open('mobilenet_v3_detect.tflite', 'wb') as f:
11 f.write(tflite_model)
Running Inference with Python
1import numpy as np
2from PIL import Image
3import tensorflow as tf
4
5# Load the TFLite model
6interpreter = tf.lite.Interpreter(model_path='ssd_mobilenet_v3.tflite')
7interpreter.allocate_tensors()
8
9# Get input/output details
10input_details = interpreter.get_input_details()
11output_details = interpreter.get_output_details()
12
13# Prepare input image
14image = Image.open('test_image.jpg').resize(
15 (input_details[0]['shape'][2], input_details[0]['shape'][1])
16)
17input_data = np.expand_dims(np.array(image), axis=0)
18
19# Handle uint8 or float32 input
20if input_details[0]['dtype'] == np.uint8:
21 input_data = input_data.astype(np.uint8)
22else:
23 input_data = (input_data / 255.0).astype(np.float32)
24
25# Run inference
26interpreter.set_tensor(input_details[0]['index'], input_data)
27interpreter.invoke()
28
29# Get results
30boxes = interpreter.get_tensor(output_details[0]['index'])[0] # Bounding boxes
31classes = interpreter.get_tensor(output_details[1]['index'])[0] # Class IDs
32scores = interpreter.get_tensor(output_details[2]['index'])[0] # Confidence scores
33count = int(interpreter.get_tensor(output_details[3]['index'])[0]) # Number of detections
34
35# Filter by confidence threshold
36threshold = 0.5
37for i in range(count):
38 if scores[i] >= threshold:
39 ymin, xmin, ymax, xmax = boxes[i]
40 class_id = int(classes[i])
41 print(f"Object: class={class_id}, score={scores[i]:.2f}, "
42 f"box=({xmin:.3f}, {ymin:.3f}, {xmax:.3f}, {ymax:.3f})")
Android Deployment
Add TFLite Dependency
1// build.gradle
2dependencies {
3 implementation 'org.tensorflow:tensorflow-lite:2.14.0'
4 implementation 'org.tensorflow:tensorflow-lite-support:0.4.4'
5}
Kotlin Inference Code
1import org.tensorflow.lite.Interpreter
2import java.nio.ByteBuffer
3
4class ObjectDetector(private val modelPath: String, context: Context) {
5
6 private val interpreter: Interpreter
7
8 init {
9 val model = loadModelFile(context, modelPath)
10 interpreter = Interpreter(model)
11 }
12
13 fun detect(bitmap: Bitmap): List<Detection> {
14 val input = preprocessImage(bitmap, 320, 320)
15 val boxes = Array(1) { Array(10) { FloatArray(4) } }
16 val classes = Array(1) { FloatArray(10) }
17 val scores = Array(1) { FloatArray(10) }
18 val count = FloatArray(1)
19
20 val outputs = mapOf(
21 0 to boxes, 1 to classes, 2 to scores, 3 to count
22 )
23 interpreter.runForMultipleInputsOutputs(arrayOf(input), outputs)
24
25 return (0 until count[0].toInt())
26 .filter { scores[0][it] > 0.5f }
27 .map { Detection(classes[0][it].toInt(), scores[0][it], boxes[0][it]) }
28 }
29}
Quantize the model for faster inference on mobile:
1# Full integer quantization
2converter = tf.lite.TFLiteConverter.from_saved_model('saved_model_dir')
3converter.optimizations = [tf.lite.Optimize.DEFAULT]
4
5def representative_dataset():
6 for _ in range(100):
7 yield [np.random.rand(1, 320, 320, 3).astype(np.float32)]
8
9converter.representative_dataset = representative_dataset
10converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8]
11converter.inference_input_type = tf.uint8
12converter.inference_output_type = tf.uint8
13
14tflite_quant_model = converter.convert()
| Quantization | Model Size | Speed | Accuracy |
| Float32 | ~25 MB | Baseline | Best |
| Float16 | ~12 MB | ~1.5x faster | Near-identical |
| INT8 | ~6 MB | ~2-3x faster | Slight loss |
Real-World Applications
Real-Time Video Analysis: Detect and classify objects in camera feeds on mobile devices
IoT Devices: Deploy on smart cameras, drones, and robotics for edge inference
Mobile Applications: Enable apps to recognize products, read text, or identify objects offline
Retail: Shelf monitoring, checkout-free shopping, and inventory tracking
Common Pitfalls
Input size mismatch: MobileNet v3 models expect specific input sizes (typically 320x320 or 224x224). Resize images to match input_details[0]['shape'] exactly.
Output tensor order: Different TFLite models may order output tensors differently (boxes, classes, scores, count). Always check output_details rather than hardcoding indices.
Quantization calibration: INT8 quantization requires a representative dataset that covers your actual input distribution. Random data for calibration produces poor accuracy.
NNAPI/GPU delegate: Enable hardware acceleration on Android with Interpreter.Options().addDelegate(NnApiDelegate()) for 2-5x speedup, but test compatibility as not all ops are supported.
COCO class IDs: Pre-trained models use COCO dataset class IDs (1-90, not 0-89). Map IDs to labels using the COCO label file.
Summary
MobileNet v3 + TFLite enables real-time object detection on mobile and edge devices
Use pre-trained models from TF Hub or Model Zoo, or convert your own with TFLiteConverter
Quantize to INT8 for 2-3x speed improvement with minimal accuracy loss
Always verify input size and output tensor order from the model's metadata
Enable GPU/NNAPI delegates on Android for hardware-accelerated inference