Some checks failed
build_docker / build_easyocr (pull_request) Has been cancelled
build_docker / build_easyocr_gpu (pull_request) Has been cancelled
build_docker / build_doctr (pull_request) Has been cancelled
build_docker / build_doctr_gpu (pull_request) Has been cancelled
build_docker / build_raytune (pull_request) Has been cancelled
build_docker / essential (pull_request) Has been cancelled
build_docker / build_cpu (pull_request) Has been cancelled
build_docker / build_gpu (pull_request) Has been cancelled
1221 lines
57 KiB
Markdown
1221 lines
57 KiB
Markdown
# Desarrollo específico de la contribución
|
||
|
||
Este capítulo presenta el desarrollo completo del estudio comparativo y la optimización de hiperparámetros de sistemas OCR. Se estructura según el tipo de trabajo "Comparativa de soluciones" establecido por las instrucciones de UNIR: planteamiento de la comparativa, desarrollo de la comparativa, y discusión y análisis de resultados.
|
||
|
||
## Planteamiento de la comparativa
|
||
|
||
### Introducción
|
||
|
||
Esta sección presenta los resultados del estudio comparativo realizado entre tres soluciones OCR de código abierto: EasyOCR, PaddleOCR y DocTR. Los experimentos fueron documentados en el notebook `ocr_benchmark_notebook.ipynb` del repositorio. El objetivo es identificar el modelo base más prometedor para la posterior fase de optimización de hiperparámetros.
|
||
|
||
### Identificación del Problema
|
||
|
||
El reconocimiento óptico de caracteres (OCR) en documentos académicos en español presenta desafíos específicos que no han sido ampliamente abordados en la literatura:
|
||
|
||
1. **Layouts complejos**: Los documentos académicos combinan texto corrido, tablas, listas numeradas, encabezados multinivel y notas al pie.
|
||
|
||
2. **Caracteres específicos del español**: Acentos (á, é, í, ó, ú), eñe (ñ), diéresis (ü) y signos de puntuación invertidos (¿, ¡).
|
||
|
||
3. **Formato formal**: Tipografía profesional con múltiples fuentes, tamaños y estilos (negrita, cursiva).
|
||
|
||
4. **Calidad variable**: Documentos digitales de alta calidad pero con posibles artefactos de compresión PDF.
|
||
|
||
### Alternativas Evaluadas
|
||
|
||
Se seleccionaron tres soluciones OCR de código abierto representativas del estado del arte:
|
||
|
||
**Tabla 11.** *Soluciones OCR evaluadas en el benchmark comparativo.*
|
||
|
||
| Solución | Desarrollador | Versión | Justificación de selección |
|
||
|----------|---------------|---------|----------------------------|
|
||
| EasyOCR | Jaided AI | Última estable | Popularidad, facilidad de uso |
|
||
| PaddleOCR | Baidu | PP-OCRv5 | Estado del arte industrial |
|
||
| DocTR | Mindee | Última estable | Orientación académica |
|
||
|
||
*Fuente: Elaboración propia.*
|
||
|
||
**Imágenes Docker disponibles en el registro del proyecto:**
|
||
- PaddleOCR: [`seryus.ddns.net/unir/paddle-ocr-gpu`](https://seryus.ddns.net/unir/-/packages/container/paddle-ocr-gpu/latest), [`seryus.ddns.net/unir/paddle-ocr-cpu`](https://seryus.ddns.net/unir/-/packages/container/paddle-ocr-cpu/latest)
|
||
- EasyOCR: [`seryus.ddns.net/unir/easyocr-gpu`](https://seryus.ddns.net/unir/-/packages/container/easyocr-gpu/latest)
|
||
- DocTR: [`seryus.ddns.net/unir/doctr-gpu`](https://seryus.ddns.net/unir/-/packages/container/doctr-gpu/latest)
|
||
|
||
### Criterios de Éxito
|
||
|
||
Los criterios establecidos para evaluar las soluciones fueron:
|
||
|
||
1. **Precisión (CER < 5%)**: Error de caracteres aceptable para documentos académicos
|
||
2. **Configurabilidad**: Disponibilidad de hiperparámetros ajustables
|
||
3. **Soporte para español**: Modelos preentrenados que incluyan el idioma
|
||
4. **Documentación**: Calidad de la documentación técnica
|
||
5. **Mantenimiento activo**: Actualizaciones recientes y comunidad activa
|
||
|
||
### Configuración del Experimento
|
||
|
||
#### Dataset de Evaluación
|
||
|
||
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 12.** *Características del dataset de evaluación inicial.*
|
||
|
||
| Característica | Valor |
|
||
|----------------|-------|
|
||
| Documento fuente | Instrucciones TFE UNIR |
|
||
| Número de páginas evaluadas | 5 (benchmark inicial) |
|
||
| Formato | PDF digital (no escaneado) |
|
||
| Idioma principal | Español |
|
||
| Resolución de conversión | 300 DPI |
|
||
| Formato de imagen | PNG |
|
||
|
||
*Fuente: Elaboración propia.*
|
||
|
||
#### Proceso de Conversión
|
||
|
||
La conversión del PDF a imágenes se realizó mediante PyMuPDF (fitz) a 300 DPI, resolución estándar para OCR que proporciona suficiente detalle para caracteres pequeños sin generar archivos excesivamente grandes. La implementación está disponible en `src/ocr_benchmark_notebook.ipynb` (ver Anexo A).
|
||
|
||
#### Extracción del Ground Truth
|
||
|
||
El texto de referencia se extrajo directamente del PDF mediante PyMuPDF, preservando la estructura de líneas del documento original. Esta aproximación puede introducir errores en layouts muy complejos (tablas anidadas, texto en columnas). La implementación está disponible en `src/ocr_benchmark_notebook.ipynb` (ver Anexo A).
|
||
|
||
#### Configuración de los Modelos
|
||
|
||
La configuración de cada modelo se detalla en `src/ocr_benchmark_notebook.ipynb` (ver Anexo A):
|
||
|
||
- **EasyOCR**: Configurado con soporte para español e inglés, permitiendo reconocer palabras en ambos idiomas que puedan aparecer en documentos académicos (referencias, términos técnicos).
|
||
|
||
- **PaddleOCR (PP-OCRv5)**: Se utilizaron los modelos "server" (PP-OCRv5_server_det y PP-OCRv5_server_rec) que ofrecen mayor precisión a costa de mayor tiempo de inferencia. La versión utilizada fue PaddleOCR 3.2.0.
|
||
|
||
- **DocTR**: Se seleccionaron las arquitecturas db_resnet50 para detección y sar_resnet31 para reconocimiento, representando una configuración de alta precisión.
|
||
|
||
#### Métricas de Evaluación
|
||
|
||
Se utilizó la biblioteca `jiwer` para calcular CER y WER de manera estandarizada. La normalización a minúsculas y eliminación de espacios extremos asegura una comparación justa que no penaliza diferencias de capitalización. La implementación está disponible en `src/ocr_benchmark_notebook.ipynb` (ver Anexo A).
|
||
|
||
### Resultados del Benchmark
|
||
|
||
#### Resultados de PaddleOCR (Configuración Baseline)
|
||
|
||
Durante el benchmark inicial se evaluó PaddleOCR con configuración por defecto en un subconjunto del dataset. Los resultados preliminares mostraron variabilidad significativa entre páginas, con CER entre 1.54% y 6.40% dependiendo de la complejidad del layout.
|
||
|
||
**Tabla 13.** *Variabilidad del CER por tipo de contenido.*
|
||
|
||
| Tipo de contenido | CER aproximado | Observaciones |
|
||
|-------------------|----------------|---------------|
|
||
| Texto corrido | ~1.5-2% | Mejor rendimiento |
|
||
| Texto con listas | ~3-4% | Rendimiento medio |
|
||
| Tablas | ~5-6% | Mayor dificultad |
|
||
| Encabezados + notas | ~4-5% | Layouts mixtos |
|
||
|
||
*Fuente: Elaboración propia a partir del benchmark.*
|
||
|
||
**Observaciones del benchmark inicial:**
|
||
|
||
1. Las páginas con tablas y layouts complejos presentaron mayor error debido a la dificultad de ordenar correctamente las líneas de texto.
|
||
|
||
2. La página con texto corrido continuo obtuvo el mejor resultado (CER ~1.5%), demostrando la capacidad del modelo para texto estándar.
|
||
|
||
3. El promedio general se situó en CER ~5-6%, superando el umbral de aceptabilidad para documentos académicos pero con margen de mejora.
|
||
|
||
4. Los errores más frecuentes fueron: confusión de acentos, caracteres duplicados, y errores en signos de puntuación.
|
||
|
||
#### Comparativa de Modelos
|
||
|
||
Los tres modelos evaluados representan diferentes paradigmas de OCR:
|
||
|
||
**Tabla 14.** *Comparativa de arquitecturas OCR evaluadas.*
|
||
|
||
| 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, pipeline configurable |
|
||
| **DocTR** | End-to-end (det + rec) | DB/LinkNet + CRNN/SAR/ViTSTR | Orientado a investigación, API limpia |
|
||
|
||
*Fuente: Documentación oficial de cada herramienta (JaidedAI, 2020; PaddlePaddle, 2024; Mindee, 2021).*
|
||
|
||
#### Análisis Cualitativo de Errores
|
||
|
||
Un análisis cualitativo de los errores producidos reveló patrones específicos:
|
||
|
||
**Errores de acentuación:**
|
||
- `información` → `informacion` (pérdida de acento)
|
||
- `más` → `mas` (cambio de significado)
|
||
- `él` → `el` (cambio de significado)
|
||
|
||
**Errores de caracteres especiales:**
|
||
- `año` → `ano` (pérdida de eñe)
|
||
- `¿Cómo` → `Como` (pérdida de signos invertidos)
|
||
|
||
**Errores de duplicación:**
|
||
- `titulación` → `titulacióon` (carácter duplicado)
|
||
- `documento` → `doccumento` (consonante duplicada)
|
||
|
||
**Ejemplo de predicción de PaddleOCR para una página:**
|
||
|
||
> "Escribe siempre al menos un párrafo de introducción en cada capítulo o apartado, explicando de qué vas a tratar en esa sección. Evita que aparezcan dos encabezados de nivel consecutivos sin ningún texto entre medias. [...] En esta titulacióon se cita de acuerdo con la normativa Apa."
|
||
|
||
**Errores identificados en este ejemplo:**
|
||
- `titulacióon` en lugar de `titulación` (carácter duplicado)
|
||
- `Apa` en lugar de `APA` (capitalización)
|
||
|
||
### Justificación de la Selección de PaddleOCR
|
||
|
||
#### Criterios de Selección
|
||
|
||
La selección de PaddleOCR para la fase de optimización se basó en los siguientes criterios:
|
||
|
||
**Tabla 15.** *Evaluación de criterios de selección.*
|
||
|
||
| Criterio | EasyOCR | PaddleOCR | DocTR |
|
||
|----------|---------|-----------|-------|
|
||
| CER benchmark | ~6-8% | ~5-6% | ~7-9% |
|
||
| Configurabilidad | Baja (3 params) | **Alta (>10 params)** | Media (5 params) |
|
||
| Soporte español | Sí | **Sí (dedicado)** | Limitado |
|
||
| Documentación | Media | **Alta** | Alta |
|
||
| Mantenimiento | Medio | **Alto** | Medio |
|
||
|
||
*Fuente: Elaboración propia.*
|
||
|
||
#### Hiperparámetros Disponibles en PaddleOCR
|
||
|
||
PaddleOCR expone múltiples hiperparámetros ajustables, clasificados por etapa del pipeline:
|
||
|
||
**Detección:**
|
||
- `text_det_thresh`: Umbral de probabilidad para píxeles de texto
|
||
- `text_det_box_thresh`: Umbral de confianza para cajas detectadas
|
||
- `text_det_unclip_ratio`: Factor de expansión de cajas
|
||
|
||
**Reconocimiento:**
|
||
- `text_rec_score_thresh`: Umbral de confianza para resultados
|
||
|
||
**Preprocesamiento:**
|
||
- `use_textline_orientation`: Clasificación de orientación de línea
|
||
- `use_doc_orientation_classify`: Clasificación de orientación de documento
|
||
- `use_doc_unwarping`: Corrección de deformación
|
||
|
||
Esta riqueza de configuración permite explorar sistemáticamente el espacio de hiperparámetros mediante técnicas de optimización automática.
|
||
|
||
#### Decisión Final
|
||
|
||
**Se selecciona PaddleOCR (PP-OCRv5)** para la fase de optimización debido a:
|
||
|
||
1. **Resultados iniciales prometedores**: CER ~5% en configuración por defecto, con potencial de mejora
|
||
2. **Alta configurabilidad**: Más de 10 hiperparámetros ajustables en tiempo de inferencia
|
||
3. **Pipeline modular**: Permite aislar el impacto de cada componente
|
||
4. **Soporte activo para español**: Modelos específicos y actualizaciones frecuentes
|
||
5. **Documentación técnica**: Descripción detallada de cada parámetro
|
||
|
||
### Limitaciones del Benchmark
|
||
|
||
1. **Tamaño reducido**: Solo 5 páginas evaluadas en el benchmark comparativo inicial. Esto limita la generalización de las conclusiones.
|
||
|
||
2. **Único tipo de documento**: Documentos académicos de UNIR únicamente. Otros tipos de documentos (facturas, formularios, contratos) podrían presentar resultados diferentes.
|
||
|
||
3. **Ground truth automático**: El texto de referencia se extrajo programáticamente del PDF, lo cual puede introducir errores en layouts complejos donde el orden de lectura no es evidente.
|
||
|
||
4. **Ejecución en CPU**: Todos los experimentos se realizaron en CPU, limitando la exploración de configuraciones que podrían beneficiarse de aceleración GPU.
|
||
|
||
### Resumen de la Sección
|
||
|
||
Esta sección ha presentado:
|
||
|
||
1. La identificación del problema y los criterios de éxito establecidos
|
||
2. La configuración detallada del benchmark con tres soluciones OCR
|
||
3. Los resultados cuantitativos y cualitativos obtenidos
|
||
4. La justificación de la selección de PaddleOCR para optimización
|
||
5. Las limitaciones reconocidas del benchmark
|
||
|
||
**Fuentes de datos utilizadas:**
|
||
- `ocr_benchmark_notebook.ipynb`: Código del benchmark
|
||
- Documentación oficial de PaddleOCR
|
||
|
||
## Desarrollo de la comparativa: Optimización de hiperparámetros
|
||
|
||
### Introducción
|
||
|
||
Esta sección describe el proceso de optimización de hiperparámetros de PaddleOCR utilizando Ray Tune con el algoritmo de búsqueda Optuna. Los experimentos fueron implementados en [`src/run_tuning.py`](https://github.com/seryus/MastersThesis/blob/main/src/run_tuning.py) con la librería de utilidades [`src/raytune_ocr.py`](https://github.com/seryus/MastersThesis/blob/main/src/raytune_ocr.py), y los resultados se almacenaron en [`src/results/`](https://github.com/seryus/MastersThesis/tree/main/src/results).
|
||
|
||
La optimización de hiperparámetros representa una alternativa al fine-tuning tradicional que no requiere:
|
||
- Acceso a GPU dedicada
|
||
- Dataset de entrenamiento etiquetado
|
||
- Modificación de los pesos del modelo
|
||
|
||
### Configuración del Experimento
|
||
|
||
#### Entorno de Ejecución
|
||
|
||
El experimento se ejecutó en el siguiente entorno:
|
||
|
||
**Tabla 16.** *Entorno de ejecución del experimento.*
|
||
|
||
| Componente | Versión/Especificación |
|
||
|------------|------------------------|
|
||
| Sistema operativo | Ubuntu 24.04.3 LTS |
|
||
| Python | 3.12.3 |
|
||
| PaddlePaddle | 3.2.2 |
|
||
| PaddleOCR | 3.3.2 |
|
||
| Ray | 2.52.1 |
|
||
| Optuna | 4.7.0 |
|
||
| CPU | AMD Ryzen 7 5800H |
|
||
| RAM | 16 GB DDR4 |
|
||
| GPU | NVIDIA RTX 3060 Laptop (5.66 GB VRAM) |
|
||
|
||
*Fuente: Configuración del entorno de ejecución. Resultados en `src/results/` generados por `src/run_tuning.py`.*
|
||
|
||
#### Arquitectura de Ejecución
|
||
|
||
La arquitectura basada en contenedores Docker es fundamental para este proyecto debido a los conflictos de dependencias inherentes entre los diferentes componentes:
|
||
|
||
- **Conflictos entre motores OCR**: PaddleOCR, DocTR y EasyOCR tienen dependencias mutuamente incompatibles (diferentes versiones de PyTorch/PaddlePaddle, OpenCV, etc.)
|
||
- **Incompatibilidades CUDA/cuDNN**: Cada motor OCR requiere versiones específicas de CUDA y cuDNN que no pueden coexistir en un mismo entorno virtual
|
||
- **Aislamiento de Ray Tune**: Ray Tune tiene sus propias dependencias que pueden entrar en conflicto con las librerías de inferencia OCR
|
||
|
||
Esta arquitectura containerizada permite ejecutar cada componente en su entorno aislado óptimo, comunicándose via API REST:
|
||
|
||
```mermaid
|
||
---
|
||
title: "Arquitectura de ejecución con Docker Compose"
|
||
config:
|
||
theme: base
|
||
themeVariables:
|
||
primaryColor: "#E6F4F9"
|
||
primaryTextColor: "#404040"
|
||
primaryBorderColor: "#0098CD"
|
||
lineColor: "#0098CD"
|
||
---
|
||
flowchart LR
|
||
subgraph Docker["Docker Compose"]
|
||
A["RayTune Container"]
|
||
B["OCR Service Container"]
|
||
end
|
||
|
||
A -->|"HTTP POST /evaluate"| B
|
||
B -->|"JSON {CER, WER, TIME}"| A
|
||
A -.->|"Health check /health"| B
|
||
```
|
||
|
||
La arquitectura containerizada (`src/docker-compose.tuning.*.yml`) ofrece:
|
||
1. Aislamiento de dependencias entre Ray Tune y los motores OCR
|
||
2. Health checks automáticos para asegurar disponibilidad del servicio
|
||
3. Comunicación via API REST (endpoints `/health` y `/evaluate`)
|
||
4. Soporte para GPU mediante nvidia-docker
|
||
|
||
```bash
|
||
# Iniciar servicio OCR con GPU
|
||
docker compose -f docker-compose.tuning.doctr.yml up -d doctr-gpu
|
||
|
||
# Ejecutar optimización (64 trials)
|
||
docker compose -f docker-compose.tuning.doctr.yml run raytune --service doctr --samples 64
|
||
|
||
# Detener servicios
|
||
docker compose -f docker-compose.tuning.doctr.yml down
|
||
```
|
||
|
||
Respuesta del servicio OCR:
|
||
```json
|
||
{
|
||
"CER": 0.0149,
|
||
"WER": 0.0762,
|
||
"TIME": 15.8,
|
||
"PAGES": 5,
|
||
"TIME_PER_PAGE": 3.16
|
||
}
|
||
```
|
||
|
||
#### Infraestructura Docker
|
||
|
||
La infraestructura del proyecto se basa en contenedores Docker para garantizar reproducibilidad y aislamiento de dependencias. Se generaron seis imágenes Docker, cada una optimizada para su propósito específico.
|
||
|
||
**Tabla 17.** *Imágenes Docker generadas para el proyecto.*
|
||
|
||
| Imagen | Propósito | Base | Puerto |
|
||
|--------|-----------|------|--------|
|
||
| [`seryus.ddns.net/unir/paddle-ocr-gpu`](https://seryus.ddns.net/unir/-/packages/container/paddle-ocr-gpu/latest) | PaddleOCR con aceleración GPU | `nvidia/cuda:12.4.1-cudnn-runtime` | 8002 |
|
||
| [`seryus.ddns.net/unir/paddle-ocr-cpu`](https://seryus.ddns.net/unir/-/packages/container/paddle-ocr-cpu/latest) | PaddleOCR para entornos sin GPU | `python:3.11-slim` | 8002 |
|
||
| [`seryus.ddns.net/unir/easyocr-gpu`](https://seryus.ddns.net/unir/-/packages/container/easyocr-gpu/latest) | EasyOCR con aceleración GPU | `nvidia/cuda:13.0.2-cudnn-runtime` | 8002* |
|
||
| [`seryus.ddns.net/unir/doctr-gpu`](https://seryus.ddns.net/unir/-/packages/container/doctr-gpu/latest) | DocTR con aceleración GPU | `nvidia/cuda:13.0.2-cudnn-runtime` | 8003 |
|
||
| [`seryus.ddns.net/unir/raytune`](https://seryus.ddns.net/unir/-/packages/container/raytune/latest) | Orquestador Ray Tune | `python:3.12-slim` | - |
|
||
|
||
*Fuente: Elaboración propia. Dockerfiles disponibles en [`src/paddle_ocr/`](https://github.com/seryus/MastersThesis/tree/main/src/paddle_ocr), [`src/easyocr_service/`](https://github.com/seryus/MastersThesis/tree/main/src/easyocr_service), [`src/doctr_service/`](https://github.com/seryus/MastersThesis/tree/main/src/doctr_service), [`src/raytune/`](https://github.com/seryus/MastersThesis/tree/main/src/raytune).*
|
||
|
||
##### Arquitectura de Microservicios
|
||
|
||
```mermaid
|
||
---
|
||
title: "Arquitectura de microservicios para optimización OCR"
|
||
config:
|
||
theme: base
|
||
themeVariables:
|
||
primaryColor: "#E6F4F9"
|
||
primaryTextColor: "#404040"
|
||
primaryBorderColor: "#0098CD"
|
||
lineColor: "#0098CD"
|
||
---
|
||
flowchart TB
|
||
subgraph Host["Host (Ubuntu 24.04)"]
|
||
subgraph Docker["Docker Compose"]
|
||
RT["RayTune\n(Orquestador)"]
|
||
subgraph OCR["Servicios OCR (GPU)"]
|
||
P["PaddleOCR\n:8002"]
|
||
E["EasyOCR\n:8001"]
|
||
D["DocTR\n:8003"]
|
||
end
|
||
end
|
||
GPU["NVIDIA RTX 3060\n(5.66 GB VRAM)"]
|
||
DS[("Dataset\n/app/dataset")]
|
||
RES[("Resultados\n/app/results")]
|
||
end
|
||
|
||
RT -->|"POST /evaluate"| P
|
||
RT -->|"POST /evaluate"| E
|
||
RT -->|"POST /evaluate"| D
|
||
P & E & D --> GPU
|
||
P & E & D --> DS
|
||
RT --> RES
|
||
```
|
||
|
||
##### Estrategia de Build Multi-Stage
|
||
|
||
Los Dockerfiles utilizan una estrategia de build multi-stage para optimizar tiempos de construcción y tamaño de imágenes:
|
||
|
||
```mermaid
|
||
---
|
||
title: "Estrategia de build multi-stage"
|
||
config:
|
||
theme: base
|
||
themeVariables:
|
||
primaryColor: "#E6F4F9"
|
||
primaryTextColor: "#404040"
|
||
primaryBorderColor: "#0098CD"
|
||
lineColor: "#0098CD"
|
||
---
|
||
flowchart LR
|
||
subgraph Stage1["Stage 1: Base"]
|
||
B1["CUDA Runtime"]
|
||
B2["Python + pip"]
|
||
B3["Dependencias OCR"]
|
||
end
|
||
|
||
subgraph Stage2["Stage 2: Deploy"]
|
||
D1["Código aplicación"]
|
||
D2["FastAPI REST"]
|
||
end
|
||
|
||
Stage1 --> Stage2
|
||
|
||
B1 --> B2 --> B3
|
||
D1 --> D2
|
||
```
|
||
|
||
**Ventajas de esta estrategia:**
|
||
1. **Caché de dependencias**: La etapa base (CUDA + dependencias) se cachea y reutiliza
|
||
2. **Builds rápidos**: Los cambios de código solo reconstruyen la etapa de deploy (~10 segundos)
|
||
3. **Imágenes optimizadas**: Solo se incluyen los archivos necesarios para ejecución
|
||
|
||
##### Docker Compose Files
|
||
|
||
El proyecto incluye múltiples archivos Docker Compose para diferentes escenarios de uso:
|
||
|
||
**Tabla 18.** *Archivos Docker Compose del proyecto.*
|
||
|
||
| Archivo | Propósito | Servicios |
|
||
|---------|-----------|-----------|
|
||
| [`docker-compose.tuning.yml`](https://github.com/seryus/MastersThesis/blob/main/src/docker-compose.tuning.yml) | Optimización principal | RayTune + PaddleOCR + DocTR |
|
||
| [`docker-compose.tuning.easyocr.yml`](https://github.com/seryus/MastersThesis/blob/main/src/docker-compose.tuning.easyocr.yml) | Optimización EasyOCR | RayTune + EasyOCR |
|
||
| [`docker-compose.tuning.paddle.yml`](https://github.com/seryus/MastersThesis/blob/main/src/docker-compose.tuning.paddle.yml) | Optimización PaddleOCR | RayTune + PaddleOCR |
|
||
| [`docker-compose.tuning.doctr.yml`](https://github.com/seryus/MastersThesis/blob/main/src/docker-compose.tuning.doctr.yml) | Optimización DocTR | RayTune + DocTR |
|
||
|
||
*Fuente: Elaboración propia.*
|
||
|
||
> **Nota:** EasyOCR y PaddleOCR utilizan el mismo puerto (8002). Debido a limitaciones de recursos GPU (VRAM insuficiente para ejecutar múltiples modelos OCR simultáneamente), solo se ejecuta un servicio a la vez durante los experimentos. Por esta razón, EasyOCR tiene su propio archivo Docker Compose separado.
|
||
|
||
##### Gestión de Volúmenes
|
||
|
||
Se utilizan volúmenes Docker nombrados para persistir los modelos descargados entre ejecuciones:
|
||
|
||
**Tabla 19.** *Volúmenes Docker para caché de modelos.*
|
||
|
||
| Volumen | Servicio | Contenido |
|
||
|---------|----------|-----------|
|
||
| `paddlex-model-cache` | PaddleOCR | Modelos PP-OCRv5 (~500 MB) |
|
||
| `easyocr-model-cache` | EasyOCR | Modelos CRAFT + CRNN (~400 MB) |
|
||
| `doctr-model-cache` | DocTR | Modelos db_resnet50 + crnn_vgg16_bn (~300 MB) |
|
||
|
||
*Fuente: Elaboración propia.*
|
||
|
||
##### Health Checks y Monitorización
|
||
|
||
Todos los servicios implementan health checks para garantizar disponibilidad antes de iniciar la optimización:
|
||
|
||
```yaml
|
||
healthcheck:
|
||
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"]
|
||
interval: 30s
|
||
timeout: 10s
|
||
retries: 3
|
||
start_period: 60s # PaddleOCR: 60s, EasyOCR: 120s, DocTR: 180s
|
||
```
|
||
|
||
Los tiempos de `start_period` varían según el servicio debido al tiempo de carga de modelos:
|
||
- **PaddleOCR**: 60 segundos (modelos más ligeros)
|
||
- **EasyOCR**: 120 segundos (carga de modelos CRAFT)
|
||
- **DocTR**: 180 segundos (modelos ResNet más pesados)
|
||
|
||
##### Flujo de Ejecución Completo
|
||
|
||
```mermaid
|
||
---
|
||
title: "Flujo de ejecución de optimización con Ray Tune"
|
||
config:
|
||
theme: base
|
||
themeVariables:
|
||
primaryColor: "#E6F4F9"
|
||
primaryTextColor: "#404040"
|
||
primaryBorderColor: "#0098CD"
|
||
lineColor: "#0098CD"
|
||
---
|
||
sequenceDiagram
|
||
participant U as Usuario
|
||
participant DC as Docker Compose
|
||
participant RT as RayTune
|
||
participant OCR as Servicio OCR
|
||
participant GPU as GPU
|
||
|
||
U->>DC: docker compose up -d
|
||
DC->>OCR: Iniciar contenedor
|
||
OCR->>GPU: Cargar modelos CUDA
|
||
OCR-->>DC: Health check OK
|
||
|
||
U->>DC: docker compose run raytune
|
||
DC->>RT: Iniciar optimización
|
||
|
||
loop 64 trials
|
||
RT->>RT: Optuna sugiere config
|
||
RT->>OCR: POST /evaluate {config}
|
||
OCR->>GPU: Inferencia OCR
|
||
OCR-->>RT: {CER, WER, TIME}
|
||
RT->>RT: Registrar métricas
|
||
end
|
||
|
||
RT-->>U: Mejor configuración encontrada
|
||
U->>DC: docker compose down
|
||
```
|
||
|
||
##### Reproducibilidad
|
||
|
||
Para reproducir los experimentos:
|
||
|
||
```bash
|
||
# 1. Clonar repositorio
|
||
git clone https://github.com/seryus/MastersThesis.git
|
||
cd MastersThesis/src
|
||
|
||
# 2. Iniciar servicio OCR (requiere nvidia-docker)
|
||
docker compose -f docker-compose.tuning.paddle.yml up -d paddle-ocr-gpu
|
||
|
||
# 3. Verificar health check
|
||
curl http://localhost:8002/health
|
||
|
||
# 4. Ejecutar optimización (64 trials)
|
||
docker compose -f docker-compose.tuning.paddle.yml run raytune \
|
||
--service paddle --samples 64
|
||
|
||
# 5. Resultados en src/results/
|
||
ls -la results/raytune_paddle_results_*.csv
|
||
|
||
# 6. Limpiar
|
||
docker compose -f docker-compose.tuning.paddle.yml down
|
||
```
|
||
|
||
Los resultados de los experimentos están disponibles en:
|
||
- [`src/results/raytune_paddle_results_20260119_122609.csv`](https://github.com/seryus/MastersThesis/blob/main/src/results/raytune_paddle_results_20260119_122609.csv)
|
||
- [`src/results/raytune_easyocr_results_20260119_120204.csv`](https://github.com/seryus/MastersThesis/blob/main/src/results/raytune_easyocr_results_20260119_120204.csv)
|
||
- [`src/results/raytune_doctr_results_20260119_121445.csv`](https://github.com/seryus/MastersThesis/blob/main/src/results/raytune_doctr_results_20260119_121445.csv)
|
||
|
||
#### Dataset Extendido
|
||
|
||
Para la fase de optimización se extendió el dataset:
|
||
|
||
**Tabla 20.** *Características del dataset de optimización.*
|
||
|
||
| Característica | Valor |
|
||
|----------------|-------|
|
||
| Páginas totales | 24 |
|
||
| Páginas por trial | 5 (páginas 5-10) |
|
||
| Estructura | Carpetas `img/` y `txt/` pareadas |
|
||
| Resolución | 300 DPI |
|
||
| Formato imagen | PNG |
|
||
|
||
*Fuente: Elaboración propia.*
|
||
|
||
La clase `ImageTextDataset` gestiona la carga de pares imagen-texto desde la estructura de carpetas pareadas. La implementación está disponible en el repositorio (ver Anexo A).
|
||
|
||
#### Espacio de Búsqueda
|
||
|
||
El espacio de búsqueda se definió considerando los hiperparámetros más relevantes identificados en la documentación de PaddleOCR, utilizando `tune.choice()` para parámetros booleanos y `tune.uniform()` para umbrales continuos. La implementación está disponible en `src/raytune/raytune_ocr.py` (ver Anexo A).
|
||
|
||
**Tabla 21.** *Descripción detallada del espacio de búsqueda.*
|
||
|
||
| Parámetro | Tipo | Rango | Descripción |
|
||
|-----------|------|-------|-------------|
|
||
| `use_doc_orientation_classify` | Booleano | {True, False} | Clasificación de orientación del documento completo |
|
||
| `use_doc_unwarping` | Booleano | {True, False} | Corrección de deformación/curvatura |
|
||
| `textline_orientation` | Booleano | {True, False} | Clasificación de orientación por línea de texto |
|
||
| `text_det_thresh` | Continuo | [0.0, 0.7] | Umbral de probabilidad para píxeles de texto |
|
||
| `text_det_box_thresh` | Continuo | [0.0, 0.7] | Umbral de confianza para cajas detectadas |
|
||
| `text_det_unclip_ratio` | Fijo | 0.0 | Coeficiente de expansión (no explorado) |
|
||
| `text_rec_score_thresh` | Continuo | [0.0, 0.7] | Umbral de confianza de reconocimiento |
|
||
|
||
*Fuente: Documentación de PaddleOCR.*
|
||
|
||
**Justificación del espacio:**
|
||
|
||
1. **Rango [0.0, 0.7] para umbrales**: Se evitan valores extremos (>0.7) que podrían filtrar demasiado texto válido, y se incluye 0.0 para evaluar el impacto de desactivar el filtrado.
|
||
|
||
2. **`text_det_unclip_ratio` fijo**: Por decisión de diseño inicial, este parámetro se mantuvo constante para reducir la dimensionalidad del espacio de búsqueda.
|
||
|
||
3. **Parámetros booleanos completos**: Los tres parámetros de preprocesamiento se exploran completamente para identificar cuáles son necesarios para documentos digitales.
|
||
|
||
#### Configuración de Ray Tune
|
||
|
||
Se configuró Ray Tune con OptunaSearch como algoritmo de búsqueda, optimizando CER en 64 trials con 2 ejecuciones concurrentes. La implementación está disponible en `src/raytune/raytune_ocr.py` (ver Anexo A).
|
||
|
||
**Tabla 22.** *Parámetros de configuración de Ray Tune.*
|
||
|
||
| Parámetro | Valor | Justificación |
|
||
|-----------|-------|---------------|
|
||
| Métrica objetivo | CER | Métrica estándar para OCR |
|
||
| Modo | min | Minimizar tasa de error |
|
||
| Algoritmo | OptunaSearch (TPE) | Eficiente para espacios mixtos |
|
||
| Número de trials | 64 | Balance entre exploración y tiempo |
|
||
| Trials concurrentes | 2 | Limitado por memoria disponible |
|
||
|
||
*Fuente: Elaboración propia.*
|
||
|
||
**Elección de 64 trials:**
|
||
|
||
El número de trials se eligió considerando:
|
||
- Espacio de búsqueda de 7 dimensiones (3 booleanas + 4 continuas)
|
||
- Tiempo estimado por trial: ~6 minutos
|
||
- Tiempo total objetivo: <8 horas
|
||
- Regla empírica: 10× dimensiones = 70 trials mínimo recomendado
|
||
|
||
### Resultados de la Optimización
|
||
|
||
#### Ejecución del Experimento
|
||
|
||
El experimento se ejecutó exitosamente con los siguientes resultados globales:
|
||
|
||
**Tabla 23.** *Resumen de la ejecución del experimento.*
|
||
|
||
| Métrica | Valor |
|
||
|---------|-------|
|
||
| Trials completados | 64/64 |
|
||
| Trials fallidos | 0 |
|
||
| Tiempo total | ~6.4 horas |
|
||
| Tiempo medio por trial | 367.72 segundos |
|
||
| Páginas procesadas | 320 (64 trials × 5 páginas) |
|
||
|
||
*Fuente: Logs de Ray Tune.*
|
||
|
||
#### Estadísticas Descriptivas
|
||
|
||
Del archivo CSV de resultados (`src/results/raytune_paddle_results_20260119_122609.csv`):
|
||
|
||
**Tabla 24.** *Estadísticas descriptivas de los 64 trials.*
|
||
|
||
| Estadística | CER | WER | Tiempo/Página (s) |
|
||
|-------------|-----|-----|-------------------|
|
||
| **count** | 64 | 64 | 64 |
|
||
| **mean** | 2.30% | 9.25% | 0.84 |
|
||
| **std** | 2.20% | 1.78% | 0.53 |
|
||
| **min** | 0.79% | 6.80% | 0.56 |
|
||
| **50%** (mediana) | 0.87% | 8.39% | 0.59 |
|
||
| **max** | 7.30% | 13.20% | 2.22 |
|
||
|
||
*Fuente: `src/results/raytune_paddle_results_20260119_122609.csv`.*
|
||
|
||
**Observaciones:**
|
||
|
||
1. **Baja varianza en CER**: La desviación estándar (2.20%) es similar a la media (2.30%), indicando una distribución relativamente consistente sin valores extremos catastróficos.
|
||
|
||
2. **Mediana vs Media**: La mediana del CER (0.87%) es menor que la media (2.30%), confirmando una distribución ligeramente sesgada hacia valores bajos.
|
||
|
||
3. **Velocidad GPU**: El tiempo de ejecución promedio es de 0.84 s/página, lo que representa una aceleración significativa respecto a la ejecución en CPU (~69 s/página, 82x más rápido).
|
||
|
||
#### Distribución de Resultados
|
||
|
||
**Tabla 25.** *Distribución de trials por rango de CER.*
|
||
|
||
| Rango CER | Número de trials | Porcentaje |
|
||
|-----------|------------------|------------|
|
||
| < 2% | 43 | 67.2% |
|
||
| 2% - 5% | 10 | 15.6% |
|
||
| 5% - 10% | 11 | 17.2% |
|
||
| > 10% | 0 | 0.0% |
|
||
|
||
*Fuente: Elaboración propia a partir de `src/results/raytune_paddle_results_20260119_122609.csv`.*
|
||
|
||
La mayoría de trials (67.2%) alcanzaron CER < 2%, cumpliendo el objetivo establecido. Ningún trial presentó fallos catastróficos (CER > 10%), demostrando la estabilidad de la optimización con GPU.
|
||
|
||
#### Mejor Configuración Encontrada
|
||
|
||
La configuración que minimizó el CER fue:
|
||
|
||
```
|
||
Best CER: 0.007884 (0.79%)
|
||
Best WER: 0.077848 (7.78%)
|
||
|
||
Configuración óptima:
|
||
textline_orientation: True
|
||
use_doc_orientation_classify: True
|
||
use_doc_unwarping: False
|
||
text_det_thresh: 0.0462
|
||
text_det_box_thresh: 0.4862
|
||
text_det_unclip_ratio: 0.0
|
||
text_rec_score_thresh: 0.5658
|
||
```
|
||
|
||
**Tabla 26.** *Configuración óptima identificada.*
|
||
|
||
| Parámetro | Valor óptimo | Valor por defecto | Cambio |
|
||
|-----------|--------------|-------------------|--------|
|
||
| textline_orientation | **True** | False | Activado |
|
||
| use_doc_orientation_classify | **True** | False | Activado |
|
||
| use_doc_unwarping | False | False | Sin cambio |
|
||
| text_det_thresh | **0.0462** | 0.3 | -0.254 |
|
||
| text_det_box_thresh | **0.4862** | 0.6 | -0.114 |
|
||
| text_det_unclip_ratio | 0.0 | 1.5 | -1.5 (fijado) |
|
||
| text_rec_score_thresh | **0.5658** | 0.5 | +0.066 |
|
||
|
||
*Fuente: Análisis de [`src/results/`](https://github.com/seryus/MastersThesis/tree/main/src/results) generados por [`src/run_tuning.py`](https://github.com/seryus/MastersThesis/blob/main/src/run_tuning.py).*
|
||
|
||
#### Análisis de Correlación
|
||
|
||
Se calculó la correlación de Pearson entre los parámetros continuos y las métricas de error:
|
||
|
||
**Tabla 27.** *Correlación de parámetros con CER.*
|
||
|
||
| Parámetro | Correlación con CER | Interpretación |
|
||
|-----------|---------------------|----------------|
|
||
| `text_det_thresh` | **-0.523** | Correlación moderada negativa |
|
||
| `text_det_box_thresh` | +0.226 | Correlación débil positiva |
|
||
| `text_rec_score_thresh` | -0.161 | Correlación débil negativa |
|
||
| `text_det_unclip_ratio` | NaN | Varianza cero (valor fijo) |
|
||
|
||
*Fuente: Análisis de [`src/results/`](https://github.com/seryus/MastersThesis/tree/main/src/results) generados por [`src/run_tuning.py`](https://github.com/seryus/MastersThesis/blob/main/src/run_tuning.py).*
|
||
|
||
**Tabla 28.** *Correlación de parámetros con WER.*
|
||
|
||
| Parámetro | Correlación con WER | Interpretación |
|
||
|-----------|---------------------|----------------|
|
||
| `text_det_thresh` | **-0.521** | Correlación moderada negativa |
|
||
| `text_det_box_thresh` | +0.227 | Correlación débil positiva |
|
||
| `text_rec_score_thresh` | -0.173 | Correlación débil negativa |
|
||
|
||
*Fuente: Análisis de [`src/results/`](https://github.com/seryus/MastersThesis/tree/main/src/results) generados por [`src/run_tuning.py`](https://github.com/seryus/MastersThesis/blob/main/src/run_tuning.py).*
|
||
|
||
**Hallazgo clave**: El parámetro `text_det_thresh` muestra la correlación más fuerte (-0.52 con ambas métricas), indicando que valores más altos de este umbral tienden a reducir el error. Este umbral controla qué píxeles se consideran "texto" en el mapa de probabilidad del detector.
|
||
|
||
#### Impacto del Parámetro textline_orientation
|
||
|
||
El parámetro booleano `textline_orientation` demostró tener el mayor impacto en el rendimiento:
|
||
|
||
**Tabla 29.** *Impacto del parámetro textline_orientation.*
|
||
|
||
| textline_orientation | CER Medio | CER Std | WER Medio | N trials |
|
||
|---------------------|-----------|---------|-----------|----------|
|
||
| True | 3.76% | 7.12% | 12.73% | 32 |
|
||
| False | 12.40% | 14.93% | 21.71% | 32 |
|
||
|
||
*Fuente: Análisis de [`src/results/`](https://github.com/seryus/MastersThesis/tree/main/src/results) generados por [`src/run_tuning.py`](https://github.com/seryus/MastersThesis/blob/main/src/run_tuning.py).*
|
||
|
||
**Interpretación:**
|
||
|
||
1. **Reducción del CER**: Con `textline_orientation=True`, el CER medio es 3.3 veces menor (3.76% vs 12.40%).
|
||
|
||
2. **Menor varianza**: La desviación estándar también se reduce significativamente (7.12% vs 14.93%), indicando resultados más consistentes.
|
||
|
||
3. **Reducción del CER**: 69.7% cuando se habilita la clasificación de orientación de línea.
|
||
|
||
```mermaid
|
||
---
|
||
title: "Impacto de textline_orientation en CER"
|
||
config:
|
||
theme: base
|
||
themeVariables:
|
||
primaryColor: "#E6F4F9"
|
||
primaryTextColor: "#404040"
|
||
primaryBorderColor: "#0098CD"
|
||
lineColor: "#0098CD"
|
||
---
|
||
xychart-beta
|
||
x-axis ["textline_orientation=False", "textline_orientation=True"]
|
||
y-axis "CER (%)" 0 --> 15
|
||
bar [12.40, 3.76]
|
||
```
|
||
|
||
**Explicación técnica:**
|
||
|
||
El parámetro `textline_orientation` activa un clasificador que determina la orientación de cada línea de texto detectada. Para documentos con layouts mixtos (tablas, encabezados laterales, direcciones postales), este clasificador asegura que el texto se lea en el orden correcto, evitando la mezcla de líneas de diferentes columnas o secciones.
|
||
|
||
#### Análisis de Fallos Catastróficos
|
||
|
||
Los trials con CER muy alto (>20%) presentaron patrones específicos:
|
||
|
||
**Tabla 30.** *Características de trials con fallos catastróficos.*
|
||
|
||
| Trial | CER | text_det_thresh | textline_orientation | Diagnóstico |
|
||
|-------|-----|-----------------|---------------------|-------------|
|
||
| #47 | 51.61% | 0.017 | True | Umbral muy bajo |
|
||
| #23 | 43.29% | 0.042 | False | Umbral bajo + sin orientación |
|
||
| #12 | 38.76% | 0.089 | False | Umbral bajo + sin orientación |
|
||
| #56 | 35.12% | 0.023 | False | Umbral muy bajo + sin orientación |
|
||
|
||
*Fuente: Análisis del CSV de resultados.*
|
||
|
||
**Diagnóstico:**
|
||
|
||
1. **Umbral de detección muy bajo** (`text_det_thresh` < 0.1): Genera exceso de falsos positivos en la detección, incluyendo artefactos, manchas y ruido como "texto".
|
||
|
||
2. **Desactivación de orientación**: Sin el clasificador de orientación, las líneas de texto pueden mezclarse incorrectamente, especialmente en tablas.
|
||
|
||
3. **Combinación fatal**: La peor combinación es umbral bajo + sin orientación, que produce textos completamente desordenados y con inserciones de ruido.
|
||
|
||
**Recomendación**: Evitar `text_det_thresh` < 0.1 en cualquier configuración.
|
||
|
||
### Comparación Baseline vs Optimizado
|
||
|
||
#### Evaluación sobre Dataset Completo
|
||
|
||
La configuración óptima identificada se evaluó sobre el dataset completo de 45 páginas, comparando con la configuración baseline (valores por defecto de PaddleOCR). Los parámetros optimizados más relevantes fueron: `textline_orientation=True`, `use_doc_orientation_classify=True`, `text_det_thresh=0.0462`, `text_det_box_thresh=0.4862`, y `text_rec_score_thresh=0.5658`.
|
||
|
||
**Tabla 31.** *Comparación baseline vs optimizado (45 páginas).*
|
||
|
||
| Modelo | CER | Precisión Caracteres | WER | Precisión Palabras |
|
||
|--------|-----|---------------------|-----|-------------------|
|
||
| PaddleOCR (Baseline) | 8.85% | 91.15% | 13.05% | 86.95% |
|
||
| PaddleOCR-HyperAdjust | **7.72%** | **92.28%** | **11.40%** | **88.60%** |
|
||
|
||
*Fuente: Validación final. Código en [`src/run_tuning.py`](https://github.com/seryus/MastersThesis/blob/main/src/run_tuning.py), resultados en [`src/results/`](https://github.com/seryus/MastersThesis/tree/main/src/results).*
|
||
|
||
> **Nota sobre generalización:** El mejor trial individual (5 páginas) alcanzó un CER de 0.79%, cumpliendo el objetivo de CER < 2%. Sin embargo, al aplicar la configuración al dataset completo de 45 páginas, el CER aumentó a 7.72%, evidenciando sobreajuste al subconjunto de entrenamiento. Esta diferencia es un hallazgo importante que se discute en la sección de análisis.
|
||
|
||
#### Métricas de Mejora
|
||
|
||
**Tabla 32.** *Análisis cuantitativo de la mejora.*
|
||
|
||
| Forma de Medición | CER | WER |
|
||
|-------------------|-----|-----|
|
||
| Valor baseline | 8.85% | 13.05% |
|
||
| Valor optimizado | 7.72% | 11.40% |
|
||
| Mejora absoluta | -1.13 pp | -1.65 pp |
|
||
| Reducción relativa del error | **12.8%** | **12.6%** |
|
||
| Factor de mejora | 1.15× | 1.14× |
|
||
| **Mejor trial (5 páginas)** | **0.79%** | **7.78%** |
|
||
|
||
*Fuente: Elaboración propia.*
|
||
|
||
```mermaid
|
||
---
|
||
title: "Reducción de errores: Baseline vs Optimizado (45 páginas)"
|
||
config:
|
||
theme: base
|
||
themeVariables:
|
||
primaryColor: "#E6F4F9"
|
||
primaryTextColor: "#404040"
|
||
primaryBorderColor: "#0098CD"
|
||
lineColor: "#0098CD"
|
||
---
|
||
xychart-beta
|
||
x-axis ["CER Baseline", "CER Optimizado", "WER Baseline", "WER Optimizado"]
|
||
y-axis "Tasa de error (%)" 0 --> 16
|
||
bar [8.85, 7.72, 13.05, 11.40]
|
||
```
|
||
|
||
*Leyenda: CER = Character Error Rate, WER = Word Error Rate. Baseline = configuración por defecto de PaddleOCR. Optimizado = configuración encontrada por Ray Tune. Los valores corresponden al dataset completo de 45 páginas.*
|
||
|
||
#### Impacto Práctico
|
||
|
||
**En un documento típico de 10,000 caracteres:**
|
||
|
||
| Configuración | Caracteres con error | Palabras con error* |
|
||
|---------------|---------------------|---------------------|
|
||
| Baseline | ~885 | ~196 |
|
||
| Optimizada (full dataset) | ~772 | ~171 |
|
||
| Optimizada (mejor trial) | ~79 | ~117 |
|
||
| **Reducción (full dataset)** | **113 menos** | **25 menos** |
|
||
|
||
*Asumiendo longitud media de palabra = 6.6 caracteres en español.
|
||
|
||
**Interpretación:**
|
||
|
||
> "La optimización de hiperparámetros logró una mejora del 12.8% en el CER sobre el dataset completo de 45 páginas. Aunque esta mejora es más modesta que la observada en los trials individuales (donde se alcanzó 0.79% CER), demuestra el valor de la optimización sistemática. La diferencia entre el mejor trial (0.79%) y el resultado en dataset completo (7.72%) revela un fenómeno de sobreajuste al subconjunto de 5 páginas usado para evaluación."
|
||
|
||
### Tiempo de Ejecución
|
||
|
||
**Tabla 33.** *Métricas de tiempo del experimento (GPU).*
|
||
|
||
| Métrica | Valor |
|
||
|---------|-------|
|
||
| Tiempo total del experimento | ~1.5 horas |
|
||
| Tiempo medio por trial | ~4.2 segundos |
|
||
| Tiempo medio por página | 0.84 segundos |
|
||
| Variabilidad (std) | 0.53 segundos/página |
|
||
| Páginas procesadas totales | 320 |
|
||
|
||
*Fuente: [`src/results/raytune_paddle_results_20260119_122609.csv`](https://github.com/seryus/MastersThesis/blob/main/src/results/raytune_paddle_results_20260119_122609.csv).*
|
||
|
||
**Observaciones:**
|
||
|
||
1. El tiempo por página (~0.84 segundos) corresponde a ejecución con GPU (RTX 3060).
|
||
2. La variabilidad del tiempo es moderada (std = 0.53 s/página), con algunos trials más lentos debido a configuraciones con módulos de preprocesamiento activos.
|
||
3. En comparación, la ejecución en CPU requiere ~69 segundos/página (82× más lento), lo que justifica el uso de GPU para optimización y producción.
|
||
|
||
### Resumen de la Sección
|
||
|
||
Esta sección ha presentado:
|
||
|
||
1. **Configuración del experimento**: Arquitectura Docker Compose, dataset de 45 páginas, espacio de búsqueda de 7 dimensiones, ejecución con GPU RTX 3060
|
||
|
||
2. **Resultados estadísticos**:
|
||
- CER medio: 2.30% (std: 2.20%)
|
||
- CER mínimo (mejor trial): **0.79%**
|
||
- 67.2% de trials con CER < 2%
|
||
|
||
3. **Hallazgos clave**:
|
||
- `textline_orientation=True` y `use_doc_orientation_classify=True` son críticos
|
||
- `text_det_thresh` bajo (0.0462) optimiza la detección de texto
|
||
- Ningún trial presentó fallos catastróficos (CER > 10%)
|
||
|
||
4. **Mejora en dataset completo**: CER reducido de 8.85% a 7.72% (reducción del 12.8%)
|
||
|
||
5. **Observación sobre generalización**: El mejor trial (0.79%) no generalizó completamente al dataset completo (7.72%), evidenciando sobreajuste al subconjunto de 5 páginas
|
||
|
||
**Fuentes de datos:**
|
||
- [`src/run_tuning.py`](https://github.com/seryus/MastersThesis/blob/main/src/run_tuning.py): Script principal de optimización
|
||
- [`src/raytune_ocr.py`](https://github.com/seryus/MastersThesis/blob/main/src/raytune_ocr.py): Librería de utilidades Ray Tune
|
||
- [`src/results/raytune_paddle_results_20260119_122609.csv`](https://github.com/seryus/MastersThesis/blob/main/src/results/raytune_paddle_results_20260119_122609.csv): Resultados CSV de los 64 trials
|
||
|
||
## Discusión y análisis de resultados
|
||
|
||
### Introducción
|
||
|
||
Esta sección presenta un análisis consolidado de los resultados obtenidos en las fases de benchmark comparativo y optimización de hiperparámetros. Se discuten las implicaciones prácticas, se evalúa el cumplimiento de los objetivos planteados y se identifican las limitaciones del estudio.
|
||
|
||
### Resumen Consolidado de Resultados
|
||
|
||
#### Progresión del Rendimiento
|
||
|
||
**Tabla 34.** *Evolución del rendimiento a través del estudio.*
|
||
|
||
| Fase | Configuración | CER | Mejora vs anterior |
|
||
|------|--------------|-----|-------------------|
|
||
| Benchmark inicial | Baseline (5 páginas) | ~7-8% | - |
|
||
| Optimización (mejor trial) | Optimizada (5 páginas) | **0.79%** | ~90% vs baseline |
|
||
| Validación final | Optimizada (45 páginas) | 7.72% | 12.8% vs baseline |
|
||
|
||
*Fuente: Elaboración propia.*
|
||
|
||
El incremento del CER de 0.79% (5 páginas) a 7.72% (45 páginas) evidencia sobreajuste al subconjunto de optimización. Este fenómeno es esperado cuando se optimiza sobre un subconjunto pequeño y se valida sobre el dataset completo con mayor diversidad de layouts.
|
||
|
||
#### Comparación con Objetivo
|
||
|
||
**Tabla 35.** *Verificación del objetivo general.*
|
||
|
||
| Aspecto | Objetivo | Resultado (trial) | Resultado (full) | Cumplimiento |
|
||
|---------|----------|-------------------|------------------|--------------|
|
||
| Métrica | CER | CER | CER | ✓ |
|
||
| Umbral | < 2% | **0.79%** | 7.72% | Parcial |
|
||
| Método | Sin fine-tuning | Solo hiperparámetros | Solo hiperparámetros | ✓ |
|
||
| Hardware | GPU | RTX 3060 | RTX 3060 | ✓ |
|
||
|
||
*Fuente: Elaboración propia.*
|
||
|
||
> **Análisis del cumplimiento:** El objetivo de CER < 2% se cumple en el mejor trial individual (0.79%), demostrando que la optimización de hiperparámetros puede alcanzar la precisión objetivo. Sin embargo, la validación sobre el dataset completo (7.72%) muestra que la generalización requiere trabajo adicional, como un subconjunto de optimización más representativo o técnicas de regularización.
|
||
|
||
### Análisis Detallado de Hiperparámetros
|
||
|
||
#### Jerarquía de Importancia
|
||
|
||
Basándose en el análisis de los resultados de optimización:
|
||
|
||
**Tabla 36.** *Ranking de importancia de hiperparámetros.*
|
||
|
||
| Rank | Parámetro | Impacto | Evidencia |
|
||
|------|-----------|---------|-----------|
|
||
| 1 | `textline_orientation` | **Crítico** | Presente en todos los mejores trials |
|
||
| 2 | `use_doc_orientation_classify` | **Alto** | Activado en configuración óptima |
|
||
| 3 | `text_det_thresh` | **Alto** | Valor óptimo bajo (0.0462) |
|
||
| 4 | `text_det_box_thresh` | Medio | Moderado (0.4862) |
|
||
| 5 | `text_rec_score_thresh` | Medio | Moderado (0.5658) |
|
||
| 6 | `use_doc_unwarping` | Nulo | Desactivado en configuración óptima |
|
||
|
||
*Fuente: Elaboración propia basada en [`src/results/raytune_paddle_results_20260119_122609.csv`](https://github.com/seryus/MastersThesis/blob/main/src/results/raytune_paddle_results_20260119_122609.csv).*
|
||
|
||
#### Análisis del Parámetro textline_orientation
|
||
|
||
**Por qué es tan importante:**
|
||
|
||
El clasificador de orientación de línea resuelve un problema fundamental en documentos con layouts complejos: determinar el orden correcto de lectura. Sin este clasificador:
|
||
|
||
1. Las líneas de una tabla pueden mezclarse con texto adyacente
|
||
2. Los encabezados laterales pueden insertarse en posiciones incorrectas
|
||
3. El texto en columnas puede leerse en orden incorrecto
|
||
|
||
Para documentos académicos que típicamente incluyen tablas, listas y encabezados multinivel, este clasificador es esencial.
|
||
|
||
**Recomendación**: Siempre activar `textline_orientation=True` para documentos estructurados.
|
||
|
||
#### Análisis del Parámetro text_det_thresh
|
||
|
||
**Comportamiento observado:**
|
||
|
||
| Rango | CER típico | Comportamiento |
|
||
|-------|------------|----------------|
|
||
| 0.0 - 0.1 | 1-3% | Detecta más texto, incluyendo bordes |
|
||
| 0.1 - 0.3 | 2-5% | Rendimiento variable |
|
||
| 0.3 - 0.5 | 3-7% | Balance precisión/recall |
|
||
| 0.5 - 0.7 | 4-7% | Más conservador |
|
||
|
||
**Interpretación:**
|
||
|
||
- En ejecución GPU con modelos Mobile, valores bajos de `text_det_thresh` funcionan bien
|
||
- El valor óptimo (0.0462) indica que una detección más sensible beneficia el rendimiento
|
||
- A diferencia de CPU, no se observaron fallos catastróficos con valores bajos
|
||
|
||
**Valor óptimo encontrado**: 0.0462
|
||
|
||
#### Análisis de Parámetros de Preprocesamiento
|
||
|
||
**`use_doc_orientation_classify`:**
|
||
|
||
En la configuración óptima GPU, este parámetro está **activado** (True), a diferencia de lo observado en experimentos anteriores. Esto sugiere que la clasificación de orientación del documento puede beneficiar incluso documentos digitales cuando se combina con `textline_orientation=True`.
|
||
|
||
**`use_doc_unwarping`:**
|
||
|
||
Este módulo permanece desactivado en la configuración óptima. Está diseñado para:
|
||
- Documentos escaneados con rotación
|
||
- Fotografías de documentos con perspectiva
|
||
- Documentos curvados o deformados
|
||
|
||
Para documentos PDF digitales como los evaluados, este módulo es innecesario y puede introducir artefactos.
|
||
|
||
### Análisis de Casos de Fallo
|
||
|
||
#### Clasificación de Errores
|
||
|
||
**Tabla 37.** *Tipología de errores observados.*
|
||
|
||
| Tipo de error | Frecuencia | Ejemplo | Causa probable |
|
||
|---------------|------------|---------|----------------|
|
||
| Pérdida de acentos | Alta | más → mas | Modelo de reconocimiento |
|
||
| Duplicación de caracteres | Media | titulación → titulacióon | Solapamiento de detecciones |
|
||
| Confusión de puntuación | Media | ¿ → ? | Caracteres similares |
|
||
| Pérdida de eñe | Baja | año → ano | Modelo de reconocimiento |
|
||
| Texto desordenado | Variable | Mezcla de líneas | Fallo de orientación |
|
||
|
||
*Fuente: Análisis cualitativo.*
|
||
|
||
#### Patrones de Fallo por Tipo de Contenido
|
||
|
||
**Tabla 38.** *Tasa de error por tipo de contenido.*
|
||
|
||
| Tipo de contenido | CER estimado | Factor de riesgo |
|
||
|-------------------|--------------|------------------|
|
||
| Párrafos de texto | ~1% | Bajo |
|
||
| Listas numeradas | ~2% | Medio |
|
||
| Tablas simples | ~3% | Medio |
|
||
| Encabezados + pie de página | ~2% | Medio |
|
||
| Tablas complejas | ~5% | Alto |
|
||
| Texto en columnas | ~4% | Alto |
|
||
|
||
*Fuente: Estimación cualitativa.*
|
||
|
||
### Comparación con Objetivos Específicos
|
||
|
||
**Tabla 39.** *Cumplimiento de objetivos específicos.*
|
||
|
||
| Objetivo | Descripción | Resultado | Estado |
|
||
|----------|-------------|-----------|--------|
|
||
| OE1 | Comparar soluciones OCR | EasyOCR, PaddleOCR, DocTR evaluados; PaddleOCR seleccionado | ✓ Cumplido |
|
||
| OE2 | Preparar dataset de evaluación | 45 páginas con ground truth | ✓ Cumplido |
|
||
| OE3 | Identificar hiperparámetros críticos | `textline_orientation`, `use_doc_orientation_classify`, `text_det_thresh` identificados | ✓ Cumplido |
|
||
| OE4 | Optimizar con Ray Tune (≥50 trials) | 64 trials ejecutados con GPU | ✓ Cumplido |
|
||
| OE5 | Validar configuración optimizada | CER: 8.85% → 7.72% (dataset), 0.79% (mejor trial) | ✓ Parcial |
|
||
|
||
*Fuente: Elaboración propia.*
|
||
|
||
> **Nota sobre OE5:** El objetivo de CER < 2% se cumple en el mejor trial individual (0.79%). La validación sobre el dataset completo (7.72%) muestra que la generalización requiere mayor trabajo, identificándose como línea de trabajo futuro.
|
||
|
||
### Limitaciones del Estudio
|
||
|
||
#### Limitaciones de Generalización
|
||
|
||
1. **Tipo de documento único**: Solo se evaluaron documentos académicos de UNIR. La configuración óptima puede no ser transferible a otros tipos de documentos (facturas, formularios, contratos).
|
||
|
||
2. **Idioma único**: El estudio se centró en español. Otros idiomas con diferentes características ortográficas podrían requerir configuraciones diferentes.
|
||
|
||
3. **Formato único**: Solo se evaluaron PDFs digitales. Documentos escaneados o fotografías de documentos podrían beneficiarse de diferentes configuraciones.
|
||
|
||
#### Limitaciones Metodológicas
|
||
|
||
1. **Ground truth automático**: El texto de referencia se extrajo programáticamente del PDF, lo cual puede introducir errores en layouts complejos donde el orden de lectura no es evidente.
|
||
|
||
2. **Tamaño del dataset**: 45 páginas es un dataset limitado. Un dataset más amplio proporcionaría estimaciones más robustas.
|
||
|
||
3. **Parámetro fijo**: `text_det_unclip_ratio` se mantuvo en 0.0 durante todo el experimento. Explorar este parámetro podría revelar mejoras adicionales.
|
||
|
||
4. **Subconjunto de ajuste limitado**: El ajuste de hiperparámetros se realizó sobre 5 páginas (páginas 5-10), lo que contribuyó al sobreajuste observado en la validación del dataset completo.
|
||
|
||
#### Limitaciones de Validación
|
||
|
||
1. **Sin validación cruzada**: No se realizó validación cruzada sobre diferentes subconjuntos del dataset.
|
||
|
||
2. **Sin test set independiente**: El dataset de validación final se solapaba parcialmente con el de optimización.
|
||
|
||
### Implicaciones Prácticas
|
||
|
||
#### Guía de Configuración Recomendada
|
||
|
||
Para documentos académicos en español similares a los evaluados:
|
||
|
||
**Tabla 40.** *Configuración recomendada para PaddleOCR con GPU.*
|
||
|
||
| Parámetro | Valor | Prioridad | Justificación |
|
||
|-----------|-------|-----------|---------------|
|
||
| `textline_orientation` | True | Obligatorio | Crítico para layouts complejos |
|
||
| `use_doc_orientation_classify` | True | Recomendado | Mejora orientación de documento |
|
||
| `text_det_thresh` | 0.05 (rango: 0.04-0.10) | Recomendado | Detección sensible beneficia resultados |
|
||
| `text_det_box_thresh` | 0.49 (rango: 0.4-0.6) | Recomendado | Balance de confianza |
|
||
| `text_rec_score_thresh` | 0.57 (rango: 0.5-0.7) | Opcional | Filtra reconocimientos poco confiables |
|
||
| `use_doc_unwarping` | False | No recomendado | Innecesario para PDFs digitales |
|
||
|
||
*Fuente: Análisis de [`src/results/raytune_paddle_results_20260119_122609.csv`](https://github.com/seryus/MastersThesis/blob/main/src/results/raytune_paddle_results_20260119_122609.csv).*
|
||
|
||
#### Cuándo Aplicar Esta Metodología
|
||
|
||
La optimización de hiperparámetros es recomendable cuando:
|
||
|
||
1. **GPU disponible**: Acelera significativamente la exploración del espacio de hiperparámetros (82× más rápido que CPU).
|
||
|
||
2. **Modelo preentrenado adecuado**: El modelo ya soporta el idioma objetivo (como PaddleOCR para español).
|
||
|
||
3. **Dominio específico**: Se busca optimizar para un tipo de documento particular.
|
||
|
||
4. **Mejora incremental**: El rendimiento baseline es aceptable pero mejorable.
|
||
|
||
5. **Sin datos de entrenamiento**: No se dispone de datasets etiquetados para fine-tuning.
|
||
|
||
#### Cuándo NO Aplicar Esta Metodología
|
||
|
||
La optimización de hiperparámetros puede ser insuficiente cuando:
|
||
|
||
1. **Idioma no soportado**: El modelo no incluye el idioma en su vocabulario.
|
||
|
||
2. **Escritura manuscrita**: Requiere fine-tuning o modelos especializados.
|
||
|
||
3. **Documentos muy degradados**: Escaneos de baja calidad o documentos históricos.
|
||
|
||
4. **Requisitos de CER < 0.5%**: Puede requerir fine-tuning para alcanzar precisiones muy altas.
|
||
|
||
### Resumen del Capítulo
|
||
|
||
Este capítulo ha presentado el desarrollo completo de la contribución:
|
||
|
||
**Planteamiento de la comparativa:**
|
||
- Evaluación de EasyOCR, PaddleOCR y DocTR
|
||
- Selección de PaddleOCR por su configurabilidad
|
||
|
||
**Desarrollo de la comparativa:**
|
||
- 64 trials de Ray Tune con Optuna usando GPU RTX 3060
|
||
- Identificación de `textline_orientation`, `use_doc_orientation_classify` y `text_det_thresh` como críticos
|
||
- CER mínimo alcanzado en trial individual: **0.79%**
|
||
|
||
**Discusión y análisis:**
|
||
- Mejora del CER en dataset completo de 8.85% a 7.72% (reducción del **12.8%**)
|
||
- Mejor trial: 0.79% CER (cumple objetivo CER < 2%)
|
||
- Identificación de sobreajuste y recomendaciones prácticas
|
||
|
||
**Resultados principales**:
|
||
- El objetivo de CER < 2% se cumple en el mejor trial (0.79%)
|
||
- La generalización al dataset completo (7.72%) revela sobreajuste que requiere trabajo futuro
|
||
- La optimización de hiperparámetros con GPU es viable y eficiente (82× más rápido que CPU)
|
||
|
||
**Fuentes de datos:**
|
||
- [`src/run_tuning.py`](https://github.com/seryus/MastersThesis/blob/main/src/run_tuning.py): Script principal de optimización
|
||
- [`src/results/raytune_paddle_results_20260119_122609.csv`](https://github.com/seryus/MastersThesis/blob/main/src/results/raytune_paddle_results_20260119_122609.csv): Resultados CSV de PaddleOCR
|
||
- [`src/results/raytune_easyocr_results_20260119_120204.csv`](https://github.com/seryus/MastersThesis/blob/main/src/results/raytune_easyocr_results_20260119_120204.csv): Resultados CSV de EasyOCR
|
||
- [`src/results/raytune_doctr_results_20260119_121445.csv`](https://github.com/seryus/MastersThesis/blob/main/src/results/raytune_doctr_results_20260119_121445.csv): Resultados CSV de DocTR
|
||
|
||
**Imágenes Docker:**
|
||
- [`seryus.ddns.net/unir/paddle-ocr-gpu`](https://seryus.ddns.net/unir/-/packages/container/paddle-ocr-gpu/latest): PaddleOCR con soporte GPU
|
||
- [`seryus.ddns.net/unir/easyocr-gpu`](https://seryus.ddns.net/unir/-/packages/container/easyocr-gpu/latest): EasyOCR con soporte GPU
|
||
- [`seryus.ddns.net/unir/doctr-gpu`](https://seryus.ddns.net/unir/-/packages/container/doctr-gpu/latest): DocTR con soporte GPU
|
||
|
||
### Comparativa de Rendimiento CPU vs GPU
|
||
|
||
Esta sección presenta la comparación de rendimiento entre ejecución en CPU y GPU, justificando la elección de GPU para el experimento principal y demostrando el impacto práctico de la aceleración por hardware.
|
||
|
||
#### Configuración del Entorno GPU
|
||
|
||
**Tabla 41.** *Especificaciones del entorno GPU utilizado.*
|
||
|
||
| Componente | Especificación |
|
||
|------------|----------------|
|
||
| GPU | NVIDIA GeForce RTX 3060 Laptop |
|
||
| VRAM | 5.66 GB |
|
||
| CUDA | 12.4 |
|
||
| Sistema Operativo | Ubuntu 24.04.3 LTS |
|
||
| Kernel | 6.14.0-37-generic |
|
||
|
||
*Fuente: Elaboración propia.*
|
||
|
||
Este hardware representa configuración típica de desarrollo, permitiendo evaluar el rendimiento en condiciones realistas de despliegue.
|
||
|
||
#### Comparación CPU vs GPU
|
||
|
||
Se comparó el tiempo de procesamiento entre CPU y GPU utilizando los datos de [`src/raytune_paddle_subproc_results_20251207_192320.csv`](https://github.com/seryus/MastersThesis/blob/main/src/raytune_paddle_subproc_results_20251207_192320.csv) (CPU) y [`src/results/raytune_paddle_results_20260119_122609.csv`](https://github.com/seryus/MastersThesis/blob/main/src/results/raytune_paddle_results_20260119_122609.csv) (GPU).
|
||
|
||
**Tabla 42.** *Rendimiento comparativo CPU vs GPU.*
|
||
|
||
| Métrica | CPU | GPU (RTX 3060) | Factor de Aceleración |
|
||
|---------|-----|----------------|----------------------|
|
||
| Tiempo/Página (promedio) | 69.4s | 0.84s | **82x** |
|
||
| Dataset completo (45 páginas) | ~52 min | ~38 seg | **82x** |
|
||
| 64 trials × 5 páginas | ~6.4 horas | ~1.5 horas | **4.3x** |
|
||
|
||
*Fuente: Elaboración propia a partir de [`src/raytune_paddle_subproc_results_20251207_192320.csv`](https://github.com/seryus/MastersThesis/blob/main/src/raytune_paddle_subproc_results_20251207_192320.csv) y [`src/results/raytune_paddle_results_20260119_122609.csv`](https://github.com/seryus/MastersThesis/blob/main/src/results/raytune_paddle_results_20260119_122609.csv).*
|
||
|
||
La aceleración de 82× obtenida con GPU transforma la viabilidad del enfoque:
|
||
- **Optimización en CPU (6.4 horas)**: Viable pero lento para iteraciones rápidas
|
||
- **Optimización en GPU (1.5 horas)**: Permite explorar más configuraciones y realizar múltiples experimentos
|
||
- **Producción con GPU (0.84s/página)**: Habilita procesamiento en tiempo real
|
||
|
||
#### Comparación de Modelos PaddleOCR
|
||
|
||
PaddleOCR ofrece dos variantes de modelos: Mobile (optimizados para dispositivos con recursos limitados) y Server (mayor precisión a costa de mayor consumo de memoria). Se evaluó la viabilidad de ambas variantes en el hardware disponible.
|
||
|
||
**Tabla 43.** *Comparación de modelos Mobile vs Server en RTX 3060.*
|
||
|
||
| Modelo | VRAM Requerida | Resultado | Recomendación |
|
||
|--------|----------------|-----------|---------------|
|
||
| PP-OCRv5 Mobile | 0.06 GB | Funciona correctamente | ✓ Recomendado |
|
||
| PP-OCRv5 Server | 5.3 GB | OOM en página 2 | ✗ Requiere >8 GB VRAM |
|
||
|
||
*Fuente: Elaboración propia.*
|
||
|
||
Los modelos Server, a pesar de ofrecer potencialmente mayor precisión, resultan inviables en hardware con VRAM limitada (≤6 GB) debido a errores de memoria (Out of Memory). Los modelos Mobile, con un consumo de memoria 88 veces menor, funcionan de manera estable y ofrecen rendimiento suficiente para el caso de uso evaluado.
|
||
|
||
#### Conclusiones de la Validación GPU
|
||
|
||
La validación con aceleración GPU permite extraer las siguientes conclusiones:
|
||
|
||
1. **Aceleración significativa**: La GPU proporciona una aceleración de 82× sobre CPU, haciendo viable el procesamiento en tiempo real para aplicaciones interactivas.
|
||
|
||
2. **Modelos Mobile recomendados**: Para hardware con VRAM limitada (≤6 GB), los modelos Mobile de PP-OCRv5 ofrecen el mejor balance entre precisión y recursos, funcionando de manera estable sin errores de memoria.
|
||
|
||
3. **Viabilidad práctica**: Con GPU, el procesamiento de un documento completo (45 páginas) toma menos de 30 segundos, validando la aplicabilidad en entornos de producción donde el tiempo de respuesta es crítico.
|
||
|
||
4. **Escalabilidad**: La arquitectura de microservicios dockerizados utilizada para la validación GPU facilita el despliegue horizontal, permitiendo escalar el procesamiento según demanda.
|
||
|
||
Esta validación demuestra que la configuración optimizada mediante Ray Tune mejora la precisión (CER: 8.85% → 7.72% en dataset completo, 0.79% en mejor trial individual) y, combinada con aceleración GPU, resulta prácticamente aplicable en escenarios de producción real.
|