Evaluación avanzada en visión artificial

deep-learning
vision
evaluacion
Augmentation, errores, heatmaps y robustez: lectura de curvas y reportes en visión.
Author

Wilder Ramírez Delgado

Published

September 5, 2026

Evaluación avanzada en visión artificial

Serie Deep Learning · del perceptrón a los transformers.

Open in Colab

En este artículo evaluamos CNN más allá del accuracy de un test limpio: aumentamos datos, leemos reportes por clase, inspeccionamos errores seguros, visualizamos heatmaps y medimos la caída bajo perturbaciones que un catálogo real sí sufre.

1. Introducción

Un accuracy de test alto no cierra un problema visual. Dos redes con el mismo 0.89 pueden romper clases distintas, activar el fondo o caerse ante un desplazamiento de tres píxeles.

Este artículo continúa evaluación (sesión 4), generalización (5) y CNN (6). La pregunta: qué evidencia extra hace falta antes de firmar que la red generaliza.

2. Qué ya se conoce

CNN, Fashion-MNIST, Train/Val/Test, matriz de confusión, F1, overfitting. Aquí se aplican a diagnóstico visual.

3. Protocolo de lectura

Curvas → mejor val_loss → gap → classification_report → errores de alta confianza → caída bajo perturbación. En ese orden. El accuracy es el titular; el informe es el cuerpo.

import os
import time
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.metrics import (
    classification_report,
    confusion_matrix,
    precision_recall_fscore_support,
)
import tensorflow as tf

os.environ["TF_CPP_MIN_LOG_LEVEL"] = "2"
SEED = 42
tf.keras.utils.set_random_seed(SEED)
plt.style.use("seaborn-v0_8-whitegrid")

print("TensorFlow:", tf.__version__)
print("GPU:", tf.config.list_physical_devices("GPU") or "ninguna (CPU)")


def series_history(hist):
    h = hist.history if hasattr(hist, "history") else hist
    return {k: np.asarray(v, dtype=float) for k, v in h.items()}


def diagnostico_entrenamiento(hist, nombre="modelo"):
    """Resume un history como se leería en un informe técnico."""
    s = series_history(hist)
    loss = s["loss"]
    n = len(loss)
    tiene_val = "val_loss" in s
    fila = {"modelo": nombre, "epocas_corridas": n}
    if tiene_val:
        i = int(np.argmin(s["val_loss"]))
        fila.update({
            "mejor_epoca_val_loss": i + 1,
            "min_val_loss": float(s["val_loss"][i]),
            "val_loss_final": float(s["val_loss"][-1]),
            "train_loss_en_mejor": float(loss[i]),
            "train_loss_final": float(loss[-1]),
            "delta_val_tras_mejor": float(s["val_loss"][-1] - s["val_loss"][i]),
            "gap_loss_mejor": float(s["val_loss"][i] - loss[i]),
            "gap_loss_final": float(s["val_loss"][-1] - loss[-1]),
        })
        if "accuracy" in s and "val_accuracy" in s:
            fila["train_acc_mejor"] = float(s["accuracy"][i])
            fila["val_acc_mejor"] = float(s["val_accuracy"][i])
            fila["train_acc_final"] = float(s["accuracy"][-1])
            fila["val_acc_final"] = float(s["val_accuracy"][-1])
            fila["gap_acc_mejor"] = float(s["accuracy"][i] - s["val_accuracy"][i])
            fila["gap_acc_final"] = float(s["accuracy"][-1] - s["val_accuracy"][-1])
    print(pd.Series(fila).to_string())
    if tiene_val:
        print()
        print("LECTURA")
        if fila["mejor_epoca_val_loss"] < n:
            print(
                f"La mejor val_loss no es la última época "
                f"({fila['mejor_epoca_val_loss']} de {n}). "
                "Si restore_best_weights=True, el modelo guardado no es el del último paso."
            )
        else:
            print("La mejor val_loss coincide con la última época: no hay tramo posterior de deterioro.")
        if fila.get("gap_acc_final", 0) > 0.08:
            print("Gap train-val de accuracy notable: posible sobreajuste o desajuste de dificultad.")
        elif fila.get("gap_acc_final", 0) < -0.02:
            print("Val > train: regularización fuerte, aumento de datos o validación más fácil.")
        if fila.get("delta_val_tras_mejor", 0) > 0.05:
            print("val_loss subió tras el mínimo: el entrenamiento extra no estaba ayudando.")
    return fila


def curvas_entrenamiento(hist, titulo):
    s = series_history(hist)
    ep = np.arange(1, len(s["loss"]) + 1)
    fig, axes = plt.subplots(1, 2, figsize=(11, 3.6))
    axes[0].plot(ep, s["loss"], marker="o", label="train")
    if "val_loss" in s:
        axes[0].plot(ep, s["val_loss"], marker="o", label="validación")
        i = int(np.argmin(s["val_loss"]))
        axes[0].axvline(i + 1, ls="--", color="0.4", label=f"mejor val_loss (ép. {i+1})")
    axes[0].set_title(f"{titulo} — pérdida")
    axes[0].set_xlabel("Época")
    axes[0].legend()
    if "accuracy" in s:
        axes[1].plot(ep, s["accuracy"], marker="o", label="train")
        if "val_accuracy" in s:
            axes[1].plot(ep, s["val_accuracy"], marker="o", label="validación")
        axes[1].set_title(f"{titulo} — accuracy")
        axes[1].set_xlabel("Época")
        axes[1].legend()
    else:
        axes[1].axis("off")
    plt.tight_layout()
    plt.show()


def informe_clasificacion(y_true, y_pred, nombres, titulo=""):
    print(titulo)
    print(classification_report(y_true, y_pred, target_names=nombres, digits=4, zero_division=0))
    p, r, f1, sop = precision_recall_fscore_support(
        y_true, y_pred, average=None, zero_division=0
    )
    df = pd.DataFrame({
        "clase": nombres,
        "precision": p,
        "recall": r,
        "f1": f1,
        "soporte": sop,
    }).sort_values("f1")
    print("Clases ordenadas por F1 (las de abajo son las más débiles):")
    print(df.to_string(index=False, float_format=lambda v: f"{v:.4f}"))
    return df


def matriz_y_errores(y_true, y_pred, nombres, x=None, probs=None, k=8):
    cm = confusion_matrix(y_true, y_pred)
    fig, ax = plt.subplots(figsize=(6.2, 5.2))
    im = ax.imshow(cm, cmap="Blues")
    ax.set_xticks(range(len(nombres)), nombres, rotation=70, ha="right", fontsize=8)
    ax.set_yticks(range(len(nombres)), nombres, fontsize=8)
    ax.set_xlabel("Predicho")
    ax.set_ylabel("Verdadero")
    fig.colorbar(im, ax=ax, fraction=0.046)
    plt.tight_layout()
    plt.show()
    if x is None:
        return cm
    conf = probs[np.arange(len(y_pred)), y_pred] if probs is not None else np.ones(len(y_pred))
    err = np.where(y_true != y_pred)[0]
    if len(err) == 0:
        print("Cero errores en el recorte analizado.")
        return cm
    orden = err[np.argsort(-conf[err])]
    n = min(k, len(orden))
    cols = min(4, n)
    rows = int(np.ceil(n / cols))
    fig, axes = plt.subplots(rows, cols, figsize=(2.6 * cols, 2.6 * rows))
    axes = np.atleast_1d(axes).ravel()
    for ax, j in zip(axes, orden[:n]):
        img = x[j]
        if img.ndim == 3 and img.shape[-1] == 1:
            img = img.squeeze()
        ax.imshow(img, cmap="gray" if np.ndim(img) == 2 else None)
        ax.set_title(
            f"V:{nombres[int(y_true[j])]}\\nP:{nombres[int(y_pred[j])]} ({conf[j]:.2f})",
            fontsize=8,
        )
        ax.axis("off")
    for ax in axes[n:]:
        ax.axis("off")
    plt.suptitle("Errores de mayor confianza")
    plt.tight_layout()
    plt.show()
    return cm
TensorFlow: 2.21.0
WARNING:tensorflow:TensorFlow GPU support is not available on native Windows for TensorFlow >= 2.11. Even if CUDA/cuDNN are installed, GPU will not be used. Please use WSL2 or the TensorFlow-DirectML plugin.
GPU: ninguna (CPU)

Idea clave

En visión, generalizar es resistir variaciones que el conjunto oficial no muestra. El accuracy es una media; el diagnóstico es una distribución de fallos.

4. Laboratorio de curvas

Tres history sintéticos para afianzar el lenguaje antes de gastar fit.

sano = {"loss":[0.9,0.55,0.38,0.30], "val_loss":[0.88,0.57,0.42,0.39],
        "accuracy":[0.62,0.78,0.85,0.88], "val_accuracy":[0.60,0.76,0.82,0.84]}
sobre = {"loss":[0.85,0.40,0.18,0.07], "val_loss":[0.80,0.50,0.58,0.72],
         "accuracy":[0.65,0.86,0.94,0.99], "val_accuracy":[0.63,0.80,0.78,0.75]}
print("SANO"); diagnostico_entrenamiento(sano,"sano"); curvas_entrenamiento(sano,"Sano")
print("SOBREAJUSTE"); diagnostico_entrenamiento(sobre,"sobre"); curvas_entrenamiento(sobre,"Sobreajuste")
SANO
modelo                  sano
epocas_corridas            4
mejor_epoca_val_loss       4
min_val_loss            0.39
val_loss_final          0.39
train_loss_en_mejor      0.3
train_loss_final         0.3
delta_val_tras_mejor     0.0
gap_loss_mejor          0.09
gap_loss_final          0.09
train_acc_mejor         0.88
val_acc_mejor           0.84
train_acc_final         0.88
val_acc_final           0.84
gap_acc_mejor           0.04
gap_acc_final           0.04

LECTURA
La mejor val_loss coincide con la última época: no hay tramo posterior de deterioro.

SOBREAJUSTE
modelo                  sobre
epocas_corridas             4
mejor_epoca_val_loss        2
min_val_loss              0.5
val_loss_final           0.72
train_loss_en_mejor       0.4
train_loss_final         0.07
delta_val_tras_mejor     0.22
gap_loss_mejor            0.1
gap_loss_final           0.65
train_acc_mejor          0.86
val_acc_mejor             0.8
train_acc_final          0.99
val_acc_final            0.75
gap_acc_mejor            0.06
gap_acc_final            0.24

LECTURA
La mejor val_loss no es la última época (2 de 4). Si restore_best_weights=True, el modelo guardado no es el del último paso.
Gap train-val de accuracy notable: posible sobreajuste o desajuste de dificultad.
val_loss subió tras el mínimo: el entrenamiento extra no estaba ayudando.

Interpretación

Si la mejor val_loss no es la última época, el número que imprime el final de fit no es el del checkpoint. Eso importa cuando comparemos CNN con y sin aumento.

5. Caso 1 — Catálogo textil (Fashion-MNIST)

Diez prendas, 28×28. Es el análogo de un e-commerce que clasifica fotos de ficha. El par Shirt / T-shirt suele concentrar el error: siluetas parecidas, etiqueta humana discutible.

(xtr,ytr),(xte,yte)=tf.keras.datasets.fashion_mnist.load_data()
xtr=xtr.astype("float32")/255.0; xte=xte.astype("float32")/255.0
xtr=xtr[...,None]; xte=xte[...,None]
PRENDAS=["T-shirt","Pantalón","Pullover","Vestido","Abrigo","Sandalia","Camisa","Zapatilla","Bolso","Botín"]
N=12000
x_tr,y_tr=xtr[:N],ytr[:N]
print(x_tr.shape,xte.shape)
print(pd.Series(y_tr).value_counts().sort_index().to_frame("n").T)
(12000, 28, 28, 1) (10000, 28, 28, 1)
      0     1     2     3     4     5     6     7     8     9
n  1122  1220  1201  1212  1181  1204  1244  1192  1195  1229

Idea clave

El soporte por clase en Fashion-MNIST es casi plano. Si el F1 no lo es, el problema es confusión, no desbalance.

fig,ax=plt.subplots(2,5,figsize=(10,4))
for k,a in enumerate(ax.ravel()):
    j=np.where(y_tr==k)[0][0]
    a.imshow(x_tr[j].squeeze(),cmap="gray"); a.set_title(PRENDAS[k],fontsize=8); a.axis("off")
plt.suptitle("Una ficha por clase (catálogo textil)")
plt.tight_layout(); plt.show()

6. Dos CNN comparables: sin aumento y con aumento

Misma arquitectura, mismo Adam, mismas épocas, mismo test. Cambia solo el aumento. No se afirma que el aumento gane.

aumentador=tf.keras.Sequential([
    tf.keras.layers.RandomFlip("horizontal"),
    tf.keras.layers.RandomRotation(0.08),
    tf.keras.layers.RandomTranslation(0.08,0.08),
],name="aum")

