Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified docs/report/ML_report.pdf
Binary file not shown.
Binary file added docs/report/histogram_Accuracy.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/report/histogram_F1_Class0.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/report/histogram_F1_Class1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/report/histogram_F1_Mean.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/report/histogram_IoU_Class0.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/report/histogram_IoU_Class1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/report/histogram_Mask_Cohesion.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/report/histogram_Precision_Class0.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/report/histogram_Precision_Class1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/report/histogram_Recall_Class0.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/report/histogram_Recall_Class1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
57 changes: 48 additions & 9 deletions docs/report/main.tex
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ \subsection{Homogeneización del Entrenamiento de Modelos}


\subsection{Evaluación Imparcial y Persistencia}
La etapa final (\textit{Evaluator Node}) opera como un auditor independiente. Recibe las predicciones generadas y calcula métricas de desempeño sin acceso a la lógica que las produjo, asegurando una "evaluación ciega".
La etapa final (\textit{Evaluator Node}) opera como un auditor independiente. Recibe las predicciones generadas y calcula métricas de desempeño sin acceso a la lógica que las produjo, asegurando una ``evaluación ciega''.
Adicionalmente, el sistema implementa un mecanismo de persistencia granular que registra no solo las métricas finales, sino también los tiempos de cómputo y las configuraciones exactas. Esto habilita un análisis posterior profundo sobre el \textit{trade-off} entre costo computacional y precisión, fundamental para proponer soluciones viables en entornos de recursos limitados.

En conclusión, esta metodología instrumentaliza el método científico: permite plantear hipótesis sobre arquitecturas y datos, y validarlas o refutarlas mediante evidencia empírica generada en un entorno controlado.
Expand All @@ -208,6 +208,8 @@ \subsection{Dataset de segmentación}

El dataset principal utilizado para la tarea de segmentación está compuesto por 94 imágenes obtenidas mediante microscopía electrónica de barrido (SEM) utilizando un microscopio Vega 3 Scan. Cada imagen cuenta con su correspondiente máscara de segmentación a nivel de píxel.

De este conjunto, 15 imágenes fueron seleccionadas aleatoriamente y reservadas exclusivamente como conjunto de prueba independiente (\emph{test set}). Dicho subconjunto no fue utilizado durante ninguna etapa de entrenamiento, validación ni análisis exploratorio, y se empleó únicamente para la evaluación final del modelo seleccionado luego de la experimentación. Todos los análisis y la experimentación se realizan íntegramente sobre el subconjunto restante, complementado con 15 imágenes externas del repositorio \cite{repo_imagenes}, sumando un total de 94 imagenes para esta tarea.

Las máscaras de referencia delimitan dos morfologías de fractura fundamentales: zonas de comportamiento frágil y zonas de comportamiento dúctil. A nivel global, el conjunto presenta un desbalance significativo, con 73 imágenes donde predomina la fractura dúctil y 21 imágenes con mayor presencia de fractura frágil. Esta distribución refleja la naturaleza del material analizado y constituye un desafío adicional para la generalización del modelo.

Las imágenes originales presentan tamaños variables, lo cual motivó la adopción de un preprocesamiento de redimensionamiento a una resolución fija de $512 \times 512$ píxeles para los modelos basados en transformers y para el análisis estadístico espacial.
Expand All @@ -216,7 +218,7 @@ \subsection{Dataset de segmentación}

\begin{figure}[H]
\centering
\includegraphics{heatmap.png}
\includegraphics[width=0.5\linewidth]{heatmap.png}
\caption{Mapa de calor de la distribución espacial de las clases dúctil y frágil, obtenido a partir de la superposición de las máscaras de segmentación redimensionadas a $512 \times 512$ píxeles.}
\label{fig:heatmap_ductil}
\end{figure}
Expand Down Expand Up @@ -858,13 +860,9 @@ \subsection{Análisis de Escalabilidad de Datos}
\end{figure}


\subsection{Evaluación Cualitativa en Test}

Para complementar los resultados cuantitativos, se realizó una evaluación visual sobre el conjunto de prueba independiente. Para este análisis, se seleccionó el par modelo-estrategia que demostró el mayor rendimiento global según la métrica F1-score: el Swin Transformer Estándar entrenado con la estrategia de Aumentación Combinada (2 Geom, 2 Fotom, 1 SEM).

