seg-models / README.md
Mohamed-ENNHIRI
Solar Panel Segmentation app for HF Spaces
52efd90
---
title: Solar Panel Segmentation
emoji: πŸ“Š
colorFrom: blue
colorTo: green
sdk: streamlit
sdk_version: "1.36.0"
app_file: app.py
pinned: false
---
# Solar Panel Segmentation β€” Model Zoo
Aerial / satellite imagery β†’ binary mask of photovoltaic (PV) panels.
This repo trains and compares **five** semantic-segmentation models on the same solar-panel dataset, ships their checkpoints, runs batch inference over a large image pool, and serves an interactive HTML tool to compare model outputs side-by-side.
---
## What's in here
```
seg_models/
β”œβ”€β”€ final_data/ # Training / validation dataset
β”‚ β”œβ”€β”€ train/{images,masks} # 5,325 image+mask pairs
β”‚ └── val/{images,masks} # 1,331 image+mask pairs
β”œβ”€β”€ final_data.zip # Zipped dataset (~31 MB)
β”‚
β”œβ”€β”€ pv_panel_models/ # 4 "lightweight" baselines + tooling
β”‚ β”œβ”€β”€ cnn_model/ # SegNet (encoder-decoder w/ MaxUnpool)
β”‚ β”œβ”€β”€ unet_model/ # Classic U-Net
β”‚ β”œβ”€β”€ vit_model/ # SegFormer mit-b0 (transformer)
β”‚ β”œβ”€β”€ segformer_b5_model/ # SegFormer mit-b5 (large transformer)
β”‚ β”œβ”€β”€ predict_all.py # Runs all 4 models over a folder of images
β”‚ β”œβ”€β”€ predictions/ # Per-model PNG masks + manifest.json
β”‚ β”œβ”€β”€ source_images -> .../filtered_images # Symlink to inference inputs
β”‚ β”œβ”€β”€ comparison_tool.html # Interactive viewer (per-image, all models)
β”‚ β”œβ”€β”€ model_comparison_dashboard.html # Training-curve dashboard
β”‚ β”œβ”€β”€ model_architectures.html # Architecture explainer page
β”‚ β”œβ”€β”€ generate_dashboard.py # Builds the dashboard from training_logs.txt
β”‚ └── serve.sh # `python -m http.server` wrapper
β”‚
└── hybrid_20_epochs_4ep_stop/ # 5th, heavier model (separate experiment)
β”œβ”€β”€ hybrid_solar_segmenter.py # Hybrid Attention-UNet (ResNet34 + SE + AG)
β”œβ”€β”€ hybrid_solar_segmenter.pth # Trained weights (~335 MB)
β”œβ”€β”€ README.md / WORKFLOW.md # Detailed write-up of this model
β”œβ”€β”€ training_curves.png
└── prediction_*.png # Sample qualitative outputs
```
---
## Dataset
Binary segmentation masks for solar panels, stored as `*.jpg` images paired with `*_mask.png` ground truth. Splits:
| Split | Samples |
|------|--------|
| Train | 5,325 |
| Val | 1,331 |
The 4 baselines train on **128Γ—128** crops; the hybrid model trains on **256Γ—256**. Augmentations: H/V flips, 90Β° rotations, brightness/contrast jitter.
Loss is consistent across all models: **`0.5 * BCE + 0.5 * Dice`** (`CombinedLoss`), with Adam / AdamW optimizers and `ReduceLROnPlateau` or `CosineAnnealingWarmRestarts` schedulers.
---
## The five models
| Model | Architecture | Params | Best Val Dice |
|------|------|------:|------:|
| **SegNet (CNN)** | VGG-style encoder/decoder with stored MaxPool indices for unpooling | 11.8 M | 0.9161 |
| **U-Net** | Classic encoder/decoder with skip-concatenation | ~31 M | 0.9332 |
| **SegFormer mit-b0** | HuggingFace hierarchical transformer (small) | 3.7 M | 0.9251 |
| **SegFormer mit-b5** | HuggingFace hierarchical transformer (large) | 84.6 M | 0.9334 |
| **Hybrid Attention-UNet** | ResNet34 (ImageNet) encoder + SE blocks + Attention Gates + UNet decoder, 256Γ—256 | ~24 M | see `hybrid_20_epochs_4ep_stop/README.md` |
Each baseline directory follows the same layout:
```
<model>/
β”œβ”€β”€ <model>.py # nn.Module definition
β”œβ”€β”€ dataset.py # SolarPanelDataset + augmentations + DataLoaders
β”œβ”€β”€ train.py # Training loop, metrics, best-checkpoint saving
β”œβ”€β”€ requirements.txt
β”œβ”€β”€ checkpoints/
β”‚ β”œβ”€β”€ best_model.pth # State-dict by best val Dice
β”‚ └── training_logs.txt # Per-epoch loss / Dice / IoU / Precision / Recall
└── venv/ # Per-model virtualenv (not all dirs)
```
Metrics tracked: Loss, Accuracy, Precision, Recall, **Dice**, **IoU**.
---
## Inference & comparison tooling
### `predict_all.py`
Loads all four baseline checkpoints, runs each over every JPG in
`pv_panel_models/source_images/` (symlink β†’ `filtered_images`), and writes:
- `predictions/<model_short_name>/<stem>.png` β€” binary mask resized to original image dimensions
- `predictions/manifest.json` β€” index used by the web tool
Currently contains predictions for **15,423 images** per model.
```bash
cd pv_panel_models
python predict_all.py
```
### Web viewer
```bash
./pv_panel_models/serve.sh # default port 8000
# then open:
# http://localhost:8000/comparison_tool.html # per-image side-by-side viewer
# http://localhost:8000/model_comparison_dashboard.html # training curves
# http://localhost:8000/model_architectures.html # architecture explainer
```
The dashboard is regenerated from training logs:
```bash
python pv_panel_models/generate_dashboard.py
```
---
## Reproducing a model
Each baseline is self-contained. From its directory:
```bash
pip install -r requirements.txt
python train.py
```
Train scripts hard-code dataset paths to the original author's `~/Desktop/seg_models/...` location β€” update the `train_dir` / `val_dir` (or `train_images` / `train_masks` in the hybrid script) to point at this repo's `final_data/` before running.
The hybrid model additionally requires `scikit-learn` and `matplotlib` and downloads ImageNet ResNet34 weights on first run.
---
## Notes
- The `.venv/` at the repo root and the per-model `venv/` directories are local environments β€” not portable; recreate from `requirements.txt`.
- `final_data.zip` is the same dataset as `final_data/` packaged for distribution.
- Hard-coded absolute paths under `/home/mohamed-ennhiri/Desktop/...` appear in several scripts; expect to patch them when running on a fresh machine.