def cnn(con_aum=False):
    inp=tf.keras.Input((28,28,1))
    x=aumentador(inp) if con_aum else inp
    x=tf.keras.layers.Conv2D(32,3,activation="relu",padding="same")(x)
    x=tf.keras.layers.MaxPool2D()(x)
    x=tf.keras.layers.Conv2D(64,3,activation="relu",padding="same",name="ultima_conv")(x)
    x=tf.keras.layers.MaxPool2D()(x)
    x=tf.keras.layers.Flatten()(x)
    x=tf.keras.layers.Dense(64,activation="relu")(x)
    out=tf.keras.layers.Dense(10,activation="softmax")(x)
    m=tf.keras.Model(inp,out)
    m.compile(optimizer="adam",loss="sparse_categorical_crossentropy",metrics=["accuracy"])
    return m
print("params",cnn(False).count_params())
params 220234

7. Qué hace el aumento (y qué no)

No inventa clases. Declara equivalencias: un zapato rotado sigue siendo zapato. Si la transformación cambia el significado, ensucia la tarea.

img=x_tr[3]
fig,axes=plt.subplots(1,6,figsize=(12,2.4))
axes[0].imshow(img.squeeze(),cmap="gray"); axes[0].set_title("Original"); axes[0].axis("off")
for i,ax in enumerate(axes[1:],1):
    v=aumentador(tf.expand_dims(img,0),training=True)[0]
    ax.imshow(tf.squeeze(v),cmap="gray"); ax.set_title(f"Aum {i}"); ax.axis("off")
plt.suptitle(f"Misma etiqueta: {PRENDAS[int(y_tr[3])]}")
plt.tight_layout(); plt.show()

Interpretación

Cinco realizaciones, una etiqueta. Si el modelo acierta en todas, usa rasgos estables. Si solo acierta la original, memorizó el recorte del canvas oficial.

8. Entrenamiento de la CNN sin aumento

es=tf.keras.callbacks.EarlyStopping(monitor="val_loss",patience=2,restore_best_weights=True)
m0=cnn(False)
h0=m0.fit(x_tr,y_tr,validation_split=0.15,epochs=5,batch_size=128,callbacks=[es],verbose=1)
Epoch 1/5


 1/80 ━━━━━━━━━━━━━━━━━━━━ 2:32 2s/step - accuracy: 0.0703 - loss: 2.3012

 3/80 ━━━━━━━━━━━━━━━━━━━━ 2s 33ms/step - accuracy: 0.1667 - loss: 2.2300

 5/80 ━━━━━━━━━━━━━━━━━━━━ 2s 32ms/step - accuracy: 0.2406 - loss: 2.1467

 7/80 ━━━━━━━━━━━━━━━━━━━━ 2s 31ms/step - accuracy: 0.2868 - loss: 2.0609

 9/80 ━━━━━━━━━━━━━━━━━━━━ 2s 31ms/step - accuracy: 0.3342 - loss: 1.9460

11/80 ━━━━━━━━━━━━━━━━━━━━ 2s 31ms/step - accuracy: 0.3778 - loss: 1.8377

13/80 ━━━━━━━━━━━━━━━━━━━━ 2s 31ms/step - accuracy: 0.4165 - loss: 1.7288

15/80 ━━━━━━━━━━━━━━━━━━━━ 2s 31ms/step - accuracy: 0.4266 - loss: 1.6674

17/80 ━━━━━━━━━━━━━━━━━━━━ 2s 32ms/step - accuracy: 0.4490 - loss: 1.5886

19/80 ━━━━━━━━━━━━━━━━━━━━ 2s 33ms/step - accuracy: 0.4704 - loss: 1.5261

20/80 ━━━━━━━━━━━━━━━━━━━━ 2s 35ms/step - accuracy: 0.4754 - loss: 1.5020

22/80 ━━━━━━━━━━━━━━━━━━━━ 2s 36ms/step - accuracy: 0.4879 - loss: 1.4469

24/80 ━━━━━━━━━━━━━━━━━━━━ 1s 36ms/step - accuracy: 0.5033 - loss: 1.3937

26/80 ━━━━━━━━━━━━━━━━━━━━ 1s 36ms/step - accuracy: 0.5156 - loss: 1.3503

28/80 ━━━━━━━━━━━━━━━━━━━━ 1s 35ms/step - accuracy: 0.5299 - loss: 1.3120

30/80 ━━━━━━━━━━━━━━━━━━━━ 1s 35ms/step - accuracy: 0.5440 - loss: 1.2799

32/80 ━━━━━━━━━━━━━━━━━━━━ 1s 35ms/step - accuracy: 0.5522 - loss: 1.2582

34/80 ━━━━━━━━━━━━━━━━━━━━ 1s 35ms/step - accuracy: 0.5620 - loss: 1.2305

36/80 ━━━━━━━━━━━━━━━━━━━━ 1s 35ms/step - accuracy: 0.5720 - loss: 1.2022

38/80 ━━━━━━━━━━━━━━━━━━━━ 1s 34ms/step - accuracy: 0.5779 - loss: 1.1850

40/80 ━━━━━━━━━━━━━━━━━━━━ 1s 34ms/step - accuracy: 0.5854 - loss: 1.1625

43/80 ━━━━━━━━━━━━━━━━━━━━ 1s 33ms/step - accuracy: 0.5987 - loss: 1.1271

46/80 ━━━━━━━━━━━━━━━━━━━━ 1s 32ms/step - accuracy: 0.6106 - loss: 1.0960

49/80 ━━━━━━━━━━━━━━━━━━━━ 0s 32ms/step - accuracy: 0.6202 - loss: 1.0684

52/80 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step - accuracy: 0.6297 - loss: 1.0415

54/80 ━━━━━━━━━━━━━━━━━━━━ 0s 32ms/step - accuracy: 0.6350 - loss: 1.0248

56/80 ━━━━━━━━━━━━━━━━━━━━ 0s 32ms/step - accuracy: 0.6395 - loss: 1.0128

58/80 ━━━━━━━━━━━━━━━━━━━━ 0s 32ms/step - accuracy: 0.6445 - loss: 1.0005

60/80 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step - accuracy: 0.6487 - loss: 0.9868

62/80 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step - accuracy: 0.6512 - loss: 0.9763

64/80 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step - accuracy: 0.6543 - loss: 0.9657

66/80 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step - accuracy: 0.6592 - loss: 0.9541

68/80 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step - accuracy: 0.6625 - loss: 0.9451

70/80 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step - accuracy: 0.6666 - loss: 0.9331

72/80 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step - accuracy: 0.6695 - loss: 0.9253

74/80 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step - accuracy: 0.6723 - loss: 0.9180

76/80 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step - accuracy: 0.6750 - loss: 0.9098

78/80 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step - accuracy: 0.6783 - loss: 0.9007

80/80 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step - accuracy: 0.6806 - loss: 0.8931

80/80 ━━━━━━━━━━━━━━━━━━━━ 5s 39ms/step - accuracy: 0.6806 - loss: 0.8931 - val_accuracy: 0.8067 - val_loss: 0.5606

Epoch 2/5


 1/80 ━━━━━━━━━━━━━━━━━━━━ 5s 76ms/step - accuracy: 0.7578 - loss: 0.6288

 3/80 ━━━━━━━━━━━━━━━━━━━━ 2s 38ms/step - accuracy: 0.7786 - loss: 0.5609

 5/80 ━━━━━━━━━━━━━━━━━━━━ 2s 35ms/step - accuracy: 0.7922 - loss: 0.5480

 7/80 ━━━━━━━━━━━━━━━━━━━━ 2s 33ms/step - accuracy: 0.7868 - loss: 0.5729

 9/80 ━━━━━━━━━━━━━━━━━━━━ 2s 31ms/step - accuracy: 0.7977 - loss: 0.5435

11/80 ━━━━━━━━━━━━━━━━━━━━ 2s 30ms/step - accuracy: 0.8004 - loss: 0.5503

13/80 ━━━━━━━━━━━━━━━━━━━━ 1s 29ms/step - accuracy: 0.7999 - loss: 0.5520

15/80 ━━━━━━━━━━━━━━━━━━━━ 1s 29ms/step - accuracy: 0.7958 - loss: 0.5637

17/80 ━━━━━━━━━━━━━━━━━━━━ 1s 29ms/step - accuracy: 0.7983 - loss: 0.5611

19/80 ━━━━━━━━━━━━━━━━━━━━ 1s 29ms/step - accuracy: 0.7985 - loss: 0.5668

21/80 ━━━━━━━━━━━━━━━━━━━━ 1s 29ms/step - accuracy: 0.7965 - loss: 0.5663

22/80 ━━━━━━━━━━━━━━━━━━━━ 1s 30ms/step - accuracy: 0.7976 - loss: 0.5646

24/80 ━━━━━━━━━━━━━━━━━━━━ 1s 31ms/step - accuracy: 0.8005 - loss: 0.5553

26/80 ━━━━━━━━━━━━━━━━━━━━ 1s 31ms/step - accuracy: 0.8023 - loss: 0.5481

28/80 ━━━━━━━━━━━━━━━━━━━━ 1s 32ms/step - accuracy: 0.8058 - loss: 0.5422

30/80 ━━━━━━━━━━━━━━━━━━━━ 1s 32ms/step - accuracy: 0.8076 - loss: 0.5374

32/80 ━━━━━━━━━━━━━━━━━━━━ 1s 32ms/step - accuracy: 0.8062 - loss: 0.5387

34/80 ━━━━━━━━━━━━━━━━━━━━ 1s 32ms/step - accuracy: 0.8088 - loss: 0.5342

36/80 ━━━━━━━━━━━━━━━━━━━━ 1s 32ms/step - accuracy: 0.8092 - loss: 0.5322

38/80 ━━━━━━━━━━━━━━━━━━━━ 1s 33ms/step - accuracy: 0.8086 - loss: 0.5366

40/80 ━━━━━━━━━━━━━━━━━━━━ 1s 33ms/step - accuracy: 0.8078 - loss: 0.5343

42/80 ━━━━━━━━━━━━━━━━━━━━ 1s 33ms/step - accuracy: 0.8080 - loss: 0.5306

44/80 ━━━━━━━━━━━━━━━━━━━━ 1s 33ms/step - accuracy: 0.8097 - loss: 0.5259

46/80 ━━━━━━━━━━━━━━━━━━━━ 1s 33ms/step - accuracy: 0.8101 - loss: 0.5233

48/80 ━━━━━━━━━━━━━━━━━━━━ 1s 33ms/step - accuracy: 0.8104 - loss: 0.5217

50/80 ━━━━━━━━━━━━━━━━━━━━ 1s 33ms/step - accuracy: 0.8116 - loss: 0.5184

52/80 ━━━━━━━━━━━━━━━━━━━━ 0s 34ms/step - accuracy: 0.8133 - loss: 0.5137

54/80 ━━━━━━━━━━━━━━━━━━━━ 0s 34ms/step - accuracy: 0.8129 - loss: 0.5134

56/80 ━━━━━━━━━━━━━━━━━━━━ 0s 34ms/step - accuracy: 0.8128 - loss: 0.5132

58/80 ━━━━━━━━━━━━━━━━━━━━ 0s 34ms/step - accuracy: 0.8116 - loss: 0.5160

60/80 ━━━━━━━━━━━━━━━━━━━━ 0s 34ms/step - accuracy: 0.8113 - loss: 0.5168

62/80 ━━━━━━━━━━━━━━━━━━━━ 0s 34ms/step - accuracy: 0.8104 - loss: 0.5196

64/80 ━━━━━━━━━━━━━━━━━━━━ 0s 34ms/step - accuracy: 0.8108 - loss: 0.5180

66/80 ━━━━━━━━━━━━━━━━━━━━ 0s 34ms/step - accuracy: 0.8104 - loss: 0.5215

68/80 ━━━━━━━━━━━━━━━━━━━━ 0s 34ms/step - accuracy: 0.8097 - loss: 0.5215

70/80 ━━━━━━━━━━━━━━━━━━━━ 0s 34ms/step - accuracy: 0.8095 - loss: 0.5216

72/80 ━━━━━━━━━━━━━━━━━━━━ 0s 34ms/step - accuracy: 0.8094 - loss: 0.5227

74/80 ━━━━━━━━━━━━━━━━━━━━ 0s 34ms/step - accuracy: 0.8094 - loss: 0.5234

76/80 ━━━━━━━━━━━━━━━━━━━━ 0s 34ms/step - accuracy: 0.8090 - loss: 0.5242

78/80 ━━━━━━━━━━━━━━━━━━━━ 0s 34ms/step - accuracy: 0.8087 - loss: 0.5233

80/80 ━━━━━━━━━━━━━━━━━━━━ 0s 34ms/step - accuracy: 0.8097 - loss: 0.5207

80/80 ━━━━━━━━━━━━━━━━━━━━ 3s 38ms/step - accuracy: 0.8097 - loss: 0.5207 - val_accuracy: 0.8172 - val_loss: 0.5005

Epoch 3/5


 1/80 ━━━━━━━━━━━━━━━━━━━━ 5s 74ms/step - accuracy: 0.7656 - loss: 0.5685

 3/80 ━━━━━━━━━━━━━━━━━━━━ 2s 34ms/step - accuracy: 0.7995 - loss: 0.4981

 5/80 ━━━━━━━━━━━━━━━━━━━━ 2s 36ms/step - accuracy: 0.8188 - loss: 0.4588

 7/80 ━━━━━━━━━━━━━━━━━━━━ 2s 38ms/step - accuracy: 0.8192 - loss: 0.4879

 8/80 ━━━━━━━━━━━━━━━━━━━━ 2s 40ms/step - accuracy: 0.8145 - loss: 0.4841

 9/80 ━━━━━━━━━━━━━━━━━━━━ 2s 42ms/step - accuracy: 0.8203 - loss: 0.4674