La Figura~\ref{fig:test_predictions} presenta las segmentaciones generadas por esta configuración óptima. La visualización se estructura en tres columnas para facilitar el cotejo directo: la primera columna muestra la imagen SEM original, capturando la textura compleja del material; la columna central exhibe la máscara de referencia (\emph{Ground Truth}) generada por expertos; y la tercera columna presenta la segmentación inferida por el modelo.

\subsection{Evaluación Cualitativa y Cuantitativa en Test}

Para complementar los resultados cuantitativos globales, se realizó una evaluación visual y estadística sobre el conjunto de prueba independiente. Para este análisis, se seleccionó el par modelo--estrategia que demostró el mayor rendimiento global según la métrica F1-score: el Swin Transformer Estándar entrenado con la estrategia de Aumentación Combinada (2 Geom, 2 Fotom, 1 SEM).

\begin{figure}[H]
\centering
Expand All @@ -873,7 +871,48 @@ \subsection{Evaluación Cualitativa en Test}
\label{fig:test_predictions}
\end{figure}

El análisis detallado de estas imágenes revela que el modelo ha logrado aprender no solo la textura local, sino la topología de las fracturas. Se observa una notable precisión en la delimitación de las zonas dúctiles frente a las áreas frágiles, respetando los bordes irregulares característicos de estas morfologías. Incluso en regiones donde el contraste es bajo o la transición es sutil, el modelo mantiene una coherencia estructural alta, evitando la fragmentación excesiva y demostrando una generalización robusta ante datos no vistos.
La Figura~\ref{fig:test_predictions} presenta ejemplos representativos de las segmentaciones generadas por esta configuración óptima. La visualización se estructura en tres columnas para facilitar el cotejo directo: la primera columna muestra la imagen SEM original, capturando la textura compleja del material; la columna central exhibe la máscara de referencia (\emph{Ground Truth}); y la tercera columna presenta la segmentación inferida por el modelo.

Además de la inspección visual, se incorporó un análisis cuantitativo basado en distribuciones de métricas calculadas sobre el conjunto de prueba mediante una estrategia \emph{leave-two-out}. Este enfoque permitió caracterizar la variabilidad del desempeño del modelo en términos de F1-score, Intersection over Union (IoU), precisión, recall, accuracy y cohesión de máscara a lo largo de múltiples particiones del conjunto de test, proporcionando una estimación más robusta de su comportamiento fuera de muestra.

Las Figuras~\ref{fig:f1_iou_dist}, \ref{fig:prec_rec_dist}, \ref{fig:acc_cohesion_dist} y \ref{fig:f1_mean_dist} muestran las distribuciones obtenidas para las distintas métricas evaluadas. En conjunto, se observa una concentración consistente de los valores en rangos elevados, acompañada de una dispersión moderada, lo que sugiere estabilidad en la capacidad de generalización del modelo seleccionado frente a variaciones en los datos de prueba. Además se obtuvo un valor F1 medio entre ambas clases de 0.7634, en concordancia con las tendencias de desempeño observadas a lo largo del análisis.

\begin{figure*}[t]
\centering
\subfloat[]{\includegraphics[width=0.45\textwidth]{histogram_F1_Class0.png}}\hfill
\subfloat[]{\includegraphics[width=0.45\textwidth]{histogram_F1_Class1.png}}\\
\subfloat[]{\includegraphics[width=0.45\textwidth]{histogram_IoU_Class0.png}}\hfill
\subfloat[]{\includegraphics[width=0.45\textwidth]{histogram_IoU_Class1.png}}
\caption{Distribuciones de F1-score e Intersection over Union (IoU) obtenidas mediante validación \emph{leave-two-out} en el conjunto de prueba. Las clases 0 y 1 corresponden a las morfologías dúctil y frágil, respectivamente.}
\label{fig:f1_iou_dist}
\end{figure*}

\begin{figure*}[t]
\centering
\subfloat[]{\includegraphics[width=0.45\textwidth]{histogram_Precision_Class0.png}}\hfill
\subfloat[]{\includegraphics[width=0.45\textwidth]{histogram_Precision_Class1.png}}\\
\subfloat[]{\includegraphics[width=0.45\textwidth]{histogram_Recall_Class0.png}}\hfill
\subfloat[]{\includegraphics[width=0.45\textwidth]{histogram_Recall_Class1.png}}
\caption{Distribuciones de precisión y recall por clase en el conjunto de prueba, calculadas mediante validación \emph{leave-two-out}. Las clases 0 y 1 representan las regiones dúctiles y frágiles, respectivamente.}
\label{fig:prec_rec_dist}
\end{figure*}

