--- license: mit tags: - solar-energy - image-classification - photovoltaic - dust-detection - efficientnet - svm - explainable-ai datasets: - safwanshamsir99/solar-photovoltaics-panell-for-dust-dectection library_name: scikit-learn pipeline_tag: image-classification metrics: - accuracy - roc_auc model-index: - name: solar-panel-dust-xai results: - task: type: image-classification name: Solar panel clean vs dirty metrics: - type: accuracy value: 0.9029 name: Test Accuracy (merged held-out) - type: roc_auc value: 0.9596 name: AUC-ROC - type: accuracy value: 0.9824 name: External accuracy (2,562 imgs) - type: accuracy value: 0.9974 name: External accuracy (383 imgs) --- # Solar Panel Dust Detection with Explainable AI Hybrid **EfficientNet-B2 (frozen) + RBF-SVM** model for classifying a single RGB image of a photovoltaic (PV) panel as **clean** or **dirty**, with a focus on cross-dataset generalisation and explainability (Grad-CAM, Score-CAM, Integrated Gradients, SHAP, LIME). ## Model - **Feature extractor**: EfficientNet-B2, ImageNet weights, frozen, global-average pooled → 1,408-d vector. - **Head**: RBF-kernel SVM (`C=10`, `gamma=auto`), `class_weight="balanced"`. - **Architecture is exactly the deployed production model** (version `v007`). | Metric | Value | |--------|-------| | Test accuracy (merged held-out, 381 imgs) | **90.29%** | | AUC-ROC | **0.9596** | | 5-fold CV accuracy | **86.38%** | | External: Dusty/Clean (2,562 imgs) | **98.24%** (98.0% dirty recall) | | External: Faulty-panel clean/dirty (383 imgs) | **99.74%** (100% dirty recall) | ## Files - `svm_classifier.pkl` — trained RBF-SVM head (joblib). - `scaler.pkl` — fitted `StandardScaler` applied to pooled features. - `pipeline_meta.json` — full training metadata and per-metric scores. - `class_names.json` — label order (`["clean", "dirty"]`). - `demo.py` — self-contained inference script. ## Usage ```bash pip install tensorflow scikit-learn joblib numpy pillow python demo.py panel.jpg # print label, confidence, dustiness python demo.py clean.jpg dirty.jpg # batch ``` > The first run downloads the EfficientNet-B2 ImageNet weights (~80 MB) from > TensorFlow via `keras`. ## How it was trained A single-source model overfits one acquisition pipeline and collapses on new data (observed: ~6% dirty recall on external sets). The fix was to **merge three public PV-dust sources** into one 3,787-image corpus and retrain: | Split | Clean | Dirty | Total | |-------|------:|------:|------:| | Train | 1,750 | 1,279 | 3,029 | | Val | 218 | 159 | 377 | | Test | 220 | 161 | 381 | | **All** | 2,188 | 1,599 | **3,787** | The frozen representation + margin-based SVM then transfers far better across acquisition sources (see external-validation metrics above). ## Intended use & limitations - For single-panel RGB inspection; labels are binary (clean/dirty), not severity. - Confidence for every prediction is produced; a configurable confidence threshold can route low-confidence samples to human review. - The backbone is loaded fresh from ImageNet weights at inference (not stored in this repo), matching the deployed frozen-backbone protocol. ## Related Full experimental details, the IEEE-format paper, and the five-method XAI module live in the companion project repo.