7. Análisis de hiperparámetros
Todos los hiperparámetros del proyecto, con su función, valor por defecto, dónde se define, rango recomendado, impacto y qué pasa si sube o baja. Un hiperparámetro es un valor que tú eliges antes de entrenar (a diferencia de los pesos, que el modelo aprende).
7.1. Mapa de dónde vive cada hiperparámetro
| Fuente | Hiperparámetros |
|---|---|
config/dataset.yaml | target_size, seed, minority_ratio_threshold, max_images_per_class, config de LIME |
Flags de train_baselines.py | epochs, batch_size, learning_rate, weight_decay, image_size, num_workers, pretrained |
Hardcodeados en transforms.py | grados de rotación, factores de ColorJitter, scale de crop, sigma de blur |
Hardcodeados en create_splits.py | proporciones 70/15/15, _MIN_STRATUM_IMAGES=7 |
7.2. Hiperparámetros de entrenamiento
learning_rate (default 1e-4)
Función: tamaño del paso al actualizar pesos. El hiperparámetro más influyente.
| Si sube (p.ej. 1e-2) | Si baja (p.ej. 1e-6) |
|---|---|
| Entrena más rápido al inicio; riesgo de divergir (loss explota) o oscilar; puede destruir los pesos preentrenados | Entrena muy lento; puede no converger en 30 épocas; muy estable |
Rango recomendado (fine-tuning): 1e-5 a 1e-3. El 1e-4 elegido es un punto seguro para transfer learning. Riesgo: un LR alto en fine-tuning es especialmente dañino porque borra el conocimiento de ImageNet.
epochs (default 30)
Función: cuántas veces se recorre el dataset completo.
| Si sube | Si baja |
|---|---|
Más oportunidad de aprender; riesgo de sobreajuste en las épocas tardías (mitigado porque se guarda best.pth) | Puede quedar subentrenado (no converge); más rápido |
Nota: como se selecciona best.pth por val macro-F1, subir épocas es relativamente seguro (el sobreajuste tardío no afecta el modelo final, solo gasta cómputo). Los runs reales convergieron cerca de la época 26-30.
batch_size (default 32, auto-escalado)
Función: cuántas imágenes se procesan antes de cada actualización de pesos.
| Si sube (p.ej. 128) | Si baja (p.ej. 8) |
|---|---|
| Gradientes más estables (menos ruido); más rápido por época; más memoria GPU; a veces generaliza algo peor | Gradientes más ruidosos (efecto regularizador); menos memoria; más lento; puede ayudar a escapar de mínimos malos |
Auto-escalado clave: _scale_batch_size lo reduce inversamente al área de la imagen. Para EfficientNet-B4 (380×380 ≈ 2.9× el área de 224), el batch 32 baja a ~11 para caber en memoria. Interacción con LR: cambiar mucho el batch normalmente exige reajustar el LR (regla heurística: LR ∝ batch), aunque el proyecto mantiene LR fijo.
weight_decay (default 1e-4)
Función: fuerza de la regularización L2 (penaliza pesos grandes).
| Si sube (p.ej. 1e-2) | Si baja (p.ej. 0) |
|---|---|
| Más regularización → menos sobreajuste, pero riesgo de subajuste si es excesivo | Menos regularización → más capacidad de ajuste, más riesgo de sobreajuste |
Rango recomendado: 1e-5 a 1e-2. El 1e-4 es un valor moderado estándar.
pretrained (default True, flag --no-pretrained)
Función: si cargar pesos de ImageNet o iniciar aleatorio.
Impacto: --no-pretrained = entrenar desde cero → con este dataset, caída grande de macro-F1 y mucho más tiempo. Ver ¿qué pasaría si...?.
num_workers (default 4)
Función: procesos paralelos que cargan/transforman imágenes. No afecta la precisión, solo la velocidad.
| Si sube | Si baja (0) |
|---|---|
| Carga de datos más rápida (oculta latencia de disco); más RAM; en Windows puede dar problemas | Carga secuencial → la GPU espera por datos; útil para depurar |
7.3. Hiperparámetros de datos
target_size / image_size (default [224, 224])
Función: resolución de entrada. Impacto cuádruple: memoria y cómputo crecen ~con el área.
| Si sube (p.ej. 384) | Si baja (p.ej. 128) |
|---|---|
| Más detalle (lesiones finas); ~2.9× más cómputo/memoria; se aleja del preentrenamiento salvo modelos diseñados para ello | Más rápido y ligero (mejor para móvil); pierde detalle fino |
minority_ratio_threshold (default 4.0)
Función: umbral que decide qué clases son minoritarias (max_count/count > 4.0).
| Si sube (p.ej. 8) | Si baja (p.ej. 2) |
|---|---|
| Menos clases califican → menos augmentation agresivo y sampler menos activo | Más clases califican → más sobremuestreo y augmentation, riesgo de sobre-representar clases medianas |
Sobre el dataset completo, con 4.0 califican gray_leaf_spot, nitrogen/phosphorus/potassium_deficiency (no common_rust, que está a 3.9x).
max_images_per_class (default 1500, perfil baseline)
Función: tope de imágenes por clase antes del split.
Si sube (o NO_CAP) | Si baja |
|---|---|
| Splits más grandes → entrenamiento más lento pero más datos de las clases grandes | Más rápido; menos datos; más balanceado artificialmente |
seed (default 42)
Función: semilla de reproducibilidad. No afecta la calidad esperada, solo hace que splits/muestreo/inicialización sean deterministas. Cambiarla da un split y una inicialización distintos (resultados ligeramente diferentes pero estadísticamente equivalentes).
Proporciones de split 70/15/15 (hardcodeadas)
Función: reparto train/val/test.
| Más train (p.ej. 80/10/10) | Menos train (60/20/20) |
|---|---|
| El modelo ve más datos; val/test más pequeños → métricas más ruidosas | Val/test más robustos; el modelo aprende de menos datos |
70/15/15 es un estándar equilibrado. _MIN_STRATUM_IMAGES=7 es el mínimo que hace factible el doble split estratificado.
7.4. Hiperparámetros de augmentation (en transforms.py)
| Parámetro | Estándar | Minoritaria | Efecto de subirlo |
|---|---|---|---|
| Rotación (grados) | ±15° | ±30° | Más invariancia rotacional; demasiado deforma la hoja |
| ColorJitter brillo/contraste | 0.1 | 0.3 | Robustez a iluminación; demasiado desnaturaliza |
| ColorJitter saturación | 0.0 | 0.2 | ⚠️ Sube con cuidado: daña la señal de deficiencias |
| ColorJitter hue | 0.0 | 0.05 | ⚠️ Igual: el tono es el diagnóstico |
| RandomResizedCrop scale | — | (0.7, 1.0) | Más zoom-in; puede recortar la lesión |
| GaussianBlur sigma | — | (0.1, 1.5) | Robustez a desenfoque; demasiado borra detalle |
La perilla más delicada: saturación y hue. Están casi en cero a propósito en el pipeline estándar. Subirlas parecería "más augmentation = mejor", pero destruiría la información de color que distingue las deficiencias nutricionales. Ver datos: transforms.
7.5. Hiperparámetros de LIME (config/dataset.yaml -> lime)
| Parámetro | Default | Función | Subir |
|---|---|---|---|
num_samples | 1000 | Perturbaciones por imagen | Explicación más estable pero más lenta (lineal) |
num_features | 5 | Superpíxeles resaltados | Más regiones mostradas, explicación más densa |
images_per_class | 2 | Muestreo visual pequeño | Más reportes visuales, más tiempo |
report_sample_size | 30 | Muestreo amplio (fidelidad) | Estadísticas de fidelidad más robustas, más lento |
Trade-off central de LIME: num_samples gobierna el compromiso estabilidad vs velocidad. Pocos samples → explicación rápida pero ruidosa (alta variación entre seeds, detectable con lime_stability.py). Muchos → estable pero costosa.
7.6. Interacciones importantes entre hiperparámetros
- LR ↔ batch_size: al cambiar mucho el batch, conviene reescalar el LR.
- image_size ↔ batch_size: ya acoplados por el auto-escalado (más resolución → menos batch).
- epochs ↔ weight_decay: más épocas con poca regularización → más sobreajuste.
- minority_threshold ↔ sampler ↔ augmentation: los tres se activan juntos; mover el umbral cambia el trío.
Siguiente
Ahora los experimentos mentales: ¿Qué pasaría si...? explora las consecuencias de cambiar cada componente.