Reporte de modelo EfficientNet_B0
Documentación del Modelo EfficientNet-B0
El presente documento tiene como propósito describir el desarrollo y funcionamiento del modelo de clasificación EfficientNet-B0, implementado en el marco del proyecto de colaboración con la Estación Astronómica de Río Grande (EARG). Este modelo constituye uno de los componentes del sistema de inteligencia artificial orientado a la detección automática del nivel de nubosidad (octas) en imágenes del cielo.
El modelo EfficientNet-B0 fue entrenado para identificar, en fotografías del cielo capturadas por la EARG, la cantidad relativa de nubes presentes, expresada en la escala meteorológica de 0 a 8 octas, donde 0 representa un cielo completamente despejado y 8 uno totalmente cubierto.
Su finalidad principal es automatizar la clasificación del estado del cielo a partir de imágenes obtenidas por la EARG, permitiendo reducir el tiempo de análisis manual, estandarizar criterios de observación y generar bases de datos etiquetadas que faciliten estudios posteriores sobre condiciones atmosféricas locales.
La elección de EfficientNet-B0 se realizó tras comparar su desempeño con otros modelos como EfficientNet-B3, B4, B5, VisionMixTransformers y TensorFlow-Kerak. EfficientNet-B0 responde a su eficiencia computacional y capacidad de generalización, características que la convierten en una arquitectura adecuada para entornos con recursos limitados de cómputo.
En este contexto, el modelo constituye una primera instancia dentro de un sistema escalable que busca mejorar la gestión y planificación de las observaciones astronómicas, incorporando progresivamente nuevas fuentes de datos y modelos complementarios, como la detección de nubes noctilucentes y la correlación con variables meteorológicas (radiación solar y vapor de agua), lo que permitirá fortalecer el monitoreo atmosférico automatizado de la estación.
Preparación del Dataset
El conjunto de datos utilizado para el entrenamiento y validación del modelo EfficientNet-B0 corresponde a la carpeta “05.Etiquetado_Final”, ubicada tanto en el repositorio del proyecto en GitHub como en el espacio compartido de Google Drive.
El dataset se organiza en dieciocho carpetas principales, diferenciadas por tipo de iluminación (clara u oscura) y nivel de nubosidad según la escala de 0 a 8 octas:
-
imágenes_clara_octa_0 a imágenes_clara_octa_8
-
imágenes_oscura_octa_0 a imágenes_oscura_octa_8
Esta estructura permite mantener una jerarquía clara para su uso en los procesos de carga y entrenamiento del modelo.
El análisis exploratorio evidenció una distribución desigual entre clases, con mayor cantidad de imágenes en los niveles octa_1 y octa_8, y menor representación en los octa_2, octa_4 y octa_5.
Para la división del conjunto de datos se utilizó la función train_test_split de Scikit-learn, aplicando una proporción 80/20 con estratificación por clase, a fin de mantener la representatividad de cada categoría:
De esta manera, el 80 % de las imágenes se destinó al entrenamiento y el 20 % restante a la validación, garantizando una evaluación equilibrada y coherente del desempeño del modelo.
El dataset se encuentra disponible en las siguientes ubicaciones del proyecto:
-
📦 GitHub: Equipo-4-PP2-ASTRONOMICA-2C-2025 / 01.Data / 02.Processed / 05.Etiquetado_Final
-
☁️ Google Drive: Carpeta 0.6 Dataset → 05.Etiquetado_Final
Manejo del Desbalance de Clases
El conjunto de datos presentó una distribución desigual entre algunas categorías.
Para mitigar este desbalance y mejorar la capacidad del modelo para reconocer todos los niveles de nubosidad, se aplicaron tres estrategias complementarias:
- Cálculo de Pesos de Clase:
Se utilizaron pesos generados mediante la función compute_class_weight de Scikit-learn, con el parámetro class_weight='balanced'.
Estos valores se integraron a la función de pérdida, otorgando mayor penalización a los errores en clases minoritarias, favoreciendo así un aprendizaje más equitativo. - Oversampling Dinámico:
En el conjunto de entrenamiento se implementó un sobreremuestreo selectivo de las clases con menor cantidad de muestras, duplicando imágenes de esas categorías para equilibrar la exposición del modelo durante el entrenamiento. - Focal Loss:
Se implementa y utiliza una función de pérdida llamada FocalLoss, que está diseñada para dar más importancia a los ejemplos difíciles de clasificar, lo cual es común en clases minoritarias. Además, esta implementación de FocalLoss también incorpora los pesos de clase calculados.
Estas estrategias combinadas permitieron reducir el sesgo hacia las clases mayoritarias y mejorar la capacidad del modelo para generalizar en condiciones atmosféricas menos frecuentes.
Transformaciones y Aumento de Datos
Con el objetivo de mejorar la capacidad de generalización del modelo y reducir el sobreajuste, se aplicaron diversas transformaciones al conjunto de entrenamiento mediante las funciones del módulo torchvision.transforms.
Las operaciones incluyeron rotaciones aleatorias (hasta 40°), volteos horizontales, ajustes de brillo y contraste, traslaciones, cizallamientos y simulación de zoom mediante recorte y reescalado. También se incorporó desenfoque gaussiano para aumentar la variabilidad visual.
Las imágenes fueron redimensionadas a 224×224 píxeles y estandarizadas utilizando la media y desviación estándar del dataset ImageNet (mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]), lo que garantiza la compatibilidad con la arquitectura EfficientNet-B0 preentrenada.
Estas técnicas permitieron ampliar artificialmente el conjunto de entrenamiento, generando variaciones realistas que refuerzan la robustez del modelo ante cambios de iluminación, orientación y condiciones atmosféricas.
Arquitectura del Modelo
El modelo implementado se basa en la arquitectura EfficientNet-B0, preentrenada en el dataset ImageNet.
Se optó por habilitar el fine-tuning completo, descongelando todas las capas del modelo (param.requires_grad \= True) para permitir la actualización de pesos durante el entrenamiento y adaptar la red completamente al conjunto de imágenes del proyecto.
En cuanto a la estructura de salida, se mantuvo el clasificador original de EfficientNet, reemplazando únicamente su última capa Linear por una nueva adaptada a la tarea de clasificación de nueve clases (octas 0-8).
La cabeza del modelo consta de una capa Dropout con una probabilidad de desactivación de 0.2 (valor determinado tras múltiples pruebas), seguida de una capa lineal con 9 neuronas, correspondientes a las 9 categorías del problema.
El tamaño de entrada del modelo corresponde a tensores de (3, 224, 224), representando imágenes RGB redimensionadas a 224×224 píxeles.
El modelo se realizó en entorno local con soporte GPU, utilizando el framework PyTorch.
Para el entrenamiento se empleó el optimizador Adam con una tasa de aprendizaje de 1e-5 y un weight_decay de 1e-4.
El tamaño de lote fue de 64 imágenes, configurándose un máximo de 150 épocas y aplicando Early Stopping (paciencia \= 8) para interrumpir el proceso cuando la pérdida de validación dejó de mejorar.
Función de Pérdida y Optimizador
Para el entrenamiento del modelo se implementó una versión personalizada de la Focal Loss, definida como una clase propia dentro del script.
Esta función reemplaza la entropía cruzada estándar y está diseñada para dar mayor peso a los ejemplos difíciles de clasificar, especialmente a las clases minoritarias.
La implementación incorporó explícitamente los pesos de clase (class_weights_tensor) calculados previamente, integrados mediante nn.CrossEntropyLoss(weight=class_weights_tensor), lo que permitió penalizar con mayor severidad los errores en categorías menos representadas. El optimizador utilizado fue Adam, configurado con una tasa de aprendizaje (lr) de 1e-5 y un weight_decay de 1e-4, logrando una convergencia estable durante el fine-tuning.
Además, se implementó un scheduler dinámico (ReduceLROnPlateau), que redujo la tasa de aprendizaje a la mitad (factor=0.5) cuando la pérdida de validación (val_loss) no mejoró en un lapso de cinco épocas consecutivas (patience=5).
Durante el entrenamiento se monitorizaron las métricas de pérdida (loss) y precisión (accuracy) por época.
El criterio de Early Stopping y de guardado del mejor modelo fue la pérdida en validación, deteniéndose el proceso si no se observaban mejoras en val_loss tras ocho épocas.
Proceso de Entrenamiento
El modelo EfficientNet-B0 fue configurado para un máximo de 150 épocas, aunque el entrenamiento se detuvo anticipadamente en la época 80 gracias al mecanismo de Early Stopping, al no observarse mejoras en la pérdida de validación (val_loss) durante las últimas iteraciones.
Los resultados finales obtenidos fueron los siguientes:
| Métrica | Entrenamiento | Validación |
|---|---|---|
| Loss | 0.135154 | 0.271047 |
| Accuracy | 0.749769 (\~75.0%) | 0.676471 (\~67.6%) |
Durante la ejecución, las métricas de rendimiento se registraron mediante tres mecanismos complementarios:
-
Archivo CSV: se almacenó el historial completo de loss, val_loss, accuracy y val_accuracy por época en historial_entrenamiento.csv.
-
Visualización Gráfica: se generó el archivo grafico_aprendizaje_octas.png, que muestra la evolución de las curvas de aprendizaje.
-
Consola: las métricas fueron impresas en tiempo real durante el proceso de entrenamiento.
El ciclo de entrenamiento se implementó en PyTorch mediante un bucle clásico for epoch in range(num_epochs): que ejecutaba al final de cada época un ciclo completo de validación seguido de la actualización del scheduler con scheduler.step(val_loss).
El modelo se guardó automáticamente mediante torch.save() cada vez que alcanzaba un nuevo mínimo de pérdida de validación, asegurando la conservación de la mejor versión entrenada.
El entrenamiento se realizó en un entorno local con GPU compatible con CUDA, lo que permitió optimizar significativamente los tiempos de cómputo y aprovechar el fine-tuning completo del modelo.
Evaluación del Modelo
La evaluación del modelo se realizó sobre el conjunto de validación tras 80 épocas de entrenamiento.
El análisis se centró en cuatro aspectos principales: matriz de confusión, métricas por clase, métricas globales y registro de errores de predicción.
Matriz de Confusión
Se generó una matriz de confusión que permitió visualizar la distribución de aciertos y errores por clase.
Los resultados muestran un comportamiento sólido en las clases extremas —octa 0 (cielo despejado) y octa 8 (cielo cubierto)—, pero revelan confusiones sistemáticas entre clases vecinas.
Las principales discrepancias observadas fueron:
-
43 casos donde imágenes de clase real 6 fueron clasificadas como clase 5.
-
25 casos de clase real 8 predichas como clase 7.
-
21 casos de clase real 1 predichas como clase 2.
Este comportamiento indica que el modelo tiende a “confundirse con el vecino”, especialmente en las transiciones graduales de nubosidad.
La clase 6 presentó el peor rendimiento: solo 18 aciertos correctos frente a 43 errores hacia clase 5.
Métricas por Clase
Las métricas de precisión, recall y f1-score se calcularon con la función precision_recall_fscore_support de Scikit-learn y se guardaron en el archivo metricas_modelo_octas.csv.
El modelo alcanzó los mejores resultados en las clases extremas:
-
Clase 0 (Despejado): F1-score de 87.5%.
-
Clase 8 (Cubierto): F1-score de 82.7%.
-
Clase 5: presenta la menor precisión del conjunto, con un 42.5%. Esto significa que cuando el modelo predice "octa 5", se equivoca más de la mitad de las veces, lo que la convierte en una predicción poco fiable.
-
Clase 6: Es la categoría que presentó mayores dificultades de recuperación, con un Recall de 21.6%. Esto indica que el modelo no pudo identificar correctamente a casi 4 de cada 5 imágenes que realmente pertenecían a esta clase.
Métricas Globales
La métrica global utilizada fue la Accuracy, con un valor final de 67.6% en el conjunto de validación.
La implementación de evaluación se centró exclusivamente en las métricas por clase y la precisión general del modelo.
Registro de Predicciones y Errores
Para un análisis más detallado del comportamiento del modelo, se exportó un archivo errores_clasificacion.csv que contiene exclusivamente las predicciones incorrectas.
Este registro incluye la ruta de la imagen, la etiqueta real, la predicción errónea y la carpeta de origen, lo que permitió examinar patrones de error y tipos de imágenes problemáticas.
Análisis General
El modelo presenta un buen desempeño en la detección de extremos atmosféricos (cielos despejados o totalmente cubiertos), pero dificultades para discriminar niveles intermedios de nubosidad.
El entrenamiento fue estable, aunque se observa un ligero sobreajuste, reflejado en la diferencia entre las precisiones de entrenamiento (74.9%) y validación (67.6%).
Las técnicas de aumento de datos y balanceo de clases mejoraron el rendimiento general, aunque no fueron suficientes para compensar la escasez de ejemplos en clases ambiguas.
En síntesis, el modelo constituye una base sólida para la clasificación de nubosidad en imágenes del cielo, pero requiere ajustes adicionales (como incremento de datos en clases intermedias o exploración de arquitecturas alternativas) para alcanzar una precisión robusta en contextos operativos.
Análisis de Errores
El modelo muestra un patrón consistente de confusión entre clases adyacentes, fenómeno típico en tareas de clasificación ordinal.
Las confusiones más frecuentes fueron las siguientes:
-
Clase 6 → Clase 5: 43 errores (el más significativo).
-
Clase 8 → Clase 7: 25 errores.
-
Clase 1 → Clase 2: 21 errores.
-
Clase 0 → Clase 1: 13 errores.
-
Clase 3 → Clase 4: 12 errores.
Este comportamiento indica que el modelo tiende a equivocarse con categorías vecinas, especialmente en los niveles intermedios de nubosidad.
En particular, la clase 6 fue la de peor desempeño, con solo 18 aciertos correctos frente a 43 errores hacia la clase 5, lo que evidencia que el modelo no logró aprender características distintivas para ese nivel.
Durante la etapa de análisis se generaron varios recursos gráficos que facilitaron la interpretación de los resultados:
-
distribucion_clases_octas.png → muestra la cantidad de imágenes por clase, evidenciando el desbalance del dataset.
-
matriz_confusion_octas.png → representa visualmente la distribución de aciertos y errores entre clases.
-
errores_clasificacion_octas.png → collage con las primeras 9 imágenes mal clasificadas, cada una acompañada por su etiqueta real y la predicha.
-
grafico_aprendizaje_octas.png → curvas de entrenamiento y validación, utilizadas para verificar estabilidad y convergencia.
Los errores observados se deben principalmente a la alta similitud visual y ambigüedad entre los niveles intermedios de nubosidad, donde las diferencias son sutiles y difíciles de distinguir incluso para un observador humano.
En particular, las clases 4, 5 y 6 presentan límites difusos en términos visuales, lo que explica la tendencia del modelo a confundirlas.
A pesar de las técnicas aplicadas de balanceo y aumento de datos, el modelo no logró aprender de forma robusta las transiciones entre niveles contiguos, manteniendo un ligero sobreajuste que afectó su capacidad de generalización.
Visualización del Aprendizaje
El proceso de aprendizaje del modelo se registró y visualizó mediante el archivo grafico_aprendizaje_octas.png, que representa las curvas de pérdida (Loss) y precisión (Accuracy) tanto en entrenamiento como en validación a lo largo de las 80 épocas.
Comportamiento de las curvas
El gráfico muestra un comportamiento de entrenamiento clásico, en el que el modelo aprende de manera efectiva al inicio y luego comienza a mostrar signos de ligero sobreajuste (overfitting) hacia las últimas épocas.
-
Pérdida de entrenamiento (Train Loss): Disminuyó de forma continua y pronunciada, alcanzando un valor final de 0.135, lo que indica un aprendizaje estable sobre los datos de entrenamiento.
-
Pérdida de validación (Validation Loss): Descendió significativamente en las primeras etapas del entrenamiento, alcanzando su mínimo en la época 72 (val_loss \= 0.261), pero posteriormente se estabilizó y comenzó a aumentar levemente.
-
Precisión de entrenamiento (Train Accuracy): Aumentó de manera sostenida hasta llegar a 74.9% al finalizar la época 80.
-
Precisión de validación (Validation Accuracy): Mejoró en paralelo al inicio, alcanzando su punto máximo en la época 70 (val_accuracy \= 68.7%), tras lo cual se mantuvo estable sin mayores mejoras.
Las curvas reflejan un buen proceso de convergencia, evidenciando que el modelo logró aprender las características principales del dataset.
No obstante, la brecha entre las curvas de entrenamiento y validación (donde las métricas de validación se estabilizan mientras las de entrenamiento continúan mejorando) señala un ligero sobreajuste, indicando que el modelo comenzó a especializarse en los datos de entrenamiento en lugar de generalizar de manera óptima a nuevos ejemplos.
El gráfico de aprendizaje fue generado usando los datos del historial de entrenamiento, que también fueron exportados al archivo historial_entrenamiento.csv.
Este registro contiene los valores de loss, val_loss, accuracy y val_accuracy para cada una de las 80 épocas que duró el entrenamiento.
El análisis numérico confirmó que:
-
La mejor precisión de validación (68.7%) se obtuvo en la época 70.
-
La menor pérdida de validación (0.261) se registró en la época 72, momento a partir del cual comenzó el estancamiento.
Estos resultados justificaron la aplicación del Early Stopping, que detuvo el entrenamiento en el punto óptimo antes de que el sobreajuste se intensificara.
Evaluación Final del Modelo
El modelo EfficientNet-B0, reentrenado mediante un proceso de fine-tuning completo sobre las nueve clases de niveles de nubosidad (octas), alcanzó una precisión global (accuracy) del 67.6% en el conjunto de validación.
El entrenamiento fue estable y convergente, deteniéndose automáticamente en la época 80 gracias al mecanismo de Early Stopping, activado cuando la pérdida de validación dejó de mejorar.
El rendimiento del modelo presenta el siguiente comportamiento:
-
Fortalezas:
- Alta eficacia en los extremos atmosféricos (clases 0 y 8).
- Reconocimiento consistente de patrones visuales bien definidos.
- Buen aprovechamiento de los datos contrastantes y balanceados. -
Debilidades:
- Dificultad para discriminar niveles intermedios de nubosidad (clases 5 y 6).
- Confusión entre categorías visualmente similares, incluso tras aplicar aumento de datos y Focal Loss.
- Persistencia de ambigüedad visual intrínseca entre clases adyacentes.
El historial de entrenamiento refleja un ligero sobreajuste (overfitting).
Al finalizar, la precisión de entrenamiento fue de 74.9%, mientras que la de validación se mantuvo en 67.6%, generando una brecha aproximada del 7%.
Este comportamiento indica que el modelo aprendió adecuadamente los patrones del conjunto de entrenamiento, pero perdió parte de su capacidad de generalización ante datos nuevos.
En conjunto, el modelo logra capturar de manera efectiva los extremos de nubosidad, pero aún presenta limitaciones en la representación de los matices intermedios del cielo.
A pesar de ello, constituye una base sólida para etapas posteriores de refinamiento, tanto en la mejora de la clasificación por niveles de octas como en su futura integración dentro del sistema de monitoreo atmosférico automatizado de la Estación Astronómica de Río Grande.
Este modelo forma parte del proyecto desarrollado en el marco de Prácticas Profesionalizantes II del Instituto Politécnico Malvinas Argentinas, en colaboración con la Estación Astronómica de Río Grande (EARG). Su desarrollo representa una etapa clave en la implementación de sistemas inteligentes de análisis atmosférico, integrando ciencia de datos e inteligencia artificial con fines científicos y educativos.