\begin{figure*}[t]
\centering
\subfloat[]{\includegraphics[width=0.45\textwidth]{histogram_Accuracy.png}}\hfill
\subfloat[]{\includegraphics[width=0.45\textwidth]{histogram_Mask_Cohesion.png}}
\caption{Distribuciones de accuracy y cohesión de máscara obtenidas sobre el conjunto de prueba mediante validación \emph{leave-two-out}.}
\label{fig:acc_cohesion_dist}
\end{figure*}

\begin{figure*}[t]
\centering
\includegraphics[width=0.5\textwidth]{histogram_F1_Mean.png}
\caption{Distribución del F1-score medio entre ambas clases obtenida mediante validación \emph{leave-two-out} sobre el conjunto de prueba independiente.}
\label{fig:f1_mean_dist}
\end{figure*}

El análisis conjunto de los resultados cualitativos y cuantitativos indica que el modelo ha logrado aprender no solo la textura local, sino también la topología global de las fracturas. Se observa una delimitación consistente de las zonas dúctiles frente a las áreas frágiles, respetando los bordes irregulares característicos de estas morfologías. Incluso en regiones de bajo contraste o con transiciones graduales, el modelo mantiene una elevada coherencia estructural, evitando la fragmentación excesiva y reforzando las conclusiones derivadas del análisis estadístico sobre el conjunto de prueba independiente.

\subsection{Posibles Sesgos}

