Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Updated: 31 aug 2026

Clasificación de imágenes con Machine Learning

En este proyecto vamos a trabajar con CIFAR-10, un dataset abierto muy conocido en Machine Learning y visión computacional.

A diferencia del proyecto con Iris, donde clasificábamos flores usando medidas numéricas, aquí vamos a clasificar imágenes.

La pregunta central será:

¿Puede un modelo aprender a reconocer objetos en imágenes pequeñas?

Este notebook está diseñado para docentes de High School. La idea es que puedan seguir el proyecto paso a paso, ejecutar el código, interpretar resultados y luego pensar cómo adaptar una actividad similar para sus estudiantes.

Objetivos del proyecto

Al finalizar este módulo podrás:

  1. Explicar qué es un dataset de imágenes.

  2. Cargar el dataset abierto CIFAR-10.

  3. Visualizar imágenes y sus etiquetas.

  4. Preparar imágenes para un modelo de Machine Learning.

  5. Entrenar un modelo básico de clasificación de imágenes.

  6. Evaluar el modelo usando accuracy y matriz de confusión.

  7. Reflexionar sobre los límites de los modelos de visión computacional.

  8. Diseñar una idea de actividad educativa usando imágenes.

¿Qué es CIFAR-10?

CIFAR-10 es un dataset abierto compuesto por imágenes pequeñas de 10 categorías diferentes.

Las categorías son:

  1. airplane

  2. automobile

  3. bird

  4. cat

  5. deer

  6. dog

  7. frog

  8. horse

  9. ship

  10. truck

Cada imagen tiene tamaño 32 × 32 píxeles y está en color.

Esto significa que cada imagen es pequeña, pero contiene suficiente información para que un modelo intente reconocer patrones visuales.

Nota importante para docentes

Este proyecto usa imágenes reales, pero el modelo que construiremos será intencionalmente sencillo.

No esperamos obtener un accuracy perfecto.
La meta principal es entender el flujo completo:

  1. Cargar imágenes.

  2. Ver ejemplos.

  3. Preparar datos.

  4. Entrenar un modelo.

  5. Evaluar predicciones.

  6. Reflexionar sobre los errores.

En Machine Learning, los errores también enseñan.

Parte 1: Importar librerías

Usaremos:

  • numpy para manejar arreglos numéricos.

  • matplotlib para visualizar imágenes.

  • tensorflow.keras para cargar CIFAR-10 y construir un modelo sencillo.

  • sklearn para evaluar el modelo.

Ejecuta la siguiente celda.

import numpy as np
import matplotlib.pyplot as plt

from tensorflow.keras.datasets import cifar10
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Flatten
from tensorflow.keras.utils import to_categorical

from sklearn.metrics import accuracy_score, ConfusionMatrixDisplay, classification_report

print("Librerías importadas correctamente.")
---------------------------------------------------------------------------
ModuleNotFoundError                       Traceback (most recent call last)
Cell In[1], line 4
      1 import numpy as np
      2 import matplotlib.pyplot as plt
      3 
----> 4 from tensorflow.keras.datasets import cifar10
      5 from tensorflow.keras.models import Sequential
      6 from tensorflow.keras.layers import Dense, Flatten
      7 from tensorflow.keras.utils import to_categorical

ModuleNotFoundError: No module named 'tensorflow'

Parte 2: Cargar el dataset CIFAR-10

El dataset viene disponible directamente desde tensorflow.keras.datasets.

La primera vez que ejecutes esta celda, el computador descargará los datos desde internet.

(X_train, y_train), (X_test, y_test) = cifar10.load_data()

print("Forma de X_train:", X_train.shape)
print("Forma de y_train:", y_train.shape)
print("Forma de X_test:", X_test.shape)
print("Forma de y_test:", y_test.shape)

Interpretación de las dimensiones

Cuando veas:

X_train.shape

probablemente obtendrás algo parecido a:

(50000, 32, 32, 3)

Esto significa:

  • 50000: número de imágenes para entrenamiento.

  • 32: alto de cada imagen.

  • 32: ancho de cada imagen.

  • 3: canales de color: rojo, verde y azul.

Cada imagen es una matriz de números.

