# deep-learning-en-python-y-tensorflow
Deep Learning en Python y Tensorflow
Volver a la portada del cursoImplementación Práctica en Notebook
Sección 6 · Proyecto Final
Notebook: implementación práctica del clasificador de prendas
Este notebook es la solución de referencia del proyecto final: el clasificador que etiqueta solas las fotos del catálogo de moda de PyShop, de los datos crudos a un modelo guardado que predice fotos nuevas. Esta guía acompaña al notebook proyecto-clasificador-de-prendas, sección por sección, con los resultados que debes obtener. Te conviene intentar primero el proyecto por tu cuenta y usar el notebook para comparar.
Objetivos
- Recorrer el flujo completo: explorar, preparar, modelo base, MLP, CNN, evaluar, analizar errores, guardar y predecir.
- Comparar tres modelos con las mismas condiciones y una semilla fija.
- Leer una matriz de confusión y explicar el error más frecuente.
- Guardar un modelo en formato
.kerasy usarlo sobre fotos que no vio.
1. Explorar los datos
La primera celda copia los datos del curso (cargar_moda, semillas, CLASES, modelo_mlp, modelo_cnn). Después revisa: 60,000 fotos de entrenamiento y 10,000 de prueba, de 28×28 en uint8, con píxeles de 0 a 255 y media 72.94. Las clases están balanceadas: 6000 fotos por prenda en entrenamiento y 1000 en prueba. Una cuadrícula muestra ejemplos de las 10 prendas; las primeras etiquetas son botín, camiseta, camiseta y vestido.
2. Preparar
(x_tr, y_tr), (x_te, y_te) = cargar_moda() # píxeles en [0, 1]
xc_tr, xc_te = x_tr[..., None], x_te[..., None] # canal para la CNN
print(xc_tr.shape, round(float(x_tr.mean()), 3)) # (60000, 28, 28, 1) 0.286
3. Modelo base
Antes de una red profunda conviene un punto de comparación sencillo: Flatten → Dense(10, softmax), que equivale a una regresión logística sobre los 784 píxeles. Tiene 7,850 parámetros ($784 \times 10 + 10$) y, con 5 épocas, acierta 0.8366 en prueba. Todo modelo más complejo debe superar esa cifra para justificarse.
4. MLP
El MLP del curso agrega una capa oculta Dense(128, relu): 101,770 parámetros. Con 10 épocas, lotes de 64 y validation_split=0.1 llega a 0.8746 en prueba (pérdida 0.3674). Su val_loss mínima es 0.3379, en la época 7.
5. CNN con EarlyStopping
semillas(42)
cnn = modelo_cnn()
cnn.compile(optimizer="adam", metrics=["accuracy"],
loss="sparse_categorical_crossentropy")
alto = keras.callbacks.EarlyStopping(patience=3, restore_best_weights=True)
h = cnn.fit(xc_tr, y_tr, epochs=10, batch_size=64,
validation_split=0.1, callbacks=[alto], verbose=0)
print(cnn.evaluate(xc_te, y_te, verbose=0)) # [0.2697, 0.902] redondeado
La CNN tiene 34,826 parámetros, un tercio de los del MLP, y acierta 0.902 en prueba con pérdida 0.2697. Entrenarla tarda más que el MLP: en una CPU de escritorio, del orden de medio minuto. EarlyStopping no llega a detenerla: su val_loss baja en las 10 épocas (de 0.416 a 0.2505). El callback queda como seguro por si entrenas más épocas.
6. Curvas de entrenamiento
Dos gráficas, pérdida y accuracy, con las curvas de entrenamiento y de validación. En la CNN la val_accuracy sube de 0.8512 a 0.9082 y las dos curvas de pérdida bajan juntas: no hay sobreajuste en estas 10 épocas.
7. Matriz de confusión y acierto por clase
tf.math.confusion_matrix(y_te, pred) cuenta cuántas fotos de cada prenda real se predijeron como cada prenda; el notebook la dibuja como mapa de calor. El acierto por clase es la diagonal dividida entre 1000:
| Prenda | MLP | CNN |
|---|---|---|
| sandalia | 0.975 | 0.98 |
| pantalón | 0.968 | 0.979 |
| suéter | 0.779 | 0.868 |
| abrigo | 0.782 | 0.883 |
| camiseta | 0.857 | 0.898 |
| camisa | 0.601 | 0.601 |
La CNN mejora sobre todo en suéter y abrigo, prendas que se distinguen por texturas y bordes locales. La camisa se queda en 0.601 con los dos modelos.
8. Análisis de errores
La confusión más frecuente, en los dos modelos, es camisa → camiseta: 174 fotos. El notebook muestra ejemplos de camisas mal clasificadas: en 28×28 y en gris, una camisa sin botones visibles se parece mucho a una camiseta. Es un límite de los datos, no un error de código. En total, el MLP falla en 1254 de 10,000 fotos y la CNN en 980.
9. Tabla comparativa
| Modelo | Parámetros | Accuracy en prueba | Errores |
|---|---|---|---|
| Base: Flatten → Dense(10) | 7,850 | 0.8366 | — |
| MLP | 101,770 | 0.8746 | 1254 |
| CNN | 34,826 | 0.902 | 980 |
10. Guardar y cargar
cnn.save("moda_cnn.keras")
cargado = keras.models.load_model("moda_cnn.keras")
print(cargado.evaluate(xc_te, y_te, verbose=0)[1]) # 0.902 redondeado
El archivo pesa unos 442 KB y guarda arquitectura, pesos y configuración de compilación. El modelo cargado da la misma accuracy: 0.902.
11. Predecir fotos nuevas
Las 5 primeras fotos del conjunto de prueba hacen de fotos nuevas que suben los vendedores. Para cada una se imprimen las 3 prendas más probables:
| Foto | Prenda real | Top-3 de la CNN |
|---|---|---|
| 0 | botín | botín 0.998, tenis 0.001, sandalia 0.001 |
| 1 | suéter | suéter 1.0 |
| 2 | pantalón | pantalón 1.0 |
| 3 | pantalón | pantalón 1.0 |
| 4 | camisa | camisa 0.725, abrigo 0.134, camiseta 0.131 |
Las cinco son correctas, pero la camisa llega con 0.725: el modelo duda justo en la clase difícil. Para PyShop esto sugiere una regla práctica: etiquetar sola la foto cuando la probabilidad máxima es alta y mandar a revisión humana las dudosas.
Qué debes obtener
Modelo base 0.8366, MLP 0.8746, CNN 0.902; camisa → camiseta 174; errores 1254 contra 980; archivo de unos 442 KB que, al cargarse, da 0.902; botín 0.998 en la primera foto. Si tus números difieren, revisa que llamaste a semillas(42) justo antes de crear cada modelo y que usaste 10 épocas, lotes de 64 y validation_split=0.1. El notebook termina con un informe breve e ideas para mejorar: aumento de datos, BatchNormalization y una tercera capa convolucional.