11/80 ━━━━━━━━━━━━━━━━━━━━ 2s 41ms/step - accuracy: 0.8210 - loss: 0.4746

13/80 ━━━━━━━━━━━━━━━━━━━━ 2s 40ms/step - accuracy: 0.8215 - loss: 0.4722

15/80 ━━━━━━━━━━━━━━━━━━━━ 2s 40ms/step - accuracy: 0.8219 - loss: 0.4728

17/80 ━━━━━━━━━━━━━━━━━━━━ 2s 39ms/step - accuracy: 0.8199 - loss: 0.4732

19/80 ━━━━━━━━━━━━━━━━━━━━ 2s 39ms/step - accuracy: 0.8228 - loss: 0.4758

21/80 ━━━━━━━━━━━━━━━━━━━━ 2s 39ms/step - accuracy: 0.8225 - loss: 0.4738

23/80 ━━━━━━━━━━━━━━━━━━━━ 2s 38ms/step - accuracy: 0.8254 - loss: 0.4670

25/80 ━━━━━━━━━━━━━━━━━━━━ 2s 38ms/step - accuracy: 0.8275 - loss: 0.4604

27/80 ━━━━━━━━━━━━━━━━━━━━ 2s 38ms/step - accuracy: 0.8319 - loss: 0.4517

29/80 ━━━━━━━━━━━━━━━━━━━━ 1s 37ms/step - accuracy: 0.8332 - loss: 0.4499

31/80 ━━━━━━━━━━━━━━━━━━━━ 1s 37ms/step - accuracy: 0.8342 - loss: 0.4477

33/80 ━━━━━━━━━━━━━━━━━━━━ 1s 37ms/step - accuracy: 0.8359 - loss: 0.4426

35/80 ━━━━━━━━━━━━━━━━━━━━ 1s 37ms/step - accuracy: 0.8375 - loss: 0.4407

37/80 ━━━━━━━━━━━━━━━━━━━━ 1s 37ms/step - accuracy: 0.8368 - loss: 0.4414

39/80 ━━━━━━━━━━━━━━━━━━━━ 1s 37ms/step - accuracy: 0.8369 - loss: 0.4410

41/80 ━━━━━━━━━━━━━━━━━━━━ 1s 37ms/step - accuracy: 0.8377 - loss: 0.4395

43/80 ━━━━━━━━━━━━━━━━━━━━ 1s 37ms/step - accuracy: 0.8396 - loss: 0.4366

45/80 ━━━━━━━━━━━━━━━━━━━━ 1s 37ms/step - accuracy: 0.8405 - loss: 0.4334

47/80 ━━━━━━━━━━━━━━━━━━━━ 1s 36ms/step - accuracy: 0.8418 - loss: 0.4308

49/80 ━━━━━━━━━━━━━━━━━━━━ 1s 36ms/step - accuracy: 0.8431 - loss: 0.4283

51/80 ━━━━━━━━━━━━━━━━━━━━ 1s 36ms/step - accuracy: 0.8436 - loss: 0.4265

53/80 ━━━━━━━━━━━━━━━━━━━━ 0s 36ms/step - accuracy: 0.8440 - loss: 0.4254

55/80 ━━━━━━━━━━━━━━━━━━━━ 0s 36ms/step - accuracy: 0.8445 - loss: 0.4256

57/80 ━━━━━━━━━━━━━━━━━━━━ 0s 36ms/step - accuracy: 0.8453 - loss: 0.4254

59/80 ━━━━━━━━━━━━━━━━━━━━ 0s 35ms/step - accuracy: 0.8449 - loss: 0.4259

61/80 ━━━━━━━━━━━━━━━━━━━━ 0s 35ms/step - accuracy: 0.8436 - loss: 0.4298

63/80 ━━━━━━━━━━━━━━━━━━━━ 0s 35ms/step - accuracy: 0.8439 - loss: 0.4276

65/80 ━━━━━━━━━━━━━━━━━━━━ 0s 35ms/step - accuracy: 0.8438 - loss: 0.4307

67/80 ━━━━━━━━━━━━━━━━━━━━ 0s 35ms/step - accuracy: 0.8421 - loss: 0.4344

69/80 ━━━━━━━━━━━━━━━━━━━━ 0s 35ms/step - accuracy: 0.8427 - loss: 0.4327

71/80 ━━━━━━━━━━━━━━━━━━━━ 0s 34ms/step - accuracy: 0.8415 - loss: 0.4340

73/80 ━━━━━━━━━━━━━━━━━━━━ 0s 34ms/step - accuracy: 0.8405 - loss: 0.4374

75/80 ━━━━━━━━━━━━━━━━━━━━ 0s 34ms/step - accuracy: 0.8405 - loss: 0.4372

77/80 ━━━━━━━━━━━━━━━━━━━━ 0s 34ms/step - accuracy: 0.8403 - loss: 0.4380

79/80 ━━━━━━━━━━━━━━━━━━━━ 0s 34ms/step - accuracy: 0.8415 - loss: 0.4354

80/80 ━━━━━━━━━━━━━━━━━━━━ 3s 37ms/step - accuracy: 0.8416 - loss: 0.4354 - val_accuracy: 0.8361 - val_loss: 0.4360

Epoch 4/5


 1/80 ━━━━━━━━━━━━━━━━━━━━ 5s 75ms/step - accuracy: 0.8203 - loss: 0.4814

 3/80 ━━━━━━━━━━━━━━━━━━━━ 2s 30ms/step - accuracy: 0.8490 - loss: 0.4059

 5/80 ━━━━━━━━━━━━━━━━━━━━ 2s 30ms/step - accuracy: 0.8687 - loss: 0.3781

 7/80 ━━━━━━━━━━━━━━━━━━━━ 2s 30ms/step - accuracy: 0.8594 - loss: 0.4130

 9/80 ━━━━━━━━━━━━━━━━━━━━ 2s 30ms/step - accuracy: 0.8628 - loss: 0.3965

11/80 ━━━━━━━━━━━━━━━━━━━━ 2s 30ms/step - accuracy: 0.8608 - loss: 0.4058

13/80 ━━━━━━━━━━━━━━━━━━━━ 2s 30ms/step - accuracy: 0.8576 - loss: 0.4038

15/80 ━━━━━━━━━━━━━━━━━━━━ 1s 30ms/step - accuracy: 0.8552 - loss: 0.4039

17/80 ━━━━━━━━━━━━━━━━━━━━ 1s 30ms/step - accuracy: 0.8534 - loss: 0.4060

19/80 ━━━━━━━━━━━━━━━━━━━━ 1s 29ms/step - accuracy: 0.8553 - loss: 0.4112

21/80 ━━━━━━━━━━━━━━━━━━━━ 1s 29ms/step - accuracy: 0.8545 - loss: 0.4096

23/80 ━━━━━━━━━━━━━━━━━━━━ 1s 29ms/step - accuracy: 0.8556 - loss: 0.4048

25/80 ━━━━━━━━━━━━━━━━━━━━ 1s 29ms/step - accuracy: 0.8559 - loss: 0.4007

27/80 ━━━━━━━━━━━━━━━━━━━━ 1s 29ms/step - accuracy: 0.8591 - loss: 0.3943

29/80 ━━━━━━━━━━━━━━━━━━━━ 1s 29ms/step - accuracy: 0.8599 - loss: 0.3930

31/80 ━━━━━━━━━━━━━━━━━━━━ 1s 29ms/step - accuracy: 0.8596 - loss: 0.3918

33/80 ━━━━━━━━━━━━━━━━━━━━ 1s 29ms/step - accuracy: 0.8608 - loss: 0.3879

35/80 ━━━━━━━━━━━━━━━━━━━━ 1s 29ms/step - accuracy: 0.8618 - loss: 0.3870

37/80 ━━━━━━━━━━━━━━━━━━━━ 1s 29ms/step - accuracy: 0.8609 - loss: 0.3885

39/80 ━━━━━━━━━━━━━━━━━━━━ 1s 29ms/step - accuracy: 0.8598 - loss: 0.3888

41/80 ━━━━━━━━━━━━━━━━━━━━ 1s 29ms/step - accuracy: 0.8596 - loss: 0.3883

43/80 ━━━━━━━━━━━━━━━━━━━━ 1s 29ms/step - accuracy: 0.8608 - loss: 0.3867

45/80 ━━━━━━━━━━━━━━━━━━━━ 1s 29ms/step - accuracy: 0.8615 - loss: 0.3840

47/80 ━━━━━━━━━━━━━━━━━━━━ 0s 30ms/step - accuracy: 0.8625 - loss: 0.3820

49/80 ━━━━━━━━━━━━━━━━━━━━ 0s 30ms/step - accuracy: 0.8629 - loss: 0.3804

51/80 ━━━━━━━━━━━━━━━━━━━━ 0s 30ms/step - accuracy: 0.8634 - loss: 0.3794

53/80 ━━━━━━━━━━━━━━━━━━━━ 0s 30ms/step - accuracy: 0.8639 - loss: 0.3787

55/80 ━━━━━━━━━━━━━━━━━━━━ 0s 30ms/step - accuracy: 0.8641 - loss: 0.3792

57/80 ━━━━━━━━━━━━━━━━━━━━ 0s 30ms/step - accuracy: 0.8649 - loss: 0.3783

59/80 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step - accuracy: 0.8644 - loss: 0.3792

61/80 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step - accuracy: 0.8632 - loss: 0.3818

63/80 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step - accuracy: 0.8638 - loss: 0.3797

65/80 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step - accuracy: 0.8629 - loss: 0.3832

67/80 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step - accuracy: 0.8615 - loss: 0.3864

69/80 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step - accuracy: 0.8619 - loss: 0.3851

71/80 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step - accuracy: 0.8607 - loss: 0.3864

73/80 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step - accuracy: 0.8589 - loss: 0.3899

75/80 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step - accuracy: 0.8587 - loss: 0.3897

77/80 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step - accuracy: 0.8586 - loss: 0.3903

79/80 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step - accuracy: 0.8598 - loss: 0.3881

80/80 ━━━━━━━━━━━━━━━━━━━━ 3s 34ms/step - accuracy: 0.8597 - loss: 0.3882 - val_accuracy: 0.8439 - val_loss: 0.4072

Epoch 5/5


 1/80 ━━━━━━━━━━━━━━━━━━━━ 6s 79ms/step - accuracy: 0.8359 - loss: 0.4332

 3/80 ━━━━━━━━━━━━━━━━━━━━ 2s 31ms/step - accuracy: 0.8620 - loss: 0.3700

 5/80 ━━━━━━━━━━━━━━━━━━━━ 2s 31ms/step - accuracy: 0.8813 - loss: 0.3382

 7/80 ━━━━━━━━━━━━━━━━━━━━ 2s 30ms/step - accuracy: 0.8672 - loss: 0.3756

 9/80 ━━━━━━━━━━━━━━━━━━━━ 2s 31ms/step - accuracy: 0.8681 - loss: 0.3600

11/80 ━━━━━━━━━━━━━━━━━━━━ 2s 30ms/step - accuracy: 0.8651 - loss: 0.3727

13/80 ━━━━━━━━━━━━━━━━━━━━ 2s 30ms/step - accuracy: 0.8624 - loss: 0.3730

15/80 ━━━━━━━━━━━━━━━━━━━━ 1s 29ms/step - accuracy: 0.8609 - loss: 0.3710

17/80 ━━━━━━━━━━━━━━━━━━━━ 1s 29ms/step - accuracy: 0.8603 - loss: 0.3738

19/80 ━━━━━━━━━━━━━━━━━━━━ 1s 29ms/step - accuracy: 0.8631 - loss: 0.3793

21/80 ━━━━━━━━━━━━━━━━━━━━ 1s 29ms/step - accuracy: 0.8624 - loss: 0.3774

23/80 ━━━━━━━━━━━━━━━━━━━━ 1s 29ms/step - accuracy: 0.8628 - loss: 0.3739

25/80 ━━━━━━━━━━━━━━━━━━━━ 1s 28ms/step - accuracy: 0.8637 - loss: 0.3708

27/80 ━━━━━━━━━━━━━━━━━━━━ 1s 28ms/step - accuracy: 0.8660 - loss: 0.3666

29/80 ━━━━━━━━━━━━━━━━━━━━ 1s 28ms/step - accuracy: 0.8672 - loss: 0.3647

31/80 ━━━━━━━━━━━━━━━━━━━━ 1s 28ms/step - accuracy: 0.8664 - loss: 0.3640

33/80 ━━━━━━━━━━━━━━━━━━━━ 1s 28ms/step - accuracy: 0.8677 - loss: 0.3606

35/80 ━━━━━━━━━━━━━━━━━━━━ 1s 28ms/step - accuracy: 0.8683 - loss: 0.3598

37/80 ━━━━━━━━━━━━━━━━━━━━ 1s 28ms/step - accuracy: 0.8687 - loss: 0.3607

39/80 ━━━━━━━━━━━━━━━━━━━━ 1s 28ms/step - accuracy: 0.8684 - loss: 0.3603

