Clasificador de riesgo de incendio forestal por zona usando el dataset D-Fire. Dado una imagen de una zona, predice el nivel de riesgo: ninguno / bajo / medio / alto.
| Clase | Nivel | Criterio |
|---|---|---|
| 0 | ninguno | Sin fuego ni humo, menos del 30% de vegetación combustible visible |
| 1 | bajo | Sin fuego ni humo, 30–70% de vegetación combustible |
| 2 | medio | Solo humo (sin fuego), o sin incidente pero con ≥70% de vegetación densa |
| 3 | alto | Fuego presente en la imagen |
El dataset D-Fire contiene imágenes con anotaciones en formato YOLO:
- Clase
0→ fuego - Clase
1→ humo
| Split | Imágenes |
|---|---|
| Train | 16.768 |
| Test | 4.306 |
El pipeline se divide en dos fases separadas:
[imágenes + labels YOLO]
↓
Fase 1: etiquetador
(SegFormer + reglas)
↓
risk_labels_{train,test}.csv
↓
Fase 2: entrenar ResNet50
↓
modelo final (best.pth)
Las etiquetas de riesgo no existen en el dataset original. Se generan automáticamente con el script scripts/generate_risk_labels.py usando la siguiente lógica:
1. Leer label YOLO de la imagen
2. Si contiene clase 0 (fuego) → ALTO
3. Si contiene solo clase 1 (humo) → MEDIO
4. Si label vacío → pasar por SegFormer:
calcular pct_veg = área (tree + grass + plant + field) / total píxeles
si pct_veg ≥ 0.70 → MEDIO
si pct_veg ≥ 0.30 → BAJO
si pct_veg < 0.30 → NINGUNO
Para las imágenes sin fuego ni humo se usa SegFormer-B0 pre-entrenado en ADE20K (nvidia/segformer-b0-finetuned-ade-512-512) para segmentar la escena y calcular qué porcentaje de la imagen corresponde a vegetación combustible.
Las clases de ADE20K consideradas combustibles son: tree, grass, plant, field.
Esto permite distinguir, por ejemplo, entre una zona urbana (bajo riesgo aunque no haya fuego) y un bosque denso (alto potencial de propagación).
# En el PC con GPU:
python scripts/generate_risk_labels.py \
--images-dir train/images \
--labels-dir train/labels \
--output risk_labels_train.csv \
--device cuda
python scripts/generate_risk_labels.py \
--images-dir test/images \
--labels-dir test/labels \
--output risk_labels_test.csv \
--device cudaSe entrena ResNet50 (pre-entrenado en ImageNet) con la cabeza de clasificación reemplazada para 4 clases.
- Loss: CrossEntropyLoss con
class_weightscalculados automáticamente (inversamente proporcionales a la frecuencia de cada clase) para compensar el desbalance del dataset. - Optimizador: Adam, lr=1e-4
- Data augmentation: RandomHorizontalFlip + ColorJitter
- Mejor checkpoint: guardado por F1 macro en validación
python -m pytorch_custom.train_risk_classifier \
--train-csv risk_labels_train.csv \
--val-csv risk_labels_test.csv \
--epochs 10 \
--batch-size 32 \
--device cudaEl modelo se guarda en runs/risk_classifier/best.pth.
python -m pytorch_custom.evaluate_risk \
--test-csv risk_labels_test.csv \
--checkpoint runs/risk_classifier/best.pth \
--device cudaGenera:
- Accuracy global y F1 macro
- F1, precision y recall por clase
- Matriz de confusión (
confusion_matrix.png)
El notebook risk_classifier_pipeline.ipynb permite evaluar el modelo entrenado sin necesidad de instalar nada localmente.
- Matriz de confusión absoluta y normalizada
- Curvas ROC one-vs-rest por clase
- Distribución de confianza por clase (correcto vs incorrecto)
- Gráfico de Precision/Recall/F1 por clase
- Grid de ejemplos de predicciones correctas e incorrectas
- Inferencia sobre imagen individual con barra de probabilidades
- Subir a Google Drive:
test/images/con las imágenes del set de testrisk_labels_test.csvgenerado en Fase 1best.pthentrenado en Fase 2
- Ajustar las rutas en la celda de configuración del notebook
- Ejecutar todas las celdas de arriba a abajo
D-Fire/
├── train/ # Dataset de entrenamiento (no en git)
│ ├── images/
│ └── labels/ # Labels YOLO (0=fuego, 1=humo)
├── test/
│ ├── images/
│ └── labels/
├── pytorch_custom/
│ ├── dataset.py # DFireRiskDataset (lee CSV de riesgo)
│ ├── model.py # ResNet50 clasificador de 4 clases
│ ├── risk_labeling.py # Reglas puras de etiquetado
│ ├── vegetation.py # SegFormer wrapper
│ ├── train_risk_classifier.py # Script de entrenamiento
│ └── evaluate_risk.py # Script de evaluación
├── scripts/
│ └── generate_risk_labels.py # Fase 1: genera CSVs de etiquetas
├── tests/ # Tests unitarios (corren sin GPU)
├── risk_classifier_pipeline.ipynb # Notebook de evaluación (Colab)
├── docs/
│ └── superpowers/
│ ├── specs/ # Documento de diseño
│ └── plans/ # Plan de implementación
└── requirements.txt
git clone https://github.com/03Pablo03/D-Fire.git
cd D-Fire
pip install -r requirements.txtLos tests están diseñados para correr sin GPU ni SegFormer (los modelos pesados se mockean):
python -m pytest tests/ -v --ignore=tests/test_dataset.py