Expand Down
Binary file removed docs/report/progression.png
Binary file not shown.
8 changes: 8 additions & 0 deletions docs/report/references.bib
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ @dataset{campari_2025_15510590
url = {https://doi.org/10.5281/zenodo.15510590},
}

@misc{repo_imagenes,
author = {Shilvinit},
title = {Qualitative-Fractographic-Classification},
year = {2024},
howpublished = {\url{https://github.com/Shiivinnit/Qualitative-Fractographic-Classification}},
note = {Repositorio de GitHub, acceso: noviembre 2025}
}


@inproceedings{ronneberger2015unet,
author = {Ronneberger, Olaf and Fischer, Philipp and Brox, Thomas},
Expand Down
Binary file removed docs/report/test_predictions.png
Binary file not shown.
151 changes: 151 additions & 0 deletions kaggle/run-evaluation.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"id": "99852947",
"metadata": {},
"outputs": [],
"source": [
"!git clone https://github.com/CfM47/ML-Project.git"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "89e0509f",
"metadata": {},
"outputs": [],
"source": [
"import sys\n",
"from pathlib import Path"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "2ba6b9c0",
"metadata": {},
"outputs": [],
"source": [
"!ls /kaggle/input/training-notebook-output"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "05fff357",
"metadata": {},
"outputs": [],
"source": [
"segmentation_root = Path('/kaggle/input/segmentations-images-automl/pictures')\n",
"\n",
"TRAIN_LABELED = segmentation_root / 'vega_3_tescan_labeled_images'\n",
"TRAIN_UNLABELED = segmentation_root / 'vega_3_tescan_unlabeled_images'\n",
"TEST_UNLABELED = segmentation_root / 'sampled_unlabeled'\n",
"TEST_LABELED = segmentation_root / 'sampled_labeled'\n",
"\n",
"# Pretrained model from previous training run\n",
"PRETRAINED_MODEL = Path('/kaggle/input/training-notebook-output/swin_results/model.pt')\n",
"\n",
"WORKING_DIR = Path('/kaggle/working')\n",
"PROJECT_ROOT = WORKING_DIR / 'ML-Project'\n",
"OUTPUT_DIR = WORKING_DIR / 'swin_results'"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "bbcc6efc",
"metadata": {},
"outputs": [],
"source": [
"if str(PROJECT_ROOT) not in sys.path:\n",
" sys.path.insert(0, str(PROJECT_ROOT))"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "bd42e98a",
"metadata": {},
"outputs": [],
"source": [
"from model.swin.config import SwinTrainingConfig\n",
"\n",
"config = SwinTrainingConfig(\n",
" output_dir=OUTPUT_DIR,\n",
" device='auto',\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "39900be6",
"metadata": {},
"outputs": [],
"source": [
"from model.swin.train import run_evaluation_only\n",
"\n",
"result = run_evaluation_only(\n",
" TRAIN_UNLABELED,\n",
" TRAIN_LABELED,\n",
" TEST_UNLABELED,\n",
" TEST_LABELED,\n",
" PRETRAINED_MODEL,\n",
" config=config,\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3d554aad",
"metadata": {},
"outputs": [],
"source": [
"result.predictions_figure"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3a5d834b",
"metadata": {},
"outputs": [],
"source": [
"print(\"Full Test Set Metrics:\")\n",
"for metric_name, value in result.test_metrics.full_metrics.items():\n",
" print(f\" {metric_name}: {value:.4f}\")\n",
"\n",
"print(\"\\nLeave-Two-Out Summary:\")\n",
"print(f\" Subsets: {result.test_metrics.num_subsets} of size {result.test_metrics.subset_size}\")\n",
"for metric_name in sorted(result.test_metrics.subset_means.keys()):\n",
" mean_val = result.test_metrics.subset_means[metric_name]\n",
" std_val = result.test_metrics.subset_stds[metric_name]\n",
" print(f\" {metric_name}: {mean_val:.4f} ± {std_val:.4f}\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e5f6g7h8",
"metadata": {},
"outputs": [],
"source": [
"# Display all histograms\n",
"for metric_name, fig in sorted(result.histograms.items()):\n",
" print(f'\\n{metric_name}:')\n",
" display(fig)"
]
}
],
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
34 changes: 27 additions & 7 deletions kaggle/run-training.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@
"source": [
"from model.swin.train import run_final_training\n",
"\n",
"model, test_metrics, mask_pairs, predictions_fig, loss_curves_fig = run_final_training(\n",
"result = run_final_training(\n",
" TRAIN_UNLABELED,\n",
" TRAIN_LABELED,\n",
" TEST_UNLABELED,\n",
Expand All @@ -101,7 +101,7 @@
"metadata": {},
"outputs": [],
"source": [
"predictions_fig"
"result.predictions_figure"
]
},
{
Expand All @@ -111,8 +111,8 @@
"metadata": {},
"outputs": [],
"source": [
"if loss_curves_fig is not None:\n",
" display(loss_curves_fig)\n",
"if result.loss_curves_figure is not None:\n",
" display(result.loss_curves_figure)\n",
"else:\n",
" print('Loss curves not available (training history validation failed)')"
]
Expand All @@ -124,9 +124,29 @@
"metadata": {},
"outputs": [],
"source": [
"print(\"Test Metrics:\")\n",
"for metric_name, value in test_metrics.items():\n",
" print(f\" {metric_name}: {value:.4f}\")"
"print(\"Full Test Set Metrics:\")\n",
"for metric_name, value in result.test_metrics.full_metrics.items():\n",
" print(f\" {metric_name}: {value:.4f}\")\n",
"\n",
"print(\"\\nLeave-Two-Out Summary:\")\n",
"print(f\" Subsets: {result.test_metrics.num_subsets} of size {result.test_metrics.subset_size}\")\n",
"for metric_name in sorted(result.test_metrics.subset_means.keys()):\n",
" mean_val = result.test_metrics.subset_means[metric_name]\n",
" std_val = result.test_metrics.subset_stds[metric_name]\n",
" print(f\" {metric_name}: {mean_val:.4f} ± {std_val:.4f}\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e5f6g7h8",
"metadata": {},
"outputs": [],
"source": [
"# Display all histograms\n",
"for metric_name, fig in sorted(result.histograms.items()):\n",
" print(f'\\n{metric_name}:')\n",
" display(fig)"
]
}
],
Expand Down
7 changes: 6 additions & 1 deletion model/swin/__init__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
"""Swin model training and validation submodule."""

from model.swin.config import SwinTrainingConfig
from model.swin.train import run_final_training, run_percentage_validation
from model.swin.train import (
run_evaluation_only,
run_final_training,
run_percentage_validation,
)

__all__ = [
"SwinTrainingConfig",
"run_percentage_validation",
"run_final_training",
"run_evaluation_only",
]
Loading