41/80 ━━━━━━━━━━━━━━━━━━━━ 1s 28ms/step - accuracy: 0.8687 - loss: 0.3599

43/80 ━━━━━━━━━━━━━━━━━━━━ 1s 28ms/step - accuracy: 0.8694 - loss: 0.3589

45/80 ━━━━━━━━━━━━━━━━━━━━ 0s 28ms/step - accuracy: 0.8700 - loss: 0.3564

47/80 ━━━━━━━━━━━━━━━━━━━━ 0s 28ms/step - accuracy: 0.8713 - loss: 0.3539

49/80 ━━━━━━━━━━━━━━━━━━━━ 0s 28ms/step - accuracy: 0.8717 - loss: 0.3527

51/80 ━━━━━━━━━━━━━━━━━━━━ 0s 28ms/step - accuracy: 0.8721 - loss: 0.3515

53/80 ━━━━━━━━━━━━━━━━━━━━ 0s 28ms/step - accuracy: 0.8734 - loss: 0.3510

55/80 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/step - accuracy: 0.8736 - loss: 0.3511

57/80 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/step - accuracy: 0.8745 - loss: 0.3502

59/80 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/step - accuracy: 0.8738 - loss: 0.3510

61/80 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/step - accuracy: 0.8723 - loss: 0.3533

63/80 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/step - accuracy: 0.8729 - loss: 0.3511

65/80 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/step - accuracy: 0.8720 - loss: 0.3547

67/80 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/step - accuracy: 0.8707 - loss: 0.3576

69/80 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/step - accuracy: 0.8710 - loss: 0.3565

71/80 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/step - accuracy: 0.8703 - loss: 0.3578

73/80 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/step - accuracy: 0.8689 - loss: 0.3612

75/80 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/step - accuracy: 0.8687 - loss: 0.3606

77/80 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/step - accuracy: 0.8684 - loss: 0.3614

79/80 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/step - accuracy: 0.8692 - loss: 0.3594

80/80 ━━━━━━━━━━━━━━━━━━━━ 2s 30ms/step - accuracy: 0.8693 - loss: 0.3596 - val_accuracy: 0.8528 - val_loss: 0.3906

9. Informe de la CNN sin aumento

f0=diagnostico_entrenamiento(h0,"sin aumento")
curvas_entrenamiento(h0,"Sin aumento")
te0=m0.evaluate(xte,yte,verbose=0)
print(f"TEST sin aumento  loss={te0[0]:.4f} acc={te0[1]:.4f}")
modelo                  sin aumento
epocas_corridas                   5
mejor_epoca_val_loss              5
min_val_loss               0.390559
val_loss_final             0.390559
train_loss_en_mejor        0.359566
train_loss_final           0.359566
delta_val_tras_mejor            0.0
gap_loss_mejor             0.030993
gap_loss_final             0.030993
train_acc_mejor            0.869314
val_acc_mejor              0.852778
train_acc_final            0.869314
val_acc_final              0.852778
gap_acc_mejor              0.016536
gap_acc_final              0.016536

LECTURA
La mejor val_loss coincide con la última época: no hay tramo posterior de deterioro.

TEST sin aumento  loss=0.4196 acc=0.8487

Interpretación

Anote mejor época y gap. Un train_acc que se dispara con val plana es el patrón de catálogo memorizado: la ficha oficial no es la foto del cliente.

10. Entrenamiento de la CNN con aumento

m1=cnn(True)
h1=m1.fit(x_tr,y_tr,validation_split=0.15,epochs=5,batch_size=128,callbacks=[es],verbose=1)
Epoch 1/5


 1/80 ━━━━━━━━━━━━━━━━━━━━ 3:25 3s/step - accuracy: 0.0547 - loss: 2.3150

 2/80 ━━━━━━━━━━━━━━━━━━━━ 4s 52ms/step - accuracy: 0.1055 - loss: 2.2966

 3/80 ━━━━━━━━━━━━━━━━━━━━ 3s 51ms/step - accuracy: 0.1354 - loss: 2.2807

 5/80 ━━━━━━━━━━━━━━━━━━━━ 3s 45ms/step - accuracy: 0.1594 - loss: 2.2557

 7/80 ━━━━━━━━━━━━━━━━━━━━ 3s 45ms/step - accuracy: 0.1953 - loss: 2.2189

 9/80 ━━━━━━━━━━━━━━━━━━━━ 3s 45ms/step - accuracy: 0.2161 - loss: 2.1752

11/80 ━━━━━━━━━━━━━━━━━━━━ 3s 45ms/step - accuracy: 0.2472 - loss: 2.1272

13/80 ━━━━━━━━━━━━━━━━━━━━ 3s 45ms/step - accuracy: 0.2716 - loss: 2.0751

14/80 ━━━━━━━━━━━━━━━━━━━━ 3s 45ms/step - accuracy: 0.2746 - loss: 2.0503

16/80 ━━━━━━━━━━━━━━━━━━━━ 2s 45ms/step - accuracy: 0.2847 - loss: 1.9994

17/80 ━━━━━━━━━━━━━━━━━━━━ 2s 46ms/step - accuracy: 0.2987 - loss: 1.9694

19/80 ━━━━━━━━━━━━━━━━━━━━ 2s 46ms/step - accuracy: 0.3191 - loss: 1.9156

21/80 ━━━━━━━━━━━━━━━━━━━━ 2s 46ms/step - accuracy: 0.3374 - loss: 1.8664

23/80 ━━━━━━━━━━━━━━━━━━━━ 2s 46ms/step - accuracy: 0.3546 - loss: 1.8113

25/80 ━━━━━━━━━━━━━━━━━━━━ 2s 46ms/step - accuracy: 0.3731 - loss: 1.7613

27/80 ━━━━━━━━━━━━━━━━━━━━ 2s 46ms/step - accuracy: 0.3900 - loss: 1.7136

28/80 ━━━━━━━━━━━━━━━━━━━━ 2s 46ms/step - accuracy: 0.3959 - loss: 1.6947

29/80 ━━━━━━━━━━━━━━━━━━━━ 2s 46ms/step - accuracy: 0.4025 - loss: 1.6795

31/80 ━━━━━━━━━━━━━━━━━━━━ 2s 47ms/step - accuracy: 0.4171 - loss: 1.6416

33/80 ━━━━━━━━━━━━━━━━━━━━ 2s 46ms/step - accuracy: 0.4290 - loss: 1.6063

35/80 ━━━━━━━━━━━━━━━━━━━━ 2s 46ms/step - accuracy: 0.4402 - loss: 1.5741

37/80 ━━━━━━━━━━━━━━━━━━━━ 1s 46ms/step - accuracy: 0.4504 - loss: 1.5505

39/80 ━━━━━━━━━━━━━━━━━━━━ 1s 46ms/step - accuracy: 0.4585 - loss: 1.5286

41/80 ━━━━━━━━━━━━━━━━━━━━ 1s 45ms/step - accuracy: 0.4657 - loss: 1.5026

43/80 ━━━━━━━━━━━━━━━━━━━━ 1s 45ms/step - accuracy: 0.4757 - loss: 1.4792

45/80 ━━━━━━━━━━━━━━━━━━━━ 1s 44ms/step - accuracy: 0.4802 - loss: 1.4621

47/80 ━━━━━━━━━━━━━━━━━━━━ 1s 44ms/step - accuracy: 0.4842 - loss: 1.4451

49/80 ━━━━━━━━━━━━━━━━━━━━ 1s 44ms/step - accuracy: 0.4909 - loss: 1.4267

51/80 ━━━━━━━━━━━━━━━━━━━━ 1s 43ms/step - accuracy: 0.4951 - loss: 1.4150

53/80 ━━━━━━━━━━━━━━━━━━━━ 1s 43ms/step - accuracy: 0.4996 - loss: 1.4026

55/80 ━━━━━━━━━━━━━━━━━━━━ 1s 43ms/step - accuracy: 0.5058 - loss: 1.3850

57/80 ━━━━━━━━━━━━━━━━━━━━ 0s 43ms/step - accuracy: 0.5115 - loss: 1.3697

59/80 ━━━━━━━━━━━━━━━━━━━━ 0s 42ms/step - accuracy: 0.5162 - loss: 1.3557

61/80 ━━━━━━━━━━━━━━━━━━━━ 0s 42ms/step - accuracy: 0.5201 - loss: 1.3454

63/80 ━━━━━━━━━━━━━━━━━━━━ 0s 42ms/step - accuracy: 0.5250 - loss: 1.3312

65/80 ━━━━━━━━━━━━━━━━━━━━ 0s 42ms/step - accuracy: 0.5284 - loss: 1.3198

67/80 ━━━━━━━━━━━━━━━━━━━━ 0s 41ms/step - accuracy: 0.5321 - loss: 1.3080

69/80 ━━━━━━━━━━━━━━━━━━━━ 0s 41ms/step - accuracy: 0.5370 - loss: 1.2948

71/80 ━━━━━━━━━━━━━━━━━━━━ 0s 41ms/step - accuracy: 0.5403 - loss: 1.2830

73/80 ━━━━━━━━━━━━━━━━━━━━ 0s 41ms/step - accuracy: 0.5443 - loss: 1.2730

75/80 ━━━━━━━━━━━━━━━━━━━━ 0s 41ms/step - accuracy: 0.5480 - loss: 1.2630

77/80 ━━━━━━━━━━━━━━━━━━━━ 0s 41ms/step - accuracy: 0.5512 - loss: 1.2545

79/80 ━━━━━━━━━━━━━━━━━━━━ 0s 41ms/step - accuracy: 0.5546 - loss: 1.2454

80/80 ━━━━━━━━━━━━━━━━━━━━ 6s 48ms/step - accuracy: 0.5559 - loss: 1.2425 - val_accuracy: 0.6956 - val_loss: 0.8199

Epoch 2/5


 1/80 ━━━━━━━━━━━━━━━━━━━━ 6s 88ms/step - accuracy: 0.6875 - loss: 0.8108

 3/80 ━━━━━━━━━━━━━━━━━━━━ 2s 37ms/step - accuracy: 0.6667 - loss: 0.9156

 5/80 ━━━━━━━━━━━━━━━━━━━━ 2s 35ms/step - accuracy: 0.6719 - loss: 0.8796

 7/80 ━━━━━━━━━━━━━━━━━━━━ 2s 35ms/step - accuracy: 0.6741 - loss: 0.8918

 9/80 ━━━━━━━━━━━━━━━━━━━━ 2s 35ms/step - accuracy: 0.6840 - loss: 0.8657

11/80 ━━━━━━━━━━━━━━━━━━━━ 2s 37ms/step - accuracy: 0.6889 - loss: 0.8672

13/80 ━━━━━━━━━━━━━━━━━━━━ 2s 38ms/step - accuracy: 0.6809 - loss: 0.8706

15/80 ━━━━━━━━━━━━━━━━━━━━ 2s 39ms/step - accuracy: 0.6797 - loss: 0.8880

17/80 ━━━━━━━━━━━━━━━━━━━━ 2s 39ms/step - accuracy: 0.6792 - loss: 0.8868

19/80 ━━━━━━━━━━━━━━━━━━━━ 2s 40ms/step - accuracy: 0.6805 - loss: 0.8881

21/80 ━━━━━━━━━━━━━━━━━━━━ 2s 40ms/step - accuracy: 0.6778 - loss: 0.8898

23/80 ━━━━━━━━━━━━━━━━━━━━ 2s 40ms/step - accuracy: 0.6800 - loss: 0.8840

24/80 ━━━━━━━━━━━━━━━━━━━━ 2s 41ms/step - accuracy: 0.6810 - loss: 0.8789

26/80 ━━━━━━━━━━━━━━━━━━━━ 2s 41ms/step - accuracy: 0.6830 - loss: 0.8755

28/80 ━━━━━━━━━━━━━━━━━━━━ 2s 41ms/step - accuracy: 0.6864 - loss: 0.8687

30/80 ━━━━━━━━━━━━━━━━━━━━ 2s 41ms/step - accuracy: 0.6878 - loss: 0.8674

32/80 ━━━━━━━━━━━━━━━━━━━━ 1s 40ms/step - accuracy: 0.6875 - loss: 0.8672

34/80 ━━━━━━━━━━━━━━━━━━━━ 1s 40ms/step - accuracy: 0.6873 - loss: 0.8657

36/80 ━━━━━━━━━━━━━━━━━━━━ 1s 40ms/step - accuracy: 0.6862 - loss: 0.8645

38/80 ━━━━━━━━━━━━━━━━━━━━ 1s 40ms/step - accuracy: 0.6852 - loss: 0.8700

39/80 ━━━━━━━━━━━━━━━━━━━━ 1s 40ms/step - accuracy: 0.6861 - loss: 0.8666

41/80 ━━━━━━━━━━━━━━━━━━━━ 1s 40ms/step - accuracy: 0.6865 - loss: 0.8624

43/80 ━━━━━━━━━━━━━━━━━━━━ 1s 40ms/step - accuracy: 0.6875 - loss: 0.8571

45/80 ━━━━━━━━━━━━━━━━━━━━ 1s 40ms/step - accuracy: 0.6873 - loss: 0.8562