Parte 3: Nombres de las clases

Las etiquetas originales son números del 0 al 9.
Vamos a crear una lista para traducir esos números a nombres.

class_names = [
    "airplane",
    "automobile",
    "bird",
    "cat",
    "deer",
    "dog",
    "frog",
    "horse",
    "ship",
    "truck"
]

print(class_names)

Parte 4: Visualizar imágenes

Antes de entrenar un modelo, debemos mirar los datos.

Ejecuta la siguiente celda para ver algunas imágenes del dataset.

plt.figure(figsize=(10, 6))

for i in range(12):
    plt.subplot(3, 4, i + 1)
    plt.imshow(X_train[i])
    label = int(y_train[i][0])
    plt.title(class_names[label])
    plt.axis("off")

plt.tight_layout()
plt.show()

Preguntas de observación

  1. ¿Las imágenes se ven claras o pequeñas?

  2. ¿Hay clases que parecen fáciles de reconocer?

  3. ¿Hay clases que podrían confundirse?

  4. ¿Qué hace fácil o difícil clasificar una imagen?

Parte 5: Usar una muestra pequeña para el taller

CIFAR-10 tiene muchas imágenes.
Para que el notebook corra más rápido durante el taller, usaremos una muestra reducida.

Esto permite que los docentes vean todo el proceso sin esperar demasiado tiempo.

# Usaremos una muestra pequeña para entrenar más rápido
num_train = 8000
num_test = 2000

X_train_small = X_train[:num_train]
y_train_small = y_train[:num_train]

X_test_small = X_test[:num_test]
y_test_small = y_test[:num_test]

print("Entrenamiento reducido:", X_train_small.shape)
print("Prueba reducida:", X_test_small.shape)

Nota pedagógica

En proyectos reales, usar más datos suele ayudar al modelo.

Pero para enseñar el proceso por primera vez, es válido usar una muestra pequeña para que el entrenamiento sea más rápido.

Parte 6: Preparar las imágenes

Los valores de los píxeles van de 0 a 255.

Para ayudar al modelo, convertimos esos valores a un rango entre 0 y 1.

Esto se llama normalización.

X_train_norm = X_train_small / 255.0
X_test_norm = X_test_small / 255.0

print("Valor mínimo:", X_train_norm.min())
print("Valor máximo:", X_train_norm.max())

¿Por qué normalizamos?

Una imagen se guarda como números.

  • 0 representa ausencia de color.

  • 255 representa intensidad máxima.

Al dividir entre 255, todos los valores quedan entre 0 y 1.
Esto ayuda a que el modelo aprenda de forma más estable.

Parte 7: Preparar las etiquetas

Las etiquetas están como números:

  • 0 = airplane

  • 1 = automobile

  • 2 = bird

  • etc.

Para entrenar este modelo, convertiremos las etiquetas a formato categórico usando to_categorical.

y_train_cat = to_categorical(y_train_small, num_classes=10)
y_test_cat = to_categorical(y_test_small, num_classes=10)

print("Etiqueta original:", y_train_small[0])
print("Etiqueta categórica:", y_train_cat[0])

Parte 8: Crear un modelo sencillo

Vamos a construir un modelo básico.

Este modelo tendrá:

  1. Flatten: convierte la imagen de 32 × 32 × 3 en una lista de números.

  2. Dense: capa que aprende patrones.

  3. Dense(10, activation="softmax"): capa final con 10 salidas, una por cada clase.

Este no es el modelo más avanzado para imágenes, pero es excelente para aprender el proceso.

model = Sequential([
    Flatten(input_shape=(32, 32, 3)),
    Dense(128, activation="relu"),
    Dense(64, activation="relu"),
    Dense(10, activation="softmax")
])

model.summary()

Preguntas para discutir

  1. ¿Por qué la última capa tiene 10 neuronas?

  2. ¿Qué representa cada salida del modelo?

  3. ¿Por qué este modelo puede tener dificultades con imágenes?

Parte 9: Compilar el modelo

Antes de entrenar, debemos decirle al modelo:

  • qué función de pérdida usará,

  • qué optimizador usará,

  • qué métrica queremos observar.

