Image classification of natural scenes into 6 classes (buildings, forest, glacier, mountain, sea, street) built with TensorFlow / Keras. The project compares a custom CNN baseline against a MobileNetV2 transfer-learning model with two-phase fine-tuning, and exports the final model to three deployment formats: SavedModel, TensorFlow Lite, and TensorFlow.js.
| Model | Train Acc | Val Acc | Test Acc |
|---|---|---|---|
| Baseline CNN (from scratch) | 91.93% | 89.20% | 87.57% |
| MobileNetV2 (transfer learning) | 95.24% | 94.83% | 93.38% |
Transfer learning with two-phase fine-tuning substantially improves generalization over the from-scratch baseline while producing a smaller, deployment-friendly model.
- Source: Intel Image Classification — Kaggle
- Size: ~17,000 images (
seg_train+seg_testcombined) - Classes (6): buildings, forest, glacier, mountain, sea, street
- Resolution: non-uniform (no fixed resolution in the source) — see EDA in the notebook for the resolution distribution analysis.
The provider's original split is not used. All images are pooled per class and re-split manually with random_state=42 for reproducibility:
| Split | Ratio |
|---|---|
| Train | 80% |
| Validation | 10% |
| Test | 10% |
1. Baseline — Custom CNN. Four Conv2D + BatchNorm + MaxPooling + Dropout blocks (filters 32 → 64 → 128 → 256), GlobalAveragePooling2D, then a dense softmax head. Trained from scratch as a reference point.
2. Transfer Learning — MobileNetV2 (final model).
- Phase 1 — Feature extraction: ImageNet-pretrained backbone frozen; only the classification head is trained (
lr = 1e-3). - Phase 2 — Fine-tuning: the top third of the backbone is unfrozen and trained with a very small learning rate (
lr = 1e-5) so pretrained features adapt without being destroyed. Backbone BatchNorm layers are kept in inference mode for stability.
Training details
- Input size
224×224, batch size32. - Preprocessing via
mobilenet_v2.preprocess_input(range[-1, 1]). - Augmentation (training only): rotation, width/height shift, shear, zoom, horizontal flip.
- Callbacks:
EarlyStopping,ModelCheckpoint,ReduceLROnPlateau.
.
├── notebook.ipynb # End-to-end pipeline: EDA → training → eval → export → inference
├── README.md
├── requirements.txt
├── .gitignore
└── models/
├── saved_model/ # TensorFlow SavedModel
├── tfjs_model/ # TensorFlow.js
└── tflite/ # TensorFlow Lite (+ label.txt)
The dataset is downloaded at runtime from Kaggle and is not committed to the repo.
The notebook is designed for Google Colab (T4 GPU).
- Open
notebook.ipynbin Colab and select a GPU runtime. - Provide Kaggle credentials when prompted — either via Colab Secrets (
KAGGLE_USERNAME,KAGGLE_KEY) or by uploadingkaggle.json. Credentials are never hard-coded. Runtime → Run all.
To run locally:
pip install -r requirements.txt
jupyter notebook notebook.ipynb| Format | File | Use case |
|---|---|---|
| SavedModel | models/saved_model/ |
TensorFlow Serving / production backends |
| TF-Lite | models/tflite/model.tflite |
Mobile & edge devices (dynamic-range quantized) |
| TensorFlow.js | models/tfjs_model/model.json |
In-browser inference |
Class labels: models/tflite/label.txt.
Python · TensorFlow / Keras · MobileNetV2 · scikit-learn · NumPy · Matplotlib · Seaborn · TensorFlow.js · TensorFlow Lite
Muhammad Fariz Abizar
Released under the MIT License — see LICENSE.