47/80 ━━━━━━━━━━━━━━━━━━━━ 1s 40ms/step - accuracy: 0.6892 - loss: 0.8516

48/80 ━━━━━━━━━━━━━━━━━━━━ 1s 40ms/step - accuracy: 0.6896 - loss: 0.8499

50/80 ━━━━━━━━━━━━━━━━━━━━ 1s 40ms/step - accuracy: 0.6919 - loss: 0.8486

52/80 ━━━━━━━━━━━━━━━━━━━━ 1s 40ms/step - accuracy: 0.6949 - loss: 0.8421

54/80 ━━━━━━━━━━━━━━━━━━━━ 1s 40ms/step - accuracy: 0.6960 - loss: 0.8386

56/80 ━━━━━━━━━━━━━━━━━━━━ 0s 40ms/step - accuracy: 0.6964 - loss: 0.8373

58/80 ━━━━━━━━━━━━━━━━━━━━ 0s 40ms/step - accuracy: 0.6977 - loss: 0.8363

60/80 ━━━━━━━━━━━━━━━━━━━━ 0s 40ms/step - accuracy: 0.6991 - loss: 0.8350

62/80 ━━━━━━━━━━━━━━━━━━━━ 0s 40ms/step - accuracy: 0.6987 - loss: 0.8353

64/80 ━━━━━━━━━━━━━━━━━━━━ 0s 40ms/step - accuracy: 0.6979 - loss: 0.8362

66/80 ━━━━━━━━━━━━━━━━━━━━ 0s 40ms/step - accuracy: 0.6983 - loss: 0.8350

68/80 ━━━━━━━━━━━━━━━━━━━━ 0s 40ms/step - accuracy: 0.6986 - loss: 0.8326

70/80 ━━━━━━━━━━━━━━━━━━━━ 0s 40ms/step - accuracy: 0.7000 - loss: 0.8303

72/80 ━━━━━━━━━━━━━━━━━━━━ 0s 40ms/step - accuracy: 0.7019 - loss: 0.8276

74/80 ━━━━━━━━━━━━━━━━━━━━ 0s 40ms/step - accuracy: 0.7014 - loss: 0.8281

76/80 ━━━━━━━━━━━━━━━━━━━━ 0s 40ms/step - accuracy: 0.7030 - loss: 0.8264

78/80 ━━━━━━━━━━━━━━━━━━━━ 0s 40ms/step - accuracy: 0.7043 - loss: 0.8243

80/80 ━━━━━━━━━━━━━━━━━━━━ 0s 40ms/step - accuracy: 0.7045 - loss: 0.8233

80/80 ━━━━━━━━━━━━━━━━━━━━ 4s 44ms/step - accuracy: 0.7045 - loss: 0.8233 - val_accuracy: 0.7339 - val_loss: 0.7488

Epoch 3/5


 1/80 ━━━━━━━━━━━━━━━━━━━━ 7s 93ms/step - accuracy: 0.6484 - loss: 0.7902

 2/80 ━━━━━━━━━━━━━━━━━━━━ 3s 51ms/step - accuracy: 0.7031 - loss: 0.7919

 3/80 ━━━━━━━━━━━━━━━━━━━━ 4s 53ms/step - accuracy: 0.7109 - loss: 0.7510

 5/80 ━━━━━━━━━━━━━━━━━━━━ 3s 51ms/step - accuracy: 0.7234 - loss: 0.7170

 7/80 ━━━━━━━━━━━━━━━━━━━━ 3s 50ms/step - accuracy: 0.6964 - loss: 0.7772

 9/80 ━━━━━━━━━━━━━━━━━━━━ 3s 47ms/step - accuracy: 0.7179 - loss: 0.7479

11/80 ━━━━━━━━━━━━━━━━━━━━ 3s 45ms/step - accuracy: 0.7180 - loss: 0.7579

13/80 ━━━━━━━━━━━━━━━━━━━━ 3s 45ms/step - accuracy: 0.7175 - loss: 0.7643

15/80 ━━━━━━━━━━━━━━━━━━━━ 2s 45ms/step - accuracy: 0.7151 - loss: 0.7680

16/80 ━━━━━━━━━━━━━━━━━━━━ 2s 45ms/step - accuracy: 0.7153 - loss: 0.7728

18/80 ━━━━━━━━━━━━━━━━━━━━ 2s 45ms/step - accuracy: 0.7183 - loss: 0.7700

20/80 ━━━━━━━━━━━━━━━━━━━━ 2s 44ms/step - accuracy: 0.7129 - loss: 0.7763

22/80 ━━━━━━━━━━━━━━━━━━━━ 2s 43ms/step - accuracy: 0.7113 - loss: 0.7750

24/80 ━━━━━━━━━━━━━━━━━━━━ 2s 42ms/step - accuracy: 0.7152 - loss: 0.7659

26/80 ━━━━━━━━━━━━━━━━━━━━ 2s 41ms/step - accuracy: 0.7169 - loss: 0.7607

28/80 ━━━━━━━━━━━━━━━━━━━━ 2s 42ms/step - accuracy: 0.7227 - loss: 0.7567

30/80 ━━━━━━━━━━━━━━━━━━━━ 2s 41ms/step - accuracy: 0.7219 - loss: 0.7589

32/80 ━━━━━━━━━━━━━━━━━━━━ 1s 41ms/step - accuracy: 0.7197 - loss: 0.7644

34/80 ━━━━━━━━━━━━━━━━━━━━ 1s 41ms/step - accuracy: 0.7215 - loss: 0.7606

36/80 ━━━━━━━━━━━━━━━━━━━━ 1s 40ms/step - accuracy: 0.7214 - loss: 0.7596

38/80 ━━━━━━━━━━━━━━━━━━━━ 1s 40ms/step - accuracy: 0.7198 - loss: 0.7662

40/80 ━━━━━━━━━━━━━━━━━━━━ 1s 40ms/step - accuracy: 0.7207 - loss: 0.7644

42/80 ━━━━━━━━━━━━━━━━━━━━ 1s 40ms/step - accuracy: 0.7217 - loss: 0.7612

44/80 ━━━━━━━━━━━━━━━━━━━━ 1s 40ms/step - accuracy: 0.7237 - loss: 0.7572

46/80 ━━━━━━━━━━━━━━━━━━━━ 1s 40ms/step - accuracy: 0.7233 - loss: 0.7561

48/80 ━━━━━━━━━━━━━━━━━━━━ 1s 40ms/step - accuracy: 0.7222 - loss: 0.7572

50/80 ━━━━━━━━━━━━━━━━━━━━ 1s 40ms/step - accuracy: 0.7237 - loss: 0.7545

52/80 ━━━━━━━━━━━━━━━━━━━━ 1s 40ms/step - accuracy: 0.7255 - loss: 0.7486

54/80 ━━━━━━━━━━━━━━━━━━━━ 1s 40ms/step - accuracy: 0.7266 - loss: 0.7474

56/80 ━━━━━━━━━━━━━━━━━━━━ 0s 40ms/step - accuracy: 0.7280 - loss: 0.7465

58/80 ━━━━━━━━━━━━━━━━━━━━ 0s 40ms/step - accuracy: 0.7268 - loss: 0.7476

60/80 ━━━━━━━━━━━━━━━━━━━━ 0s 40ms/step - accuracy: 0.7272 - loss: 0.7476

62/80 ━━━━━━━━━━━━━━━━━━━━ 0s 40ms/step - accuracy: 0.7262 - loss: 0.7505

64/80 ━━━━━━━━━━━━━━━━━━━━ 0s 40ms/step - accuracy: 0.7266 - loss: 0.7491

66/80 ━━━━━━━━━━━━━━━━━━━━ 0s 40ms/step - accuracy: 0.7274 - loss: 0.7481

68/80 ━━━━━━━━━━━━━━━━━━━━ 0s 40ms/step - accuracy: 0.7279 - loss: 0.7458

70/80 ━━━━━━━━━━━━━━━━━━━━ 0s 40ms/step - accuracy: 0.7292 - loss: 0.7430

72/80 ━━━━━━━━━━━━━━━━━━━━ 0s 40ms/step - accuracy: 0.7300 - loss: 0.7424

74/80 ━━━━━━━━━━━━━━━━━━━━ 0s 40ms/step - accuracy: 0.7294 - loss: 0.7442

76/80 ━━━━━━━━━━━━━━━━━━━━ 0s 40ms/step - accuracy: 0.7292 - loss: 0.7442

78/80 ━━━━━━━━━━━━━━━━━━━━ 0s 40ms/step - accuracy: 0.7287 - loss: 0.7433

80/80 ━━━━━━━━━━━━━━━━━━━━ 0s 40ms/step - accuracy: 0.7291 - loss: 0.7419

80/80 ━━━━━━━━━━━━━━━━━━━━ 4s 44ms/step - accuracy: 0.7291 - loss: 0.7419 - val_accuracy: 0.7594 - val_loss: 0.6804

Epoch 4/5


 1/80 ━━━━━━━━━━━━━━━━━━━━ 6s 84ms/step - accuracy: 0.7266 - loss: 0.6788

 2/80 ━━━━━━━━━━━━━━━━━━━━ 4s 58ms/step - accuracy: 0.7188 - loss: 0.7061

 3/80 ━━━━━━━━━━━━━━━━━━━━ 4s 57ms/step - accuracy: 0.7318 - loss: 0.6946

 5/80 ━━━━━━━━━━━━━━━━━━━━ 3s 47ms/step - accuracy: 0.7578 - loss: 0.6466

 7/80 ━━━━━━━━━━━━━━━━━━━━ 3s 45ms/step - accuracy: 0.7310 - loss: 0.7015

 9/80 ━━━━━━━━━━━━━━━━━━━━ 3s 44ms/step - accuracy: 0.7378 - loss: 0.6761

11/80 ━━━━━━━━━━━━━━━━━━━━ 2s 42ms/step - accuracy: 0.7436 - loss: 0.6819

13/80 ━━━━━━━━━━━━━━━━━━━━ 2s 42ms/step - accuracy: 0.7404 - loss: 0.6913

15/80 ━━━━━━━━━━━━━━━━━━━━ 2s 41ms/step - accuracy: 0.7406 - loss: 0.6993

17/80 ━━━━━━━━━━━━━━━━━━━━ 2s 40ms/step - accuracy: 0.7408 - loss: 0.6980

19/80 ━━━━━━━━━━━━━━━━━━━━ 2s 41ms/step - accuracy: 0.7430 - loss: 0.7016

21/80 ━━━━━━━━━━━━━━━━━━━━ 2s 40ms/step - accuracy: 0.7403 - loss: 0.7078

23/80 ━━━━━━━━━━━━━━━━━━━━ 2s 39ms/step - accuracy: 0.7425 - loss: 0.7020

25/80 ━━━━━━━━━━━━━━━━━━━━ 2s 39ms/step - accuracy: 0.7428 - loss: 0.6999

27/80 ━━━━━━━━━━━━━━━━━━━━ 2s 40ms/step - accuracy: 0.7471 - loss: 0.6934

29/80 ━━━━━━━━━━━━━━━━━━━━ 2s 39ms/step - accuracy: 0.7484 - loss: 0.6926

31/80 ━━━━━━━━━━━━━━━━━━━━ 1s 39ms/step - accuracy: 0.7467 - loss: 0.6946

33/80 ━━━━━━━━━━━━━━━━━━━━ 1s 39ms/step - accuracy: 0.7479 - loss: 0.6920

35/80 ━━━━━━━━━━━━━━━━━━━━ 1s 39ms/step - accuracy: 0.7473 - loss: 0.6925

37/80 ━━━━━━━━━━━━━━━━━━━━ 1s 39ms/step - accuracy: 0.7477 - loss: 0.6927

40/80 ━━━━━━━━━━━━━━━━━━━━ 1s 37ms/step - accuracy: 0.7457 - loss: 0.6951

43/80 ━━━━━━━━━━━━━━━━━━━━ 1s 36ms/step - accuracy: 0.7480 - loss: 0.6884

45/80 ━━━━━━━━━━━━━━━━━━━━ 1s 36ms/step - accuracy: 0.7488 - loss: 0.6862

48/80 ━━━━━━━━━━━━━━━━━━━━ 1s 35ms/step - accuracy: 0.7497 - loss: 0.6854

50/80 ━━━━━━━━━━━━━━━━━━━━ 1s 35ms/step - accuracy: 0.7506 - loss: 0.6833

52/80 ━━━━━━━━━━━━━━━━━━━━ 0s 35ms/step - accuracy: 0.7521 - loss: 0.6786

55/80 ━━━━━━━━━━━━━━━━━━━━ 0s 34ms/step - accuracy: 0.7543 - loss: 0.6775

58/80 ━━━━━━━━━━━━━━━━━━━━ 0s 34ms/step - accuracy: 0.7543 - loss: 0.6782

61/80 ━━━━━━━━━━━━━━━━━━━━ 0s 33ms/step - accuracy: 0.7529 - loss: 0.6820

64/80 ━━━━━━━━━━━━━━━━━━━━ 0s 33ms/step - accuracy: 0.7539 - loss: 0.6827

67/80 ━━━━━━━━━━━━━━━━━━━━ 0s 32ms/step - accuracy: 0.7536 - loss: 0.6841