Para este proyecto usaremos accuracy.

model.compile(
    optimizer="adam",
    loss="categorical_crossentropy",
    metrics=["accuracy"]
)

print("Modelo compilado correctamente.")

Parte 10: Entrenar el modelo

Ahora entrenamos el modelo.

Usaremos pocas épocas para que el entrenamiento sea rápido.

Si tienes más tiempo o una computadora más potente, puedes aumentar epochs.

history = model.fit(
    X_train_norm,
    y_train_cat,
    epochs=8,
    batch_size=64,
    validation_split=0.2,
    verbose=1
)

Parte 11: Visualizar el aprendizaje

Vamos a graficar cómo cambió el accuracy durante el entrenamiento.

plt.figure(figsize=(8, 5))
plt.plot(history.history["accuracy"], label="Entrenamiento")
plt.plot(history.history["val_accuracy"], label="Validación")
plt.xlabel("Época")
plt.ylabel("Accuracy")
plt.title("Accuracy durante el entrenamiento")
plt.legend()
plt.show()

Preguntas de análisis

  1. ¿El accuracy de entrenamiento sube?

  2. ¿El accuracy de validación sube igual?

  3. ¿Qué podría significar si entrenamiento sube mucho pero validación no?

  4. ¿El modelo está aprendiendo bien o solo memorizando?

Parte 12: Evaluar el modelo con datos de prueba

Ahora evaluamos el modelo con imágenes que no usó para entrenar.

test_loss, test_accuracy = model.evaluate(
    X_test_norm,
    y_test_cat,
    verbose=0
)

print(f"Accuracy en datos de prueba: {test_accuracy:.2f}")

Interpretación

Si el accuracy no es muy alto, no significa que el proyecto falló.

Este modelo es sencillo y CIFAR-10 es un dataset más difícil que Iris.

La meta es entender cómo funciona el proceso y analizar los errores.

Parte 13: Hacer predicciones

El modelo devuelve probabilidades para cada clase.

Luego escogemos la clase con mayor probabilidad.

probabilidades = model.predict(X_test_norm)

y_pred = np.argmax(probabilidades, axis=1)
y_true = y_test_small.flatten()

print("Primeras 10 etiquetas reales:")
print(y_true[:10])

print("\nPrimeras 10 predicciones:")
print(y_pred[:10])

Parte 14: Comparar imágenes reales y predicciones

Vamos a visualizar algunas imágenes junto con la etiqueta real y la predicción del modelo.

plt.figure(figsize=(12, 8))

for i in range(16):
    plt.subplot(4, 4, i + 1)
    plt.imshow(X_test_small[i])
    real = class_names[y_true[i]]
    pred = class_names[y_pred[i]]
    plt.title(f"Real: {real}\nPred: {pred}")
    plt.axis("off")

plt.tight_layout()
plt.show()

Preguntas para discutir

  1. ¿Cuáles predicciones fueron correctas?

  2. ¿Cuáles fueron incorrectas?

  3. ¿Hay errores que tú también podrías cometer mirando la imagen?

  4. ¿Qué clases parece confundir el modelo?

Parte 15: Matriz de confusión

La matriz de confusión nos permite ver qué clases se confunden con otras.

ConfusionMatrixDisplay.from_predictions(
    y_true,
    y_pred,
    display_labels=class_names,
    xticks_rotation=45
)

plt.title("Matriz de confusión - CIFAR-10")
plt.show()
print(classification_report(
    y_true,
    y_pred,
    target_names=class_names
))

Preguntas de interpretación

  1. ¿Qué clase reconoce mejor el modelo?

  2. ¿Qué clase reconoce peor?

  3. ¿Confunde gatos con perros?

  4. ¿Confunde camiones con automóviles?

  5. ¿Qué nos dice esto sobre la dificultad de clasificar imágenes?

Parte 16: Probar con una imagen específica

Puedes cambiar el valor de indice para ver otra imagen del conjunto de prueba.

indice = 25

plt.imshow(X_test_small[indice])
plt.axis("off")
plt.show()

real = class_names[y_true[indice]]
pred = class_names[y_pred[indice]]

print("Etiqueta real:", real)
print("Predicción del modelo:", pred)

pd.DataFrame(
    probabilidades[indice].reshape(1, -1),
    columns=class_names
)

Actividad

Cambia el índice y busca:

  1. Una imagen que el modelo clasifique correctamente.

  2. Una imagen que el modelo clasifique incorrectamente.

  3. Una imagen donde el modelo no parezca muy seguro.

  4. Una imagen donde tú tampoco estés seguro de la clase.

Luego discute:

  • ¿Qué aprendemos de los errores?

  • ¿Por qué una imagen pequeña puede ser difícil de clasificar?

Parte 17: Reto guiado 1

Aumentar las épocas

Cambia el número de épocas de entrenamiento.

Por ejemplo:

epochs=12

o

epochs=15

Luego responde:

  1. ¿Subió el accuracy de entrenamiento?

  2. ¿Subió el accuracy de validación?

  3. ¿Subió el accuracy de prueba?

  4. ¿Crees que entrenar más siempre mejora el modelo?

Parte 18: Reto guiado 2

Cambiar el tamaño de la muestra

Puedes modificar:

num_train = 8000
num_test = 2000

Prueba con más datos si tu computadora lo permite.

Preguntas:

  1. ¿El entrenamiento tarda más?

  2. ¿Mejora el accuracy?

  3. ¿Por qué más datos pueden ayudar?

Parte 19: Reto guiado 3

Reflexionar sobre un modelo más avanzado

Para imágenes, normalmente se usan modelos llamados redes neuronales convolucionales o CNNs.

Este notebook usa un modelo sencillo para que el proceso sea fácil de entender.

Pregunta para discusión:

¿Por qué una imagen podría requerir un modelo especial que tome en cuenta patrones espaciales como bordes, formas y texturas?

Parte 20: Reflexión ética y educativa

Los modelos de visión computacional pueden ser útiles, pero también tienen límites.

Preguntas para discutir:

  1. ¿Qué pasaría si un modelo clasifica mal una imagen?

  2. ¿En qué contextos un error sería poco grave?

  3. ¿En qué contextos un error sería muy grave?

  4. ¿Qué diferencias hay entre clasificar flores, objetos o personas?

  5. ¿Por qué debemos tener cuidado al usar IA con imágenes de estudiantes?

Parte 21: Diseña tu propia actividad con imágenes

Ahora piensa en tu clase.

Diseña una actividad sencilla donde tus estudiantes puedan usar imágenes para clasificar objetos o fenómenos.

Plantilla

Materia:
Escribe aquí tu materia.

Grado:
Escribe aquí el nivel.

Pregunta de clasificación:
Ejemplo: ¿Podemos clasificar tipos de nubes usando imágenes?

Categorías:
Lista las clases posibles.

Fuente de imágenes:
Describe de dónde saldrían las imágenes.

Reglas éticas:
Explica cómo protegerías la privacidad y el uso responsable de imágenes.

Producto final:
Describe qué entregarían los estudiantes.

Reflexión:
¿Qué aprenderían sobre IA, datos y errores?

Ideas de proyectos escolares con imágenes

MateriaProyecto posible
BiologíaClasificar hojas, flores o insectos
Ciencias ambientalesClasificar tipos de nubes o paisajes
FísicaClasificar tipos de movimiento a partir de secuencias de imágenes
QuímicaClasificar materiales por apariencia
TecnologíaClasificar objetos reciclables
ArteClasificar estilos visuales o patrones
Educación agrícolaClasificar estados de crecimiento de plantas

Cierre del módulo

En este proyecto aprendimos que:

  • CIFAR-10 es un dataset abierto de imágenes.

  • Las imágenes también son datos numéricos.

  • Un modelo puede aprender patrones visuales.

  • Los modelos sencillos no siempre obtienen resultados perfectos.

  • La matriz de confusión ayuda a entender errores.

  • En educación, los errores del modelo pueden convertirse en oportunidades de discusión.

Idea final

Machine Learning no es magia.
Es un proceso de aprendizaje basado en datos.

Cuando trabajamos con imágenes, el modelo intenta aprender patrones visuales, pero necesita buenos datos, buen diseño y evaluación crítica.