This repository implements fruit image classification using TensorFlow/Keras with two complementary approaches:
-
Custom CNN Baseline - A from-scratch CNN achieving ~90% test accuracy
-
Transfer Learning - MobileNetV2 fine-tuned on fruit data, achieving 96.67% test accuracy
The project demonstrates how transfer learning with pretrained ImageNet features outperforms custom training on small datasets (310 images).
It includes data augmentation, class imbalance handling, and detailed evaluation with confusion matrices and classification reports.
The mixed fruit class is identified as the most challenging, with 60% recall in the transfer-learning model.
I trained two different approaches on the same fruit dataset:
- A custom CNN baseline in
cnn_image_classifier_fruits_v2.py - A transfer-learning version in
cnn_fruits_transfer.py
The baseline keeps the model fully custom and is useful as a simple, from-scratch reference.
The transfer-learning version starts from MobileNetV2 pretrained on ImageNet, then fine-tunes it for this fruit task.
The cleaned dataset is prepared from Train_final/ and test/.
- Train: 174 images (56.1%)
- Validation: 76 images (24.5%)
- Test: 60 images (19.4%)
- Total: 310 images
This is roughly a 7:3:2 split across train, validation, and test after rounding. I used this ratio because it keeps most images for learning, while still leaving enough data to check whether the model is improving during training and enough untouched test data for a fair final evaluation.
Class split:
- Train: apple 52, banana 51, mixed 20, orange 51
- Validation: apple 23, banana 22, mixed 9, orange 22
- Test: apple 19, banana 18, mixed 5, orange 18
- Best observed test accuracy: 90.00%
- Latest regenerated chart run: 88.33%
- This was my from-scratch baseline, so it is the clean reference for what the dataset alone can support without pretrained features.
- Reaching
90.00%at best shows the custom CNN learned the main fruit categories well and was already a strong result for a small dataset. - On the latest rerun, the model correctly classified
53out of60test images. - The baseline was strongest on
appleandorange, stayed solid onbanana, and struggled most onmixed. - The
mixedclass had0.4000recall in the regenerated run, which means it only found2out of5mixed images.
In plain terms, the baseline model worked well on the clearer single-fruit images, but it was less reliable on the more ambiguous mixed-fruit examples. That is why the overall result was good, but not yet as consistent as the transfer-learning version.
- Test accuracy: 96.67%
- Macro F1: 0.9240
mixedrecall: 0.6000- This version reused a pretrained
MobileNetV2backbone, so it started with strong general image features instead of learning everything from scratch. - It correctly classified
58out of60test images, which is a clear step up from the custom CNN baseline. - The macro F1 score of
0.9240shows the model performed well across all four classes, not just the easiest ones. - It achieved perfect recall on
apple,banana, andorangein the regenerated report. mixedrecall improved to0.6000, which means it found3out of5mixed images and handled the hardest class better than the baseline.
In plain terms, 96.67% means the model got almost all of the test fruit images right. Out of 60 unseen images, it only missed 2, so it was making the correct choice almost every time. That is a strong sign that the model is not just memorizing the training data, but actually learning patterns it can use on new images.
I started with a custom CNN because I wanted a clean baseline that learned everything from the fruit dataset itself. That gave me a solid reference point, but the dataset was small and the mixed class was still the hardest case.
From there, I tried a second path: transfer learning with a pretrained MobileNetV2 backbone. The idea was to reuse general visual features the model had already learned on ImageNet, then fine-tune it on my four fruit classes.
That change is what lifted the final result. The custom CNN reached a strong baseline, but the transfer-learning version generalized better and pushed test accuracy up to 96.67%.
cnn_image_classifier_fruits_v2.py: custom CNN baselinecnn_fruits_transfer.py: MobileNetV2 transfer-learning experimentartifacts/baseline/: saved baseline model and plotsartifacts/transfer/: saved transfer model and plotsTrain_final/andtest/: raw image foldersarchive/: old scripts, notes, and scratch files kept out of the main workflow
- Training augmentation is applied only to the training generator.
- Validation and test data are kept separate from augmentation.
- The test set is treated as the final untouched evaluation set.
- The transfer-learning run writes its plots to
artifacts/transfer/and its checkpoint toartifacts/transfer/checkpoints/. - The scripts generate training curves, accuracy curves, and confusion matrices when you run them locally.
These below results shows the difference between using a baseline CNN that I have programmed vs applying transfer learning with MobileNet to my CNN.
The loss charts show whether the model is improving over training, while the accuracy charts show how often predictions are correct, and the confusion matrices show which fruit classes the model still mixes up. The transfer-learning plots are stronger overall, which matches its better final test result.