70/80 ━━━━━━━━━━━━━━━━━━━━ 0s 32ms/step - accuracy: 0.7560 - loss: 0.6784

73/80 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step - accuracy: 0.7562 - loss: 0.6800

76/80 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step - accuracy: 0.7563 - loss: 0.6802

79/80 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step - accuracy: 0.7564 - loss: 0.6791

80/80 ━━━━━━━━━━━━━━━━━━━━ 3s 33ms/step - accuracy: 0.7567 - loss: 0.6795 - val_accuracy: 0.7828 - val_loss: 0.5931

Epoch 5/5


 1/80 ━━━━━━━━━━━━━━━━━━━━ 3s 45ms/step - accuracy: 0.7422 - loss: 0.6047

 4/80 ━━━━━━━━━━━━━━━━━━━━ 1s 22ms/step - accuracy: 0.7656 - loss: 0.6160

 6/80 ━━━━━━━━━━━━━━━━━━━━ 1s 25ms/step - accuracy: 0.7669 - loss: 0.5996

 8/80 ━━━━━━━━━━━━━━━━━━━━ 2s 31ms/step - accuracy: 0.7598 - loss: 0.6284

10/80 ━━━━━━━━━━━━━━━━━━━━ 2s 33ms/step - accuracy: 0.7648 - loss: 0.6215

12/80 ━━━━━━━━━━━━━━━━━━━━ 2s 35ms/step - accuracy: 0.7715 - loss: 0.6191

14/80 ━━━━━━━━━━━━━━━━━━━━ 2s 35ms/step - accuracy: 0.7628 - loss: 0.6344

16/80 ━━━━━━━━━━━━━━━━━━━━ 2s 35ms/step - accuracy: 0.7627 - loss: 0.6393

18/80 ━━━━━━━━━━━━━━━━━━━━ 2s 36ms/step - accuracy: 0.7626 - loss: 0.6381

20/80 ━━━━━━━━━━━━━━━━━━━━ 2s 37ms/step - accuracy: 0.7598 - loss: 0.6454

22/80 ━━━━━━━━━━━━━━━━━━━━ 2s 37ms/step - accuracy: 0.7557 - loss: 0.6493

24/80 ━━━━━━━━━━━━━━━━━━━━ 2s 37ms/step - accuracy: 0.7617 - loss: 0.6416

26/80 ━━━━━━━━━━━━━━━━━━━━ 2s 37ms/step - accuracy: 0.7614 - loss: 0.6374

28/80 ━━━━━━━━━━━━━━━━━━━━ 1s 37ms/step - accuracy: 0.7645 - loss: 0.6379

30/80 ━━━━━━━━━━━━━━━━━━━━ 1s 37ms/step - accuracy: 0.7633 - loss: 0.6407

32/80 ━━━━━━━━━━━━━━━━━━━━ 1s 37ms/step - accuracy: 0.7629 - loss: 0.6460

34/80 ━━━━━━━━━━━━━━━━━━━━ 1s 37ms/step - accuracy: 0.7645 - loss: 0.6464

36/80 ━━━━━━━━━━━━━━━━━━━━ 1s 37ms/step - accuracy: 0.7630 - loss: 0.6472

38/80 ━━━━━━━━━━━━━━━━━━━━ 1s 36ms/step - accuracy: 0.7613 - loss: 0.6526

40/80 ━━━━━━━━━━━━━━━━━━━━ 1s 36ms/step - accuracy: 0.7621 - loss: 0.6513

42/80 ━━━━━━━━━━━━━━━━━━━━ 1s 36ms/step - accuracy: 0.7640 - loss: 0.6479

44/80 ━━━━━━━━━━━━━━━━━━━━ 1s 36ms/step - accuracy: 0.7670 - loss: 0.6446

46/80 ━━━━━━━━━━━━━━━━━━━━ 1s 36ms/step - accuracy: 0.7687 - loss: 0.6431

48/80 ━━━━━━━━━━━━━━━━━━━━ 1s 36ms/step - accuracy: 0.7686 - loss: 0.6426

50/80 ━━━━━━━━━━━━━━━━━━━━ 1s 36ms/step - accuracy: 0.7689 - loss: 0.6410

52/80 ━━━━━━━━━━━━━━━━━━━━ 1s 36ms/step - accuracy: 0.7701 - loss: 0.6361

54/80 ━━━━━━━━━━━━━━━━━━━━ 0s 36ms/step - accuracy: 0.7703 - loss: 0.6349

56/80 ━━━━━━━━━━━━━━━━━━━━ 0s 36ms/step - accuracy: 0.7711 - loss: 0.6335

58/80 ━━━━━━━━━━━━━━━━━━━━ 0s 36ms/step - accuracy: 0.7695 - loss: 0.6356

60/80 ━━━━━━━━━━━━━━━━━━━━ 0s 36ms/step - accuracy: 0.7685 - loss: 0.6386

62/80 ━━━━━━━━━━━━━━━━━━━━ 0s 36ms/step - accuracy: 0.7675 - loss: 0.6410

64/80 ━━━━━━━━━━━━━━━━━━━━ 0s 36ms/step - accuracy: 0.7682 - loss: 0.6397

66/80 ━━━━━━━━━━━━━━━━━━━━ 0s 36ms/step - accuracy: 0.7670 - loss: 0.6413

68/80 ━━━━━━━━━━━━━━━━━━━━ 0s 37ms/step - accuracy: 0.7672 - loss: 0.6402

70/80 ━━━━━━━━━━━━━━━━━━━━ 0s 37ms/step - accuracy: 0.7674 - loss: 0.6379

72/80 ━━━━━━━━━━━━━━━━━━━━ 0s 37ms/step - accuracy: 0.7678 - loss: 0.6380

74/80 ━━━━━━━━━━━━━━━━━━━━ 0s 37ms/step - accuracy: 0.7669 - loss: 0.6396

76/80 ━━━━━━━━━━━━━━━━━━━━ 0s 37ms/step - accuracy: 0.7666 - loss: 0.6401

78/80 ━━━━━━━━━━━━━━━━━━━━ 0s 37ms/step - accuracy: 0.7656 - loss: 0.6407

80/80 ━━━━━━━━━━━━━━━━━━━━ 0s 36ms/step - accuracy: 0.7653 - loss: 0.6404

80/80 ━━━━━━━━━━━━━━━━━━━━ 3s 40ms/step - accuracy: 0.7653 - loss: 0.6404 - val_accuracy: 0.7833 - val_loss: 0.6003

11. Informe de la CNN con aumento

f1=diagnostico_entrenamiento(h1,"con aumento")
curvas_entrenamiento(h1,"Con aumento")
te1=m1.evaluate(xte,yte,verbose=0)
print(f"TEST con aumento  loss={te1[0]:.4f} acc={te1[1]:.4f}")
modelo                  con aumento
epocas_corridas                   5
mejor_epoca_val_loss              4
min_val_loss               0.593138
val_loss_final             0.600278
train_loss_en_mejor        0.679502
train_loss_final           0.640417
delta_val_tras_mejor        0.00714
gap_loss_mejor            -0.086363
gap_loss_final            -0.040139
train_acc_mejor            0.756667
val_acc_mejor              0.782778
train_acc_final            0.765294
val_acc_final              0.783333
gap_acc_mejor             -0.026111
gap_acc_final             -0.018039

LECTURA
La mejor val_loss no es la última época (4 de 5). Si restore_best_weights=True, el modelo guardado no es el del último paso.

TEST con aumento  loss=0.6268 acc=0.7717

12. Tabla comparada de ambos entrenamientos

df=pd.DataFrame([
    {"modelo":"sin aumento","test_acc":te0[1],"test_loss":te0[0],**{k:f0.get(k) for k in ("mejor_epoca_val_loss","gap_acc_final","min_val_loss")}},
    {"modelo":"con aumento","test_acc":te1[1],"test_loss":te1[0],**{k:f1.get(k) for k in ("mejor_epoca_val_loss","gap_acc_final","min_val_loss")}},
])
print(df.to_string(index=False,float_format=lambda v:f"{v:.4f}"))
print("El aumento gana si sube test o reduce gap sin destruir val_loss. No si solo 'se ve más regularizado' en la gráfica.")
     modelo  test_acc  test_loss  mejor_epoca_val_loss  gap_acc_final  min_val_loss
sin aumento    0.8487     0.4196                     5         0.0165        0.3906
con aumento    0.7717     0.6268                     4        -0.0180        0.5931
El aumento gana si sube test o reduce gap sin destruir val_loss. No si solo 'se ve más regularizado' en la gráfica.

Idea clave

Comparar última época entre dos fit es un error de acta. Compare checkpoints (mejor val_loss) y el test común.

13. Reporte por prenda (modelo con aumento)

Shirt vs T-shirt es el conflicto clásico de este catálogo.

probs=m1.predict(xte,verbose=0); pred=probs.argmax(1)
informe_clasificacion(yte,pred,PRENDAS,"TEST — CNN con aumento")
TEST — CNN con aumento
              precision    recall  f1-score   support

     T-shirt     0.7659    0.7690    0.7675      1000
    Pantalón     0.9377    0.9640    0.9507      1000
    Pullover     0.6027    0.7100    0.6520      1000
     Vestido     0.7749    0.7780    0.7764      1000
      Abrigo     0.6649    0.6130    0.6379      1000
    Sandalia     0.7604    0.9490    0.8443      1000
      Camisa     0.4864    0.4280    0.4553      1000
   Zapatilla     0.8558    0.7480    0.7983      1000
       Bolso     0.9669    0.8750    0.9186      1000
       Botín     0.9227    0.8830    0.9024      1000

    accuracy                         0.7717     10000
   macro avg     0.7738    0.7717    0.7703     10000
weighted avg     0.7738    0.7717    0.7703     10000

Clases ordenadas por F1 (las de abajo son las más débiles):
    clase  precision  recall     f1  soporte
   Camisa     0.4864  0.4280 0.4553     1000
   Abrigo     0.6649  0.6130 0.6379     1000
 Pullover     0.6027  0.7100 0.6520     1000
  T-shirt     0.7659  0.7690 0.7675     1000
  Vestido     0.7749  0.7780 0.7764     1000
Zapatilla     0.8558  0.7480 0.7983     1000
 Sandalia     0.7604  0.9490 0.8443     1000
    Botín     0.9227  0.8830 0.9024     1000
    Bolso     0.9669  0.8750 0.9186     1000
 Pantalón     0.9377  0.9640 0.9507     1000
clase precision recall f1 soporte
6 Camisa 0.486364 0.428 0.455319 1000
4 Abrigo 0.664859 0.613 0.637877 1000
2 Pullover 0.602716 0.710 0.651974 1000
0 T-shirt 0.765936 0.769 0.767465 1000
3 Vestido 0.774900 0.778 0.776447 1000
7 Zapatilla 0.855835 0.748 0.798292 1000
5 Sandalia 0.760417 0.949 0.844306 1000
9 Botín 0.922675 0.883 0.902402 1000
8 Bolso 0.966851 0.875 0.918635 1000
1 Pantalón 0.937743 0.964 0.950690 1000

Interpretación

Ordene por F1. Si Camisa y T-shirt están abajo, el accuracy 0.89 no describe el mostrador: ahí es donde el cliente reclama. Precision alta y recall bajo en Botín significa que cuando dice botín suele acertar, pero se le escapan botines.

_=matriz_y_errores(yte,pred,PRENDAS,xte,probs,k=8)

14. Errores seguros vs indecisos

La confianza del softmax no es certeza. Sirve para priorizar revisión humana.

conf=probs[np.arange(len(pred)),pred]
err=pred!=yte
print(f"errores={err.sum()}  acc={1-err.mean():.4f}")
print(f"confianza media aciertos={conf[~err].mean():.3f}  errores={conf[err].mean():.3f}")
print(f"errores con conf>=0.90: {((err)&(conf>=0.90)).sum()}")
print(f"aciertos con conf<0.50: {((~err)&(conf<0.50)).sum()}")
errores=2283  acc=0.7717
confianza media aciertos=0.832  errores=0.598
errores con conf>=0.90: 147
aciertos con conf<0.50: 569

Interpretación

Errores con confianza ≥ 0.90 piden revisar representación o etiqueta. Aciertos indecisos piden umbral de rechazo, no más filtros.

15. Heatmaps (Grad-CAM simplificado)

La mancha indica dónde se apoyó la decisión, no por qué en sentido causal.

def grad_cam(modelo,imagen,capa="ultima_conv"):
    img=tf.convert_to_tensor(imagen[None,...])
    conv=modelo.get_layer(capa)
    cm=tf.keras.Model(modelo.input,[conv.output,modelo.output])
    with tf.GradientTape() as tape:
        mapas,preds=cm(img,training=False)
        clase=tf.argmax(preds[0]); perdida=preds[:,clase]
    grads=tape.gradient(perdida,mapas)[0]
    pesos=tf.reduce_mean(grads,axis=(0,1))
    cam=tf.nn.relu(tf.reduce_sum(mapas[0]*pesos,axis=-1))
    cam=cam/(tf.reduce_max(cam)+1e-8)
    return tf.image.resize(cam[...,None],(28,28)).numpy().squeeze(), int(clase), float(preds[0,clase])

