ChandraPrakashBathula's picture
Update README.md
dc92b7e verified
|
Raw History Blame Contribute Delete
4.76 kB
---
title: Intel Scene CNN
emoji: πŸ”οΈ
colorFrom: blue
colorTo: green
sdk: gradio
sdk_version: 5.9.1
app_file: app.py
pinned: false
license: mit
---
# Intel Scene Classification: a CNN built from scratch
A plain convolutional neural network (no ResNet, no pretrained weights) trained on the
[Intel Image Classification](https://www.kaggle.com/datasets/puneet6060/intel-image-classification)
dataset: ~25k natural scene photos in 6 classes: **buildings, forest, glacier, mountain, sea, street**.
This is the follow-up to my EuroSAT satellite CNN. It tests whether the same architecture
generalizes to street-level photos, where orientation matters and the classes overlap visually.
**Live demo:** upload an image, get the predicted class and a Grad-CAM heatmap, plus the test metrics.
## Results
| Metric | Value |
|---|---|
| Test accuracy (seg_test, 3,000 images) | **89.87%** |
| Macro F1 | **0.900** |
| Best validation accuracy | **90.98%** |
| Parameters | **1,206,886** |
| Class | Precision | Recall | F1 | Test images |
|---|---|---|---|---|
| buildings | 0.913 | 0.860 | 0.886 | 437 |
| forest | 0.979 | 0.985 | 0.982 | 474 |
| glacier | 0.846 | 0.866 | 0.856 | 553 |
| mountain | 0.876 | 0.830 | 0.852 | 525 |
| sea | 0.895 | 0.937 | 0.916 | 510 |
| street | 0.897 | 0.918 | 0.907 | 501 |
**Where it fails:** mountain β†’ glacier (65), buildings β†’ street (46), glacier β†’ mountain (46),
street β†’ buildings (29). Almost all errors come from two pairs: snow-covered peaks vs. glaciers,
and urban scenes where a photo of a street is also a photo of buildings. Forest is near-perfect
(98% F1) because its texture and color are unique. Several high-confidence "mistakes" are
labeling errors in the dataset itself.
![Confusion matrix](images/11_confusion_matrix.png)
![Per-class accuracy](images/12_per_class_accuracy.png)
![Training curves](images/10_curves.png)
## Dataset
| Split | Images |
|---|---|
| seg_train β†’ train (85%) | ~11,900 |
| seg_train β†’ validation (15%, stratified) | ~2,100 |
| seg_test (held-out test) | 3,000 |
| seg_pred (unlabeled) | ~7,300 |
![Samples](images/01_samples.png)
![Class distribution](images/02_class_distribution.png)
![Average color per class](images/03_class_colors.png)
## Architecture
```mermaid
flowchart LR
A[Input 3Γ—128Γ—128] --> B1[Block 1<br/>32ch β†’ 64Γ—64]
B1 --> B2[Block 2<br/>64ch β†’ 32Γ—32]
B2 --> B3[Block 3<br/>128ch β†’ 16Γ—16]
B3 --> B4[Block 4<br/>256ch β†’ 8Γ—8]
B4 --> G[Global Avg Pool<br/>256]
G --> F1[Dropout 0.4 β†’ FC 128 β†’ ReLU]
F1 --> F2[FC 6 β†’ softmax]
```
Each block is `Conv3Γ—3 β†’ BN β†’ ReLU β†’ Conv3Γ—3 β†’ BN β†’ ReLU β†’ MaxPool 2Γ—2 β†’ Dropout2d(0.1)`.
| Stage | Output shape |
|---|---|
| Input | 3 Γ— 128 Γ— 128 |
| Block 1 | 32 Γ— 64 Γ— 64 |
| Block 2 | 64 Γ— 32 Γ— 32 |
| Block 3 | 128 Γ— 16 Γ— 16 |
| Block 4 | 256 Γ— 8 Γ— 8 |
| Global average pool | 256 |
| FC + ReLU | 128 |
| FC (logits) | 6 |
## Training setup
- **Optimizer:** AdamW (lr 1e-3, weight decay 1e-2), cosine LR schedule, 30 epochs
- **Loss:** cross-entropy with label smoothing 0.1
- **Image size:** 128Γ—128, normalized with per-channel stats computed from the training data
- **Augmentation:** random resized crop (0.75–1.0), horizontal flip, Β±10Β° rotation, mild color jitter
- **No vertical flips or large rotations.** Scenes have gravity (sky on top), unlike satellite images.
- **Model selection:** best validation accuracy checkpoint
![Augmentation](images/04_augmentation.png)
![Bad augmentation](images/05_bad_augmentation.png)
## What the CNN learns
**Feature maps before vs. after training**
![Before](images/06_feature_maps_before.png)
![After](images/08_feature_maps_after.png)
**First-layer filters before vs. after training**
![Filters before](images/07_filters_before.png)
![Filters after](images/09_filters_after.png)
**Grad-CAM: where the network looks**
![Grad-CAM](images/15_gradcam.png)
![Grad-CAM on mistakes](images/16_gradcam_mistakes.png)
**Confidence and mistakes**
![Confidence](images/13_confidence.png)
![Mistakes](images/14_mistakes.png)
![Unlabeled predictions](images/17_unlabeled_predictions.png)
## Run locally
```bash
pip install -r requirements.txt gradio
python app.py
```
## Files
| File | Purpose |
|---|---|
| `app.py` | Gradio app: upload, prediction, Grad-CAM, metrics, plots |
| `model.py` | `SceneCNN` architecture + Grad-CAM |
| `cnn_intel.pth` | Trained weights (state_dict) |
| `cnn_intel_meta.json` | Class names, normalization stats, width, image size |
| `metrics.json` | Test metrics shown in the app |
| `images/` | All plots from training and evaluation |
## Author
Chandra Prakash Bathula, Adjunct Faculty, Saint Louis University (School for Professional Studies)