diff --git a/apply_content.py b/apply_content.py index 84bb22d..367e92c 100644 --- a/apply_content.py +++ b/apply_content.py @@ -92,9 +92,13 @@ def parse_md_to_html_blocks(md_content): mermaid_lines.append(lines[i]) i += 1 - # Try to extract title from mermaid content + # Try to extract title from mermaid content (YAML format: title: "...") mermaid_content = '\n'.join(mermaid_lines) - title_match = re.search(r'title\s+["\']?([^"\'"\n]+)["\']?', mermaid_content) + # Match YAML format: title: "Title" or title: 'Title' + title_match = re.search(r'title:\s*["\']([^"\']+)["\']', mermaid_content) + if not title_match: + # Fallback to non-YAML format: title "Title" + title_match = re.search(r'title\s+["\']?([^"\'"\n]+)["\']?', mermaid_content) if title_match: fig_title = title_match.group(1).strip() else: @@ -106,12 +110,13 @@ def parse_md_to_html_blocks(md_content): # Create figure with MsoCaption class and proper Word SEQ field for cross-reference # Format: "Figura X." in bold, title in italic (per UNIR guidelines) - bookmark_id = f"_TocFigura{figure_counter}" - html_blocks.append(f'''
Figura {figure_counter}. {fig_title}
''') + # Word TOC looks for text with Caption style - anchor must be outside main caption text + bookmark_id = f"_Ref_Fig{figure_counter}" + html_blocks.append(f'''Figura {figure_counter}. {fig_title}
''') if os.path.exists(fig_path): - # Use actual image with proper Word-compatible format (max 350px width, 400px height to fit page with caption) - html_blocks.append(f'''[Insertar diagrama Mermaid aquí]
''') @@ -189,12 +194,13 @@ def parse_md_to_html_blocks(md_content): # Add table title with MsoCaption class and proper Word SEQ field for cross-reference # Format: "Tabla X." in bold, title in italic (per UNIR guidelines) - bookmark_id = f"_TocTabla{table_counter}" + # Word TOC looks for text with Caption style - anchor must be outside main caption text + bookmark_id = f"_Ref_Tab{table_counter}" if table_title: clean_title = table_title.replace(f"Tabla {table_counter}.", "").strip() else: clean_title = "Tabla de datos." - html_blocks.append(f'''Tabla {table_counter}. {clean_title}
''') + html_blocks.append(f'''Tabla {table_counter}. {clean_title}
''') # Build table HTML with APA style (horizontal lines only, no vertical) table_html = 'Parámetro | Descripción | Valor por defecto |
text_det_thresh | Umbral de detección de píxeles | 0.3 |
text_det_box_thresh | Umbral de caja de detección | 0.6 |
text_det_unclip_ratio | Coeficiente de expansión | 1.5 |
text_rec_score_thresh | Umbral de confianza de reconocimiento | 0.5 |
use_textline_orientation | Clasificación de orientación | False |
use_doc_orientation_classify | Clasificación de orientación de documento | False |
use_doc_unwarping | Corrección de deformación | False |
Fuente: Elaboración propia.
· Limitaciones: Menor rendimiento en español comparado con PaddleOCR
Tabla 2. Comparativa de soluciones OCR de código abierto.
+Tabla 2. Comparativa de soluciones OCR de código abierto.
Modelo | Tipo | Componentes | Fortalezas Clave |
EasyOCR | End-to-end (det + rec) | CRAFT + CRNN/Transformer | Ligero, fácil de usar, multilingüe |
PaddleOCR | End-to-end (det + rec + cls) | DB + SVTR/CRNN | Soporte multilingüe robusto, configurable |
DocTR | End-to-end (det + rec) | DB/LinkNet + CRNN/SAR/ViTSTR | Orientado a investigación, API limpia |
Fuente: Elaboración propia.
· Visualización de resultados
La combinación Ray Tune + Optuna permite búsquedas eficientes en espacios de alta dimensionalidad.
-Figura 2. Diagrama 2
-
Figura 2. Ciclo de optimización con Ray Tune y Optuna
+
Fuente: Elaboración propia.
Optimizar el rendimiento de PaddleOCR para documentos académicos en español mediante ajuste de hiperparámetros, alcanzando un CER inferior al 2% sin requerir fine-tuning del modelo ni recursos GPU dedicados.
Tabla 3. Tabla de datos.
+Tabla 3. Tabla de datos.
Criterio | Cumplimiento |
Específico (S) | Se define claramente qué se quiere lograr: optimizar PaddleOCR mediante ajuste de hiperparámetros para documentos en español |
Medible (M) | Se establece una métrica cuantificable: CER < 2% |
Alcanzable (A) | Es viable dado que: (1) PaddleOCR permite configuración de hiperparámetros, (2) Ray Tune posibilita búsqueda automatizada, (3) No se requiere GPU |
Relevante (R) | El impacto es demostrable: mejora la extracción de texto en documentos académicos sin costes adicionales de infraestructura |
Temporal (T) | El plazo es un cuatrimestre, correspondiente al TFM |
Fuente: Elaboración propia.
Figura 3. Diagrama 3
-
Figura 3. Fases de la metodología experimental
+
Fuente: Elaboración propia.
Descripción de las fases:
@@ -4715,8 +4706,8 @@ concretos y metodología de trabajo1. Extracción de texto de referencia:- Método: page.get_text("dict") de PyMuPDF - Preservación de estructura de líneas - Tratamiento de texto vertical/marginal - Normalización de espacios y saltos de línea
Figura 4. Diagrama 4
-
Figura 4. Estructura del dataset de evaluación
+
Fuente: Elaboración propia.
Tabla 4. Tabla de datos.
+Tabla 4. Tabla de datos.
Modelo | Versión | Configuración |
EasyOCR | - | Idiomas: ['es', 'en'] |
PaddleOCR | PP-OCRv5 | Modelos server_det + server_rec |
DocTR | - | db_resnet50 + sar_resnet31 |
Fuente: Elaboración propia.
Tabla 5. Tabla de datos.
+Tabla 5. Tabla de datos.
Parámetro | Tipo | Rango/Valores | Descripción |
use_doc_orientation_classify | Booleano | [True, False] | Clasificación de orientación del documento |
use_doc_unwarping | Booleano | [True, False] | Corrección de deformación del documento |
textline_orientation | Booleano | [True, False] | Clasificación de orientación de línea de texto |
text_det_thresh | Continuo | [0.0, 0.7] | Umbral de detección de píxeles de texto |
text_det_box_thresh | Continuo | [0.0, 0.7] | Umbral de caja de detección |
text_det_unclip_ratio | Fijo | 0.0 | Coeficiente de expansión (fijado) |
text_rec_score_thresh | Continuo | [0.0, 0.7] | Umbral de confianza de reconocimiento |
Fuente: Elaboración propia.
Debido a incompatibilidades entre Ray y PaddleOCR en el mismo proceso, se implementó una arquitectura basada en subprocesos:
-Figura 5. Diagrama 5
-
Figura 5. Arquitectura de ejecución con subprocesos
+
Fuente: Elaboración propia.
4. Métricas reportadas: CER, WER, tiempo de procesamiento
Tabla 6. Tabla de datos.
+Tabla 6. Tabla de datos.
Componente | Especificación |
CPU | Intel Core (especificar modelo) |
RAM | 16 GB |
GPU | No disponible (ejecución en CPU) |
Almacenamiento | SSD |
Fuente: Elaboración propia.
Tabla 7. Tabla de datos.
+Tabla 7. Tabla de datos.
Componente | Versión |
Sistema Operativo | Windows 10/11 |
Python | 3.11.9 |
PaddleOCR | 3.3.2 |
PaddlePaddle | 3.2.2 |
Ray | 2.52.1 |
Optuna | 4.6.0 |
Fuente: Elaboración propia.
Se utilizó el documento "Instrucciones para la redacción y elaboración del TFE" del Máster Universitario en Inteligencia Artificial de UNIR, ubicado en la carpeta instructions/.
-Tabla 8. Tabla 3. Características del dataset de evaluación.
+Tabla 8. Tabla 3. Características del dataset de evaluación.
Característica | Valor |
Número de páginas evaluadas | 5 (páginas 1-5 en benchmark inicial) |
Formato | PDF digital (no escaneado) |
Idioma | Español |
Resolución de conversión | 300 DPI |
Fuente: Elaboración propia.
Del archivo results/ai_ocr_benchmark_finetune_results_20251206_113206.csv, se obtienen los siguientes resultados de PaddleOCR para las páginas 5-9 del documento:
-Tabla 9. Tabla 4. Resultados de PaddleOCR por página (benchmark inicial).
+Tabla 9. Tabla 4. Resultados de PaddleOCR por página (benchmark inicial).
Página | WER | CER |
5 | 12.16% | 6.33% |
6 | 12.81% | 6.40% |
7 | 11.06% | 6.24% |
8 | 8.13% | 1.54% |
9 | 10.61% | 5.58% |
Fuente: Elaboración propia.
· WER medio: ~10.95%
Según la documentación del notebook ocr_benchmark_notebook.ipynb, los tres modelos evaluados representan diferentes paradigmas de OCR:
-Tabla 10. Tabla 5. Comparativa de arquitecturas OCR evaluadas.
+Tabla 10. Tabla 5. Comparativa de arquitecturas OCR evaluadas.
Modelo | Tipo | Componentes | Fortalezas Clave |
EasyOCR | End-to-end (det + rec) | DB + CRNN/Transformer | Ligero, fácil de usar, multilingüe |
PaddleOCR (PP-OCR) | End-to-end (det + rec + cls) | DB + SRN/CRNN | Soporte multilingüe robusto, pipeline configurable |
DocTR | End-to-end (det + rec) | DB/LinkNet + CRNN/SAR/VitSTR | Orientado a investigación, API limpia |
Fuente: Elaboración propia.
Según los outputs del notebook:
-Tabla 11. Tabla 6. Entorno de ejecución del experimento.
+Tabla 11. Tabla 6. Entorno de ejecución del experimento.
Componente | Versión/Especificación |
Python | 3.11.9 |
PaddlePaddle | 3.2.2 |
PaddleOCR | 3.3.2 |
Ray | 2.52.1 |
GPU | No disponible (CPU only) |
Fuente: Elaboración propia.
Descripción de parámetros (según documentación de PaddleOCR):
-Tabla 12. Tabla de datos.
+Tabla 12. Tabla de datos.
Parámetro | Descripción |
use_doc_orientation_classify | Clasificación de orientación del documento |
use_doc_unwarping | Corrección de deformación del documento |
textline_orientation | Clasificación de orientación de línea de texto |
text_det_thresh | Umbral de detección de píxeles de texto |
text_det_box_thresh | Umbral de caja de detección |
text_det_unclip_ratio | Coeficiente de expansión (fijado en 0.0) |
text_rec_score_thresh | Umbral de confianza de reconocimiento |
Fuente: Elaboración propia.
Del archivo CSV de resultados (raytune_paddle_subproc_results_20251207_192320.csv):
-Tabla 13. Tabla 7. Estadísticas descriptivas de los 64 trials de Ray Tune.
+Tabla 13. Tabla 7. Estadísticas descriptivas de los 64 trials de Ray Tune.
Estadística | CER | WER | Tiempo (s) | Tiempo/Página (s) |
count | 64 | 64 | 64 | 64 |
mean | 5.25% | 14.28% | 347.61 | 69.42 |
std | 11.03% | 10.75% | 7.88 | 1.57 |
min | 1.15% | 9.89% | 320.97 | 64.10 |
25% | 1.20% | 10.04% | 344.24 | 68.76 |
50% | 1.23% | 10.20% | 346.42 | 69.19 |
75% | 4.03% | 13.20% | 350.14 | 69.93 |
max | 51.61% | 59.45% | 368.57 | 73.63 |
Fuente: Elaboración propia.
Correlación de Pearson entre parámetros y métricas de error (del notebook):
Correlación con CER:
-Tabla 14. Tabla de datos.
+Tabla 14. Tabla de datos.
Parámetro | Correlación |
CER | 1.000 |
config/text_det_box_thresh | 0.226 |
config/text_rec_score_thresh | -0.161 |
config/text_det_thresh | -0.523 |
config/text_det_unclip_ratio | NaN |
Fuente: Elaboración propia.
Correlación con WER:
-Tabla 15. Tabla de datos.
+Tabla 15. Tabla de datos.
Parámetro | Correlación |
WER | 1.000 |
config/text_det_box_thresh | 0.227 |
config/text_rec_score_thresh | -0.173 |
config/text_det_thresh | -0.521 |
config/text_det_unclip_ratio | NaN |
Fuente: Elaboración propia.
Hallazgo clave: El parámetro text_det_thresh muestra la correlación más fuerte (-0.52), indicando que valores más altos de este umbral tienden a reducir el error.
Según el análisis del notebook, este parámetro booleano tiene el mayor impacto:
-Tabla 16. Tabla 8. Impacto del parámetro textline_orientation en las métricas de error.
+Tabla 16. Tabla 8. Impacto del parámetro textline_orientation en las métricas de error.
textline_orientation | CER Medio | WER Medio |
True | ~3.76% | ~12.73% |
False | ~12.40% | ~21.71% |
Fuente: Elaboración propia.
Interpretación: El CER medio es ~3.3x menor con textline_orientation=True (3.76% vs 12.40%). Además, la varianza es mucho menor, lo que indica resultados más consistentes. Para documentos en español con layouts mixtos (tablas, encabezados, direcciones), la clasificación de orientación ayuda a PaddleOCR a ordenar correctamente las líneas de texto.
-Figura 6. Impacto de textline_orientation en CER
-
Figura 6. Impacto de textline_orientation en CER
+
Fuente: Elaboración propia.
Del análisis final del notebook ejecutando sobre las 24 páginas:
-Tabla 17. Tabla 9. Comparación baseline vs configuración optimizada (24 páginas).
+Tabla 17. Tabla 9. Comparación baseline vs configuración optimizada (24 páginas).
Modelo | CER | WER |
PaddleOCR (Baseline) | 7.78% | 14.94% |
PaddleOCR-HyperAdjust | 1.49% | 7.62% |
Fuente: Elaboración propia.
Tabla 18. Tabla 10. Análisis de la mejora obtenida.
+Tabla 18. Tabla 10. Análisis de la mejora obtenida.
Métrica | Baseline | Optimizado | Mejora Absoluta | Reducción Error |
CER | 7.78% | 1.49% | -6.29 pp | 80.9% |
WER | 14.94% | 7.62% | -7.32 pp | 49.0% |
Fuente: Elaboración propia.
"La optimización de hiperparámetros mejoró la precisión de caracteres de 92.2% a 98.5%, una ganancia de 6.3 puntos porcentuales. Aunque el baseline ya ofrecía resultados aceptables, la configuración optimizada reduce los errores residuales en un 80.9%."
-Figura 7. Comparación Baseline vs Optimizado (24 páginas)
-
Figura 7. Comparación Baseline vs Optimizado (24 páginas)
+
Fuente: Elaboración propia.
Impacto práctico: En un documento de 10,000 caracteres:
@@ -5047,7 +5038,7 @@ Configuración óptima:· Optimizado: ~149 caracteres con error
· Diferencia: ~629 caracteres menos con errores
Tabla 19. Tabla de datos.
+Tabla 19. Tabla de datos.
Métrica | Valor |
Tiempo total del experimento | ~6 horas (64 trials × ~6 min/trial) |
Tiempo medio por trial | 367.72 segundos |
Tiempo medio por página | 69.42 segundos |
Total páginas procesadas | 64 trials × 5 páginas = 320 evaluaciones |
Fuente: Elaboración propia.
Del archivo results/ai_ocr_benchmark_finetune_results_20251206_113206.csv, PaddleOCR con configuración inicial (use_textline_orientation=True) obtuvo los siguientes resultados en las páginas 5-9:
-Tabla 20. Tabla de datos.
+Tabla 20. Tabla de datos.
Página | WER | CER |
5 | 12.16% | 6.33% |
6 | 12.81% | 6.40% |
7 | 11.06% | 6.24% |
8 | 8.13% | 1.54% |
9 | 10.61% | 5.58% |
Promedio | 10.95% | 5.22% |
Fuente: Elaboración propia.
Del archivo src/raytune_paddle_subproc_results_20251207_192320.csv (64 trials):
-Tabla 21. Tabla de datos.
+Tabla 21. Tabla de datos.
Métrica | Valor |
CER mínimo | 1.15% |
CER medio | 5.25% |
CER máximo | 51.61% |
WER mínimo | 9.89% |
WER medio | 14.28% |
WER máximo | 59.45% |
Fuente: Elaboración propia.
Resultados del notebook src/paddle_ocr_fine_tune_unir_raytune.ipynb:
-Tabla 22. Tabla de datos.
+Tabla 22. Tabla de datos.
Modelo | CER | Precisión Caracteres | WER | Precisión Palabras |
PaddleOCR (Baseline) | 7.78% | 92.22% | 14.94% | 85.06% |
PaddleOCR-HyperAdjust | 1.49% | 98.51% | 7.62% | 92.38% |
Fuente: Elaboración propia.
Tabla 23. Tabla de datos.
+Tabla 23. Tabla de datos.
Forma de Medición | Valor |
Mejora en precisión de caracteres (absoluta) | +6.29 puntos porcentuales |
Reducción del CER (relativa) | 80.9% |
Mejora en precisión de palabras (absoluta) | +7.32 puntos porcentuales |
Reducción del WER (relativa) | 49.0% |
Precisión final de caracteres | 98.51% |
Fuente: Elaboración propia.
Parámetro textline_orientation
Este parámetro booleano demostró ser el más influyente:
-Tabla 24. Tabla de datos.
+Tabla 24. Tabla de datos.
Valor | CER Medio | Impacto |
True | ~3.76% | Rendimiento óptimo |
False | ~12.40% | 3.3x peor |
Fuente: Elaboración propia.
Reducción del CER: 69.7% cuando se habilita la clasificación de orientación de línea.
Parámetro text_det_thresh
Correlación con CER: -0.523 (la más fuerte de los parámetros continuos)
-Tabla 25. Tabla de datos.
+Tabla 25. Tabla de datos.
Rango | Comportamiento |
< 0.1 | Fallos catastróficos (CER 40-50%) |
0.3 - 0.6 | Rendimiento óptimo |
Valor óptimo | 0.4690 |
Fuente: Elaboración propia.
Parámetros con menor impacto
-Tabla 26. Tabla de datos.
+Tabla 26. Tabla de datos.
Parámetro | Correlación con CER | Valor óptimo |
text_det_box_thresh | +0.226 | 0.5412 |
text_rec_score_thresh | -0.161 | 0.6350 |
use_doc_orientation_classify | - | False |
use_doc_unwarping | - | False |
Fuente: Elaboración propia.
1. Ejecución en CPU: Los tiempos reportados (~69s/página) corresponden a ejecución en CPU. Con GPU, los tiempos serían significativamente menores.
1. Parámetro fijo: text_det_unclip_ratio permaneció fijo en 0.0 durante todo el experimento por decisión de diseño.
Tabla 27. Tabla de datos.
+Tabla 27. Tabla de datos.
Objetivo | Meta | Resultado | Cumplimiento |
OE1: Comparar soluciones OCR | Evaluar EasyOCR, PaddleOCR, DocTR | PaddleOCR seleccionado | ✓ |
OE2: Preparar dataset | Construir dataset estructurado | Dataset de 24 páginas | ✓ |
OE3: Identificar hiperparámetros críticos | Analizar correlaciones | textline_orientation y text_det_thresh identificados | ✓ |
OE4: Optimizar con Ray Tune | Mínimo 50 configuraciones | 64 trials ejecutados | ✓ |
OE5: Validar configuración | Documentar mejora | CER 7.78% → 1.49% | ✓ |
Objetivo General | CER < 2% | CER = 1.49% | ✓ |
Fuente: Elaboración propia.
4. No recomendado: Habilitar use_doc_orientation_classify o use_doc_unwarping para documentos digitales
En un documento típico de 10,000 caracteres:
-Tabla 28. Tabla de datos.
+Tabla 28. Tabla de datos.
Configuración | Errores estimados |
Baseline | ~778 caracteres |
Optimizada | ~149 caracteres |
Reducción | 629 caracteres menos con errores |
Fuente: Elaboración propia.
Este capít
Este Trabajo Fin de Máster ha demostrado que es posible mejorar significativamente el rendimiento de sistemas OCR preentrenados mediante optimización sistemática de hiperparámetros, sin requerir fine-tuning ni recursos GPU dedicados. El objetivo principal del trabajo era alcanzar un CER inferior al 2% en documentos académicos en español. Los resultados obtenidos confirman el cumplimiento de este objetivo: Tabla 29. Tabla de datos. Tabla 29. Tabla de datos. Métrica Objetivo Resultado CER < 2% 1.49% Fuente: Elaboración propia. · Dataset: Imágenes y textos de referencia utilizados · Resultados: Archivos CSV con los resultados de los 64 trials de Ray Tune Figura 8. Diagrama 8 Figura 8. Estructura del repositorio del proyecto Fuente: Elaboración propia. Descripción de componentes: · instructions/: Instrucciones y plantilla UNIR Para reproducir los experimentos se requieren las siguientes dependencias: Tabla 30. Tabla de datos. Tabla 30. Tabla de datos. Componente Versión Python 3.11.9 PaddlePaddle 3.2.2 PaddleOCR 3.3.2 Ray 2.52.1 Optuna 4.6.0 jiwer (última versión) PyMuPDF (última versión) Fuente: Elaboración propia. Conclusiones Generales
A.2 Estructura del Repositorio
-

A.3 Requisitos de Software