err_idx=np.where(err)[0]
ej=[0,80,200] + ([int(err_idx[0])] if len(err_idx) else [1])
fig,axes=plt.subplots(2,4,figsize=(10,5))
for k,j in enumerate(ej):
    cam,ch,p=grad_cam(m1,xte[j])
    axes[0,k].imshow(xte[j].squeeze(),cmap="gray"); axes[0,k].set_title(f"V:{PRENDAS[yte[j]]}",fontsize=8); axes[0,k].axis("off")
    axes[1,k].imshow(xte[j].squeeze(),cmap="gray"); axes[1,k].imshow(cam,cmap="jet",alpha=0.45)
    axes[1,k].set_title(f"P:{PRENDAS[ch]} ({p:.2f})",fontsize=8); axes[1,k].axis("off")
plt.suptitle("Arriba imagen, abajo Grad-CAM")
plt.tight_layout(); plt.show()

Idea clave

Un Grad-CAM sobre la manga no prueba que la red ‘entendió’ una camisa. Prueba que esa región empujó el logit. Es evidencia espacial, no semántica.

16. Caso 2 — Foto de cliente vs ficha de estudio

El test oficial es estudio. El cliente fotografía con pulso, recorte y ruido. Medimos la caída de accuracy, no un adjetivo de robustez.

def acc(m,x,y):
    return m.evaluate(x,y,verbose=0)[1]
rng=np.random.default_rng(42)
x_ruido=np.clip(xte+rng.normal(0,0.15,xte.shape).astype("float32"),0,1)
x_shift=np.roll(xte,3,axis=2)
filas=[]
for nombre,m in [("sin aumento",m0),("con aumento",m1)]:
    filas.append({
        "modelo":nombre,
        "limpio":acc(m,xte,yte),
        "ruido":acc(m,x_ruido,yte),
        "shift":acc(m,x_shift,yte),
    })
    filas[-1]["caida_ruido"]=filas[-1]["limpio"]-filas[-1]["ruido"]
    filas[-1]["caida_shift"]=filas[-1]["limpio"]-filas[-1]["shift"]
print(pd.DataFrame(filas).to_string(index=False,float_format=lambda v:f"{v:.4f}"))
     modelo  limpio  ruido  shift  caida_ruido  caida_shift
sin aumento  0.8487 0.8264 0.4676       0.0223       0.3811
con aumento  0.7717 0.7057 0.7464       0.0660       0.0253
fig,ax=plt.subplots(1,3,figsize=(8,2.6))
for a,im,t in zip(ax,[xte[0],x_ruido[0],x_shift[0]],["Ficha","Ruido cliente","Shift recorte"]):
    a.imshow(im.squeeze(),cmap="gray"); a.set_title(t); a.axis("off")
plt.tight_layout(); plt.show()

Interpretación

Si el aumento sube el test limpio pero no reduce caida_ruido, regularizó el protocolo oficial, no la variabilidad que importa. Robustez es una diferencia medida bajo una perturbación declarada.

17. Caso 3 — Proxy de defectos en color (CIFAR-10, 4 clases)

Un segundo dominio: objetos en color, como un control visual grosero de línea. No es un defect dataset industrial; sirve para ver si el informe (curvas + F1) se sostiene fuera del gris 28×28.

(c_tr,cy_tr),(c_te,cy_te)=tf.keras.datasets.cifar10.load_data()
cy_tr,cy_te=cy_tr.ravel(),cy_te.ravel()
sel=np.isin(cy_tr,[0,1,8,9])  # avion, auto, barco, camion — 'cajas' de logística
x=c_tr[sel][:6000].astype("float32")/255.0
y=cy_tr[sel][:6000]
# remap
conv={0:0,1:1,8:2,9:3}; y=np.vectorize(conv.get)(y)
LOG=["avion","auto","barco","camion"]
xt=c_te[np.isin(cy_te,[0,1,8,9])][:1500].astype("float32")/255.0
yt=np.vectorize(conv.get)(cy_te[np.isin(cy_te,[0,1,8,9])][:1500])
print(x.shape,xt.shape)
(6000, 32, 32, 3) (1500, 32, 32, 3)

18. CNN de logística y su informe

mq=tf.keras.Sequential([
    tf.keras.layers.Input((32,32,3)),
    tf.keras.layers.Conv2D(32,3,activation="relu",padding="same"),
    tf.keras.layers.MaxPool2D(),
    tf.keras.layers.Conv2D(64,3,activation="relu",padding="same"),
    tf.keras.layers.MaxPool2D(),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(64,activation="relu"),
    tf.keras.layers.Dense(4,activation="softmax"),
])
mq.compile(optimizer="adam",loss="sparse_categorical_crossentropy",metrics=["accuracy"])
hq=mq.fit(x,y,validation_split=0.2,epochs=5,batch_size=64,verbose=1,
          callbacks=[tf.keras.callbacks.EarlyStopping(monitor="val_loss",patience=2,restore_best_weights=True)])
Epoch 1/5


 1/75 ━━━━━━━━━━━━━━━━━━━━ 1:24 1s/step - accuracy: 0.2500 - loss: 1.3814

 3/75 ━━━━━━━━━━━━━━━━━━━━ 2s 36ms/step - accuracy: 0.2396 - loss: 1.4761

 5/75 ━━━━━━━━━━━━━━━━━━━━ 2s 31ms/step - accuracy: 0.2406 - loss: 1.4530

 7/75 ━━━━━━━━━━━━━━━━━━━━ 2s 30ms/step - accuracy: 0.2522 - loss: 1.4365

 9/75 ━━━━━━━━━━━━━━━━━━━━ 1s 28ms/step - accuracy: 0.2361 - loss: 1.4316

12/75 ━━━━━━━━━━━━━━━━━━━━ 1s 27ms/step - accuracy: 0.2422 - loss: 1.4179

15/75 ━━━━━━━━━━━━━━━━━━━━ 1s 26ms/step - accuracy: 0.2677 - loss: 1.4092

18/75 ━━━━━━━━━━━━━━━━━━━━ 1s 25ms/step - accuracy: 0.2882 - loss: 1.4024

21/75 ━━━━━━━━━━━━━━━━━━━━ 1s 25ms/step - accuracy: 0.3140 - loss: 1.3953

24/75 ━━━━━━━━━━━━━━━━━━━━ 1s 25ms/step - accuracy: 0.3307 - loss: 1.3882

27/75 ━━━━━━━━━━━━━━━━━━━━ 1s 25ms/step - accuracy: 0.3368 - loss: 1.3808

30/75 ━━━━━━━━━━━━━━━━━━━━ 1s 25ms/step - accuracy: 0.3432 - loss: 1.3700

33/75 ━━━━━━━━━━━━━━━━━━━━ 1s 25ms/step - accuracy: 0.3494 - loss: 1.3615

36/75 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step - accuracy: 0.3563 - loss: 1.3483

39/75 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step - accuracy: 0.3638 - loss: 1.3364

42/75 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step - accuracy: 0.3772 - loss: 1.3228

45/75 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step - accuracy: 0.3878 - loss: 1.3049

47/75 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step - accuracy: 0.3949 - loss: 1.2958

49/75 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step - accuracy: 0.3967 - loss: 1.2917

52/75 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step - accuracy: 0.4023 - loss: 1.2801

55/75 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step - accuracy: 0.4045 - loss: 1.2750

58/75 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step - accuracy: 0.4119 - loss: 1.2648

61/75 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step - accuracy: 0.4173 - loss: 1.2561

64/75 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step - accuracy: 0.4226 - loss: 1.2474

67/75 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step - accuracy: 0.4275 - loss: 1.2387

69/75 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step - accuracy: 0.4278 - loss: 1.2366

71/75 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step - accuracy: 0.4320 - loss: 1.2311

74/75 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step - accuracy: 0.4352 - loss: 1.2263

75/75 ━━━━━━━━━━━━━━━━━━━━ 4s 32ms/step - accuracy: 0.4379 - loss: 1.2228 - val_accuracy: 0.5400 - val_loss: 1.0722

Epoch 2/5


 1/75 ━━━━━━━━━━━━━━━━━━━━ 5s 71ms/step - accuracy: 0.5469 - loss: 1.0669

 3/75 ━━━━━━━━━━━━━━━━━━━━ 2s 31ms/step - accuracy: 0.5677 - loss: 1.0814

 5/75 ━━━━━━━━━━━━━━━━━━━━ 2s 31ms/step - accuracy: 0.5406 - loss: 1.1139

 7/75 ━━━━━━━━━━━━━━━━━━━━ 2s 30ms/step - accuracy: 0.5692 - loss: 1.0710

10/75 ━━━━━━━━━━━━━━━━━━━━ 1s 27ms/step - accuracy: 0.5813 - loss: 1.0481

13/75 ━━━━━━━━━━━━━━━━━━━━ 1s 27ms/step - accuracy: 0.5877 - loss: 1.0359

16/75 ━━━━━━━━━━━━━━━━━━━━ 1s 26ms/step - accuracy: 0.5771 - loss: 1.0426

19/75 ━━━━━━━━━━━━━━━━━━━━ 1s 25ms/step - accuracy: 0.5740 - loss: 1.0296

22/75 ━━━━━━━━━━━━━━━━━━━━ 1s 25ms/step - accuracy: 0.5724 - loss: 1.0261

25/75 ━━━━━━━━━━━━━━━━━━━━ 1s 24ms/step - accuracy: 0.5763 - loss: 1.0153

28/75 ━━━━━━━━━━━━━━━━━━━━ 1s 24ms/step - accuracy: 0.5737 - loss: 1.0152

31/75 ━━━━━━━━━━━━━━━━━━━━ 1s 24ms/step - accuracy: 0.5857 - loss: 1.0004

34/75 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step - accuracy: 0.5804 - loss: 1.0009

37/75 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step - accuracy: 0.5832 - loss: 0.9960

40/75 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step - accuracy: 0.5891 - loss: 0.9885

43/75 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step - accuracy: 0.5901 - loss: 0.9856

46/75 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step - accuracy: 0.5934 - loss: 0.9776

49/75 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step - accuracy: 0.5957 - loss: 0.9720

52/75 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step - accuracy: 0.5950 - loss: 0.9681

55/75 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step - accuracy: 0.5935 - loss: 0.9668

58/75 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step - accuracy: 0.5938 - loss: 0.9652

61/75 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step - accuracy: 0.5935 - loss: 0.9662

64/75 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step - accuracy: 0.5964 - loss: 0.9635

67/75 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step - accuracy: 0.5954 - loss: 0.9627

70/75 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step - accuracy: 0.5973 - loss: 0.9611

73/75 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step - accuracy: 0.5982 - loss: 0.9597

75/75 ━━━━━━━━━━━━━━━━━━━━ 2s 26ms/step - accuracy: 0.5981 - loss: 0.9574 - val_accuracy: 0.6125 - val_loss: 0.9235

Epoch 3/5


 1/75 ━━━━━━━━━━━━━━━━━━━━ 4s 63ms/step - accuracy: 0.6406 - loss: 0.9069

 4/75 ━━━━━━━━━━━━━━━━━━━━ 1s 21ms/step - accuracy: 0.6680 - loss: 0.9102

 7/75 ━━━━━━━━━━━━━━━━━━━━ 1s 21ms/step - accuracy: 0.6496 - loss: 0.9087

 9/75 ━━━━━━━━━━━━━━━━━━━━ 1s 23ms/step - accuracy: 0.6510 - loss: 0.8913

11/75 ━━━━━━━━━━━━━━━━━━━━ 1s 24ms/step - accuracy: 0.6562 - loss: 0.8903

13/75 ━━━━━━━━━━━━━━━━━━━━ 1s 25ms/step - accuracy: 0.6394 - loss: 0.9152

15/75 ━━━━━━━━━━━━━━━━━━━━ 1s 26ms/step - accuracy: 0.6313 - loss: 0.9274

17/75 ━━━━━━━━━━━━━━━━━━━━ 1s 26ms/step - accuracy: 0.6342 - loss: 0.9208

19/75 ━━━━━━━━━━━━━━━━━━━━ 1s 26ms/step - accuracy: 0.6357 - loss: 0.9147

22/75 ━━━━━━━━━━━━━━━━━━━━ 1s 26ms/step - accuracy: 0.6385 - loss: 0.9144

25/75 ━━━━━━━━━━━━━━━━━━━━ 1s 26ms/step - accuracy: 0.6388 - loss: 0.9049

28/75 ━━━━━━━━━━━━━━━━━━━━ 1s 26ms/step - accuracy: 0.6395 - loss: 0.8997

31/75 ━━━━━━━━━━━━━━━━━━━━ 1s 25ms/step - accuracy: 0.6507 - loss: 0.8836

34/75 ━━━━━━━━━━━━━━━━━━━━ 1s 25ms/step - accuracy: 0.6466 - loss: 0.8823

36/75 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step - accuracy: 0.6497 - loss: 0.8784

38/75 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step - accuracy: 0.6521 - loss: 0.8757

41/75 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step - accuracy: 0.6574 - loss: 0.8686

44/75 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step - accuracy: 0.6609 - loss: 0.8641

47/75 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step - accuracy: 0.6652 - loss: 0.8531

50/75 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step - accuracy: 0.6662 - loss: 0.8483

53/75 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step - accuracy: 0.6639 - loss: 0.8455

55/75 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step - accuracy: 0.6651 - loss: 0.8431

57/75 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step - accuracy: 0.6639 - loss: 0.8429

59/75 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step - accuracy: 0.6626 - loss: 0.8436

61/75 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step - accuracy: 0.6629 - loss: 0.8447

64/75 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step - accuracy: 0.6650 - loss: 0.8428

67/75 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step - accuracy: 0.6628 - loss: 0.8442

70/75 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step - accuracy: 0.6629 - loss: 0.8423

73/75 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step - accuracy: 0.6616 - loss: 0.8424

75/75 ━━━━━━━━━━━━━━━━━━━━ 2s 28ms/step - accuracy: 0.6608 - loss: 0.8404 - val_accuracy: 0.6400 - val_loss: 0.8625

Epoch 4/5


 1/75 ━━━━━━━━━━━━━━━━━━━━ 4s 63ms/step - accuracy: 0.6719 - loss: 0.8616

 4/75 ━━━━━━━━━━━━━━━━━━━━ 1s 24ms/step - accuracy: 0.6953 - loss: 0.8027

 6/75 ━━━━━━━━━━━━━━━━━━━━ 1s 24ms/step - accuracy: 0.6823 - loss: 0.8249

 9/75 ━━━━━━━━━━━━━━━━━━━━ 1s 24ms/step - accuracy: 0.6927 - loss: 0.7728

12/75 ━━━━━━━━━━━━━━━━━━━━ 1s 24ms/step - accuracy: 0.6979 - loss: 0.7675

15/75 ━━━━━━━━━━━━━━━━━━━━ 1s 23ms/step - accuracy: 0.6948 - loss: 0.7804

18/75 ━━━━━━━━━━━━━━━━━━━━ 1s 23ms/step - accuracy: 0.6936 - loss: 0.7720

21/75 ━━━━━━━━━━━━━━━━━━━━ 1s 22ms/step - accuracy: 0.6957 - loss: 0.7773

24/75 ━━━━━━━━━━━━━━━━━━━━ 1s 22ms/step - accuracy: 0.6979 - loss: 0.7645

27/75 ━━━━━━━━━━━━━━━━━━━━ 1s 22ms/step - accuracy: 0.6973 - loss: 0.7670

30/75 ━━━━━━━━━━━━━━━━━━━━ 1s 23ms/step - accuracy: 0.6984 - loss: 0.7573

33/75 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step - accuracy: 0.6979 - loss: 0.7587

36/75 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step - accuracy: 0.6988 - loss: 0.7567

39/75 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step - accuracy: 0.7039 - loss: 0.7497

42/75 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step - accuracy: 0.7057 - loss: 0.7488

45/75 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step - accuracy: 0.7108 - loss: 0.7409

48/75 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step - accuracy: 0.7119 - loss: 0.7371

51/75 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step - accuracy: 0.7102 - loss: 0.7341

53/75 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step - accuracy: 0.7114 - loss: 0.7303

56/75 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step - accuracy: 0.7126 - loss: 0.7274

59/75 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step - accuracy: 0.7121 - loss: 0.7291

62/75 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step - accuracy: 0.7119 - loss: 0.7305

65/75 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step - accuracy: 0.7127 - loss: 0.7292

67/75 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step - accuracy: 0.7120 - loss: 0.7304

69/75 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step - accuracy: 0.7099 - loss: 0.7317

71/75 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step - accuracy: 0.7113 - loss: 0.7293

73/75 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step - accuracy: 0.7102 - loss: 0.7315

75/75 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step - accuracy: 0.7098 - loss: 0.7305

75/75 ━━━━━━━━━━━━━━━━━━━━ 2s 27ms/step - accuracy: 0.7098 - loss: 0.7305 - val_accuracy: 0.6700 - val_loss: 0.8107

Epoch 5/5


 1/75 ━━━━━━━━━━━━━━━━━━━━ 5s 76ms/step - accuracy: 0.6719 - loss: 0.7672

 3/75 ━━━━━━━━━━━━━━━━━━━━ 2s 32ms/step - accuracy: 0.7292 - loss: 0.6927

 6/75 ━━━━━━━━━━━━━━━━━━━━ 1s 28ms/step - accuracy: 0.7057 - loss: 0.7261

 9/75 ━━━━━━━━━━━━━━━━━━━━ 1s 25ms/step - accuracy: 0.7240 - loss: 0.6841

12/75 ━━━━━━━━━━━━━━━━━━━━ 1s 24ms/step - accuracy: 0.7253 - loss: 0.6847

15/75 ━━━━━━━━━━━━━━━━━━━━ 1s 23ms/step - accuracy: 0.7250 - loss: 0.6971

18/75 ━━━━━━━━━━━━━━━━━━━━ 1s 23ms/step - accuracy: 0.7222 - loss: 0.6905

21/75 ━━━━━━━━━━━━━━━━━━━━ 1s 23ms/step - accuracy: 0.7217 - loss: 0.6967

24/75 ━━━━━━━━━━━━━━━━━━━━ 1s 23ms/step - accuracy: 0.7272 - loss: 0.6842

27/75 ━━━━━━━━━━━━━━━━━━━━ 1s 22ms/step - accuracy: 0.7274 - loss: 0.6867

30/75 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step - accuracy: 0.7286 - loss: 0.6767

33/75 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step - accuracy: 0.7301 - loss: 0.6778

36/75 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step - accuracy: 0.7300 - loss: 0.6772

39/75 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step - accuracy: 0.7356 - loss: 0.6699

42/75 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step - accuracy: 0.7385 - loss: 0.6698

45/75 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step - accuracy: 0.7420 - loss: 0.6628

48/75 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step - accuracy: 0.7422 - loss: 0.6596

51/75 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step - accuracy: 0.7420 - loss: 0.6572

54/75 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step - accuracy: 0.7442 - loss: 0.6513

57/75 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step - accuracy: 0.7451 - loss: 0.6526

60/75 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step - accuracy: 0.7448 - loss: 0.6531

63/75 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step - accuracy: 0.7448 - loss: 0.6539

66/75 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step - accuracy: 0.7472 - loss: 0.6513

69/75 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step - accuracy: 0.7459 - loss: 0.6541

72/75 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step - accuracy: 0.7467 - loss: 0.6527

75/75 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step - accuracy: 0.7458 - loss: 0.6532

75/75 ━━━━━━━━━━━━━━━━━━━━ 2s 26ms/step - accuracy: 0.7458 - loss: 0.6532 - val_accuracy: 0.6750 - val_loss: 0.7978
fq=diagnostico_entrenamiento(hq,"logística CIFAR-4")
curvas_entrenamiento(hq,"Logística (4 clases)")
print("TEST", mq.evaluate(xt,yt,verbose=0))
pr=mq.predict(xt,verbose=0); ph=pr.argmax(1)
informe_clasificacion(yt,ph,LOG,"TEST logística")
modelo                  logística CIFAR-4
epocas_corridas                         5
mejor_epoca_val_loss                    5
min_val_loss                     0.797809
val_loss_final                   0.797809
train_loss_en_mejor              0.653224
train_loss_final                 0.653224
delta_val_tras_mejor                  0.0
gap_loss_mejor                   0.144585
gap_loss_final                   0.144585
train_acc_mejor                  0.745833
val_acc_mejor                       0.675
train_acc_final                  0.745833
val_acc_final                       0.675
gap_acc_mejor                    0.070833
gap_acc_final                    0.070833

LECTURA
La mejor val_loss coincide con la última época: no hay tramo posterior de deterioro.

TEST [0.7431877255439758, 0.690666675567627]
TEST logística
              precision    recall  f1-score   support

       avion     0.7803    0.6432    0.7052       370
        auto     0.8101    0.5246    0.6368       366
       barco     0.8070    0.7225    0.7624       382
      camion     0.5357    0.8639    0.6613       382

    accuracy                         0.6907      1500
   macro avg     0.7333    0.6886    0.6914      1500
weighted avg     0.7321    0.6907    0.6919      1500

Clases ordenadas por F1 (las de abajo son las más débiles):
 clase  precision  recall     f1  soporte
  auto     0.8101  0.5246 0.6368      366
camion     0.5357  0.8639 0.6613      382
 avion     0.7803  0.6432 0.7052      370
 barco     0.8070  0.7225 0.7624      382
clase precision recall f1 soporte
1 auto 0.810127 0.524590 0.636816 366
3 camion 0.535714 0.863874 0.661323 382
0 avion 0.780328 0.643243 0.705185 370
2 barco 0.807018 0.722513 0.762431 382

Interpretación

Avión vs pájaro no está en este recorte; avión vs barco sí puede mezclar cielo y agua. Si barco tiene recall bajo, la línea ‘pierde’ contenedores marítimos: eso es una frase de operaciones, no un adorno.

19. Relación gap–perturbación

Un modelo con gap bajo en ficha y caída alta en ruido es frágil de protocolo. Uno con gap alto y caída baja puede estar regularizado de casualidad. Se reportan ambos.

print("Textil gap final sin/con aumento:", f0.get("gap_acc_final"), f1.get("gap_acc_final"))
print("Logística gap final:", fq.get("gap_acc_final"))
print("No hay un umbral universal de gap. Hay un umbral de negocio (reclamos, devoluciones).")
Textil gap final sin/con aumento: 0.016535937786102295 -0.018039226531982422
Logística gap final: 0.07083332538604736
No hay un umbral universal de gap. Hay un umbral de negocio (reclamos, devoluciones).

20. Calibración grosera de la confianza

Agrupamos predicciones por decil de confianza y medimos accuracy de cada cubo. Si el cubo 0.9–1.0 no está cerca de 0.9, la softmax no es una probabilidad usable para rechazo.

bins=np.linspace(0,1,6)
dig=np.digitize(conf,bins)-1
tab=[]
for b in range(5):
    msk=dig==b
    if msk.sum()==0: continue
    tab.append({"bin":f"{bins[b]:.1f}-{bins[b+1]:.1f}","n":int(msk.sum()),
                "acc":float((pred[msk]==yte[msk]).mean()), "conf_media":float(conf[msk].mean())})
print(pd.DataFrame(tab).to_string(index=False,float_format=lambda v:f"{v:.3f}"))
    bin    n   acc  conf_media
0.2-0.4  360 0.389       0.353
0.4-0.6 2113 0.506       0.506
0.6-0.8 2125 0.674       0.698
0.8-1.0 5386 0.939       0.945

Idea clave

Confianza alta y accuracy de cubo baja es mala calibración. No se arregla con más épocas; se arregla con temperatura, rechazo o mejor dato.

21. Amenazas a la validez

Subconjunto 12 000, 5 épocas, shift de 3 px no es ataque adversario, Grad-CAM no es causal, CIFAR-4 no es una planta.

22. Camisa vs T-shirt: el par que el accuracy esconde

Aislamos esas dos prendas en test y medimos precision/recall solo en ese subproblema. Es el reclamo típico del catálogo.

mask = np.isin(yte, [0, 6])
print("n test Camisa/T-shirt:", int(mask.sum()))
print(classification_report(yte[mask], pred[mask], labels=[0, 6], target_names=["T-shirt", "Camisa"], digits=3, zero_division=0))
cm2 = confusion_matrix(yte[mask], pred[mask], labels=[0, 6])
print("matriz 2x2\n", cm2)
n test Camisa/T-shirt: 2000
              precision    recall  f1-score   support

     T-shirt      0.803     0.769     0.785      1000
      Camisa      0.811     0.428     0.560      1000

   micro avg      0.806     0.599     0.687      2000
   macro avg      0.807     0.599     0.673      2000
weighted avg      0.807     0.599     0.673      2000

matriz 2x2
 [[769 100]
 [189 428]]

Interpretación

Si la off-diagonal es casi simétrica, las clases son ambiguas en 28×28. Si una dirección domina, el umbral o el aumento están sesgando el mostrador hacia una de las dos etiquetas.

23. Lectura del soporte en el reporte

El soporte (n por clase) ancla cada F1. Un F1 0.50 con soporte 30 no pesa igual que con soporte 1000. Fashion-MNIST engaña porque el soporte es parejo; un catálogo real no lo es.

24. Macro F1 frente a accuracy

Accuracy pondera por frecuencia. Macro F1 trata cada prenda igual. En un catálogo real (pocas bolsas, muchas camisetas) el macro es el número que merchandising entiende.

from sklearn.metrics import f1_score, accuracy_score
print("acc", accuracy_score(yte,pred))
print("macro F1", f1_score(yte,pred,average="macro"))
print("weighted F1", f1_score(yte,pred,average="weighted"))
print("Si macro << weighted, las clases difíciles tiran el promedio no ponderado.")
acc 0.7717
macro F1 0.77034084376738
weighted F1 0.7703408437673801
Si macro << weighted, las clases difíciles tiran el promedio no ponderado.

25. Qué no hacer con el heatmap

No anote «la red entiende el cuello». Anote «la activación se concentra en la región superior». La segunda frase es defendible en un informe de calidad.

26. Cierre

💬 ¿Te sirvió?Deja en los comentarios una duda o un caso donde aplicarías esto —respondo todos. Sígueme para no perderte el próximo artículo de la serie ycomparte con alguien que esté aprendiendo deep learning.👉 El código completo está disponible para ejecutar directamente.