Files
2026-08-25 12:19:45 -06:00

4.8 KiB
Executable File

Inferencia configurable

Este notebook recibe un CSV con las columnas id, x1, x2, x3 y x4. Carga los pesos desde un diccionario que declara explícitamente la ruta y arquitectura, estandariza con los valores guardados y produce un CSV de predicciones.

La ruta configurada por defecto es un artefacto del instructor. Para inferencia de estudiante, cambie ruta_pesos a su propio modelo exportado y mantenga una arquitectura coincidente.

In [1]:
from pathlib import Path
import sys
import numpy as np
import matplotlib.pyplot as plt

candidatos = [Path.cwd().resolve(), Path.cwd().resolve() / 'dist' / 'laboratorio_clasificacion', Path.cwd().resolve().parent]
RAIZ = next((ruta for ruta in candidatos if (ruta / 'lib_modelos.py').exists()), None)
if RAIZ is None:
    raise FileNotFoundError('No se encontró la carpeta laboratorio_clasificacion.')
sys.path.insert(0, str(RAIZ))
print('Raíz del laboratorio:', RAIZ)
from lib_modelos import cargar_csv, cargar_modelo, transformar
Raíz del laboratorio: /home/aleleba/projects/cursos/Universidad/Procesamiento de Imagenes y Vision por Computadora/Labs/Lab2
In [2]:
CONFIG_MODELOS = {
    'referencia_instructor': {
        'ruta_pesos': RAIZ / 'instructor_privado' / 'artefactos' / 'modelo_mejor.npz',
        'arquitectura': {'tipo': 'mlp', 'entrada': 4, 'ocultas': [32, 16]},
        'umbral': 0.405,
    },
    # Modelo propio, exportado en la sección 6 de laboratorio_estudiante.ipynb:
    'mi_modelo': {
        'ruta_pesos': RAIZ / 'entrega' / 'modelo_elegido.npz',
        'arquitectura': {'tipo': 'mlp', 'entrada': 4, 'ocultas': [48, 24]},
        'umbral': 0.315,
    },
}
NOMBRE_MODELO = 'mi_modelo'
RUTA_ARCHIVO = RAIZ / 'datos_publicos' / 'ejemplo_entrada_inferencia.csv'

Ejecución

Cambie RUTA_ARCHIVO por el CSV recibido. No incluya la columna etiqueta: inferencia no requiere ni debe leer etiquetas.

In [3]:
import csv

config = CONFIG_MODELOS[NOMBRE_MODELO]
if not config['ruta_pesos'].exists():
    raise FileNotFoundError(f"No se encontraron los pesos: {config['ruta_pesos']}")
if not RUTA_ARCHIVO.exists():
    raise FileNotFoundError('Actualice RUTA_ARCHIVO con el archivo de entrada.')

modelo, media, desviacion = cargar_modelo(config['ruta_pesos'], config['arquitectura'])
x, ids = cargar_csv(RUTA_ARCHIVO, con_etiqueta=False)
probabilidades = modelo.probabilidad(transformar(x, media, desviacion))
predicciones = (probabilidades >= config['umbral']).astype(int)

salida = RUTA_ARCHIVO.with_name(RUTA_ARCHIVO.stem + '_predicciones.csv')
with salida.open('w', encoding='utf-8', newline='') as archivo:
    escritor = csv.writer(archivo)
    escritor.writerow(['id', 'probabilidad_clase_1', 'prediccion', 'umbral'])
    for ident, p, pred in zip(ids, probabilidades, predicciones):
        escritor.writerow([ident, f'{p:.8f}', int(pred), config['umbral']])
print('Predicciones guardadas en:', salida)
print('Filas procesadas:', len(ids))
Predicciones guardadas en: /home/aleleba/projects/cursos/Universidad/Procesamiento de Imagenes y Vision por Computadora/Labs/Lab2/datos_publicos/ejemplo_entrada_inferencia_predicciones.csv
Filas procesadas: 12

Verificación de arquitectura

Si se cambia el archivo de pesos, la entrada arquitectura debe coincidir exactamente con el modelo usado al guardarlo: tipo mlp y lista ocultas, o tipo mlp_residual_bn y ancho. El notebook falla de forma visible si las dimensiones son incompatibles.