--- 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
32ch → 64×64] B1 --> B2[Block 2
64ch → 32×32] B2 --> B3[Block 3
128ch → 16×16] B3 --> B4[Block 4
256ch → 8×8] B4 --> G[Global Avg Pool
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)