Publicado

- 6 min tiempo de lectura

Entrenamiento en redes neuronales (cómo aprende una red neuronal)

Entrenamiento en redes neuronales (cómo aprende una red neuronal)

¿Sabes qué pasa realmente dentro de una red neuronal cuando “aprende”? Hoy te lo explico con ejemplos reales, un notebook práctico, y la teoría matemática que hace que la magia ocurra.

Vamos a entrenar una red neuronal sencilla para clasificar correos de clientes en quejas, preguntas u otros. Pero no es solo código: quiero que entiendas el proceso de aprendizaje paso a paso, incluyendo cómo funciona el descenso de gradiente y la retropropagación.


1. ¿Qué es una red neuronal y cómo aprende?

Piensa en una red neuronal artificial como un conjunto de neuronas simuladas que toman decisiones en cadena. Cada neurona recibe información, la procesa y pasa el resultado a las siguientes.

¿Cómo aprende?
Ajustando los pesos de cada conexión entre neuronas para que las decisiones sean mejores cada vez. Este ajuste se basa en medir el error (qué tan lejos estamos del resultado correcto) y corregirlo poco a poco. Ahí es donde entra el descenso de gradiente y la retropropagación.


2. El proceso de aprendizaje: teoría y práctica

Te lo explico como si fuera un entrenamiento en tu empresa:

Piensa en un empleado nuevo al que das tareas. Si se equivoca, le das feedback para que mejore. Cada vez que hace algo bien o mal, aprende y ajusta su forma de trabajar.
En IA, las redes neuronales hacen lo mismo. Solo que el “feedback” es una operación matemática llamada retropropagación, y los “ajustes” se hacen con el descenso de gradiente.


3. Las fórmulas detrás del aprendizaje

3.1. Forward Pass: el recorrido hacia la predicción

Cada neurona hace dos cosas:

  1. Calcula una combinación lineal de las entradas:
  • : pesos
  • : entrada
  • : sesgo (bias)
  1. Aplica una función de activación para decidir si pasa la información:

Donde puede ser, por ejemplo, una función ReLU:


3.2. Función de pérdida (Loss Function): medir el error

El modelo hace una predicción. ¿Cómo sabemos si es buena?
Usamos la función de pérdida. Para clasificación multiclase usamos entropía cruzada:

  • : valor real (0 o 1 según la clase correcta)
  • : probabilidad que predijo el modelo para la clase
  • : número de clases (en nuestro caso, 3)

3.3. Retropropagación (Backpropagation): el feedback

El error calculado vuelve hacia atrás por la red para ajustar los pesos.

La derivada de la pérdida respecto a cada peso nos dice en qué dirección moverlo:


3.4. Descenso de gradiente (Gradient Descent): actualizar los pesos

Una vez sabemos cómo mover los pesos, los ajustamos poco a poco:

  • : tasa de aprendizaje (learning rate)
  • : gradiente (pendiente del error respecto al peso)

Imagínate bajar una montaña buscando el punto más bajo. El gradiente te dice hacia dónde bajar, y es el tamaño del paso que das.


4. El notebook paso a paso (código + teoría)

Ahora que sabes qué pasa por dentro, veamos cómo lo implementamos en Python. Para eso hemos hecho un notebook interactivo:

👉 Abrir el notebook en Colab aquí

📌 Paso 1: Preparar el entorno

Instalamos las librerías que usaremos:

!pip install tensorflow nltk scikit-learn pandas matplotlib seaborn

📌 Paso 2: Dataset de correos

Creamos un dataset simple con ejemplos de quejas, preguntas y otros correos.

data = {
    "texto": [
        "No estoy satisfecho con el servicio, me cobraron de más.",
        "¿Cuánto cuesta el envío a Madrid?",
        "Gracias por la atención, todo estuvo excelente.",
        # ...
    ],
    "categoria": ["queja", "pregunta", "otro", ...]
}

df = pd.DataFrame(data)

Estos datos serán nuestro “conjunto de entrenamiento”. Es como el curso que damos a un nuevo empleado.


📌 Paso 3: Limpiar y preparar los datos

Primero limpiamos el texto:

nltk.download('stopwords')
from nltk.corpus import stopwords

stop_words = set(stopwords.words("spanish"))

def limpiar_texto(texto):
    texto = texto.lower()
    texto = re.sub(r'[^\w\s]', '', texto)
    texto = " ".join([word for word in texto.split() if word not in stop_words])
    return texto

df["texto_limpio"] = df["texto"].apply(limpiar_texto)

Luego tokenizamos y vectorizamos:

tokenizer = Tokenizer(num_words=1000, oov_token="<OOV>")
tokenizer.fit_on_texts(df["texto_limpio"])
sequences = tokenizer.texts_to_sequences(df["texto_limpio"])
padded = pad_sequences(sequences, padding="post")

Y codificamos las etiquetas:

categorias = {"queja": 0, "pregunta": 1, "otro": 2}
df["categoria_num"] = df["categoria"].map(categorias)

📌 Paso 4: Dividir en entrenamiento y prueba

Esto es clave para evitar que el modelo memorice en vez de aprender (overfitting).

X_train, X_test, y_train, y_test = train_test_split(padded, df["categoria_num"], test_size=0.2, random_state=42)

📌 Paso 5: La red neuronal (Forward Pass)

Nuestra red neuronal aprende a través de capas:

modelo = tf.keras.Sequential([
    tf.keras.layers.Embedding(1000, 16, input_length=padded.shape[1]),  # capa de embeddings
    tf.keras.layers.GlobalAveragePooling1D(),  # reduce la dimensionalidad
    tf.keras.layers.Dense(16, activation="relu"),  # capa oculta
    tf.keras.layers.Dense(3, activation="softmax")  # salida con probabilidades
])

Función de pérdida:

Compilamos:

modelo.compile(loss="sparse_categorical_crossentropy", optimizer="adam", metrics=["accuracy"])

📌 Paso 6: Entrenamiento (Backward Pass y descenso de gradiente)

historial = modelo.fit(X_train, y_train, epochs=30, validation_data=(X_test, y_test), verbose=2)

Aquí ocurre el ciclo:

  1. Predice → calcula el error con entropía cruzada
  2. Aplica retropropagación:
  1. Ajusta los pesos con descenso de gradiente:

📌 Paso 7: Evaluación del modelo

Comprobamos si la red aprendió:

y_pred = np.argmax(modelo.predict(X_test), axis=1)

from sklearn.metrics import classification_report
print(classification_report(y_test, y_pred, labels=[0,1,2], target_names=categorias.keys()))

Y visualizamos la matriz de confusión:

sns.heatmap(confusion_matrix(y_test, y_pred), annot=True, cmap="Blues", xticklabels=categorias.keys(), yticklabels=categorias.keys())

📌 Paso 8: Prueba en un caso real

def predecir_correo(texto):
    texto = limpiar_texto(texto)
    secuencia = tokenizer.texts_to_sequences([texto])
    secuencia_padded = pad_sequences(secuencia, maxlen=padded.shape[1])
    prediccion = modelo.predict(secuencia_padded)
    return list(categorias.keys())[np.argmax(prediccion)]

correo_nuevo = "Me llegó un producto dañado, ¿qué hago?"
print(predecir_correo(correo_nuevo))

📌 Paso 9: Visualizamos cómo aprendió

plt.plot(historial.history["accuracy"], label="Precisión en entrenamiento")
plt.plot(historial.history["val_accuracy"], label="Precisión en validación")
plt.xlabel("Épocas")
plt.ylabel("Precisión")
plt.legend()
plt.show()

plt.plot(historial.history["loss"], label="Pérdida en entrenamiento")
plt.plot(historial.history["val_loss"], label="Pérdida en validación")
plt.xlabel("Épocas")
plt.ylabel("Pérdida")
plt.legend()
plt.show()

Resultado final

Hemos visto cómo se entrena una red neuronal, tanto en la teoría matemática como en la práctica de negocio.

Hemos utilizado aprendizaje supervisado
✅ Entrenamiento con ejemplos
✅ Uso de retropropagación y descenso de gradiente
✅ Predicciones y mejoras con el tiempo


¿Quieres probarlo en tu empresa?

Te puedo ayudar a implementar un modelo como este adaptado a tus propios datos.
👉 Échale un vistazo a mi web: www.vialabsdigital.com o responde a esta newsletter.


Raúl Jáuregui
Consultor en IA & Machine Learning
Mindful ML

Artículos relacionados

Cómo la lógica difusa puede mejorar tus decisiones de negocio en tiempos de IA

Cómo la lógica difusa puede mejorar tus decisiones de negocio en tiempos de IA

Cómo piensa una neurona artificial? (Y por qué esto importa para tu empresa)

Cómo piensa una neurona artificial? (Y por qué esto importa para tu empresa)

Análisis de Sentimiento con BERT: Codificadores de Lenguaje

Análisis de Sentimiento con BERT: Codificadores de Lenguaje

Ver 